简体   繁体   中英

Bubble tree in d3?

Is there an equivalent implementation of a Bubble Tree in D3? In the link I provided, the Bubble Tree was implemented in RaphaelJS and jQuery.

在此输入图像描述

The straight answer to your question is no.

Using the resources at https://github.com/okfn/bubbletree/tree/master/build , the information you already know, and the information provided on http://d3js.org/ and through D3's documentation on GitHub, you should be able to conjure up your own bubble tree for D3!

This is a piece of JavaScript I used a long time ago to visualize binary tree data:

var updateVisual;

updateVisual = function() {
    var drawTree, out;
    drawTree = function(out, node) {
        var col, gray, i, line, lineElt, lines, sub, _results, _results1;
        if (node.lines) {
            out.appendChild(document.createElement("div")).innerHTML = "<b>leaf</b>: " + node.lines.length + " lines, " + Math.round(node.height) + " px";
            lines = out.appendChild(document.createElement("div"));
            lines.style.lineHeight = "6px";
            lines.style.marginLeft = "10px";
            i = 0;
            _results = [];
            while (i < node.lines.length) {
                line = node.lines[i];
                lineElt = lines.appendChild(document.createElement("div"));
                lineElt.className = "lineblock";
                gray = Math.min(line.text.length * 3, 230);
                col = gray.toString(16);
                if (col.length === 1) col = "0" + col;
                lineElt.style.background = "#" + col + col + col;
                console.log(line.height, line);
                lineElt.style.width = Math.max(Math.round(line.height / 3), 1) + "px";
                _results.push(i++);
            }
            return _results;
        } else {
            out.appendChild(document.createElement("div")).innerHTML = "<b>node</b>: " + node.size + " lines, " + Math.round(node.height) + " px";
            sub = out.appendChild(document.createElement("div"));
            sub.style.paddingLeft = "20px";
            i = 0;
            _results1 = [];
            while (i < node.children.length) {
                drawTree(sub, node.children[i]);
                _results1.push(++i);
            }
            return _results1;
        }
    };
    out = document.getElementById("btree-view");
    out.innerHTML = "";
    return drawTree(out, editor.getDoc());
};

Just insert some circular elements and manipulate it a bit to style in a circular manor and you should have a good program set!

Here you go. I didn't add the text or decorations, but it's the meat and potatoes:

 function bubbleChart(config) { var aspectRatio = 1, margin = { top: 0, right: 0, bottom: 0, left: 0 }, radiusScale = d3.scale.sqrt(), scan = function(f, data, a) { a = a === undefined ? 0 : a; var results = [a]; data.forEach(function(d, i) { a = f(a, d); results.push(a); }); return results; }, colorScale = d3.scale.category20(), result = function(selection) { selection.each(function(data) { var outerWidth = $(this).width(), outerHeight = outerWidth / aspectRatio, width = outerWidth - margin.left - margin.right, height = outerHeight - margin.top - margin.bottom, smallestDimension = Math.min(width, height), sum = data[1].reduce(function(a, d) { return a + d[1]; }, 0), radiusFractions = data[1].map(function(d) { return Math.sqrt(d[1] / sum); }), radiusNormalSum = radiusFractions.reduce(function(a, d) { return a + d; }, 0), scanned = scan(function(a, d) { return a + d; }, radiusFractions.map(function(d) { return d / radiusNormalSum; }), 0); radiusScale.domain([0, sum]).range([0, smallestDimension / 6]); var svg = d3.select(this).selectAll('svg').data([data]), svgEnter = svg.enter().append('svg'); svg.attr('width', outerWidth).attr('height', outerHeight); var gEnter = svgEnter.append('g'), g = svg.select('g').attr('transform', 'translate(' + margin.left + ' ' + margin.top + ')'), circleRing = g.selectAll('circle.ring').data(data[1]), circleRingEnter = circleRing.enter().append('circle').attr('class', 'ring'); circleRing.attr('cx', function(d, i) { return smallestDimension / 3 * Math.cos(2 * Math.PI * (scanned[i] + scanned[i + 1]) / 2) + width / 2; }).attr('cy', function(d, i) { return smallestDimension / 3 * Math.sin(2 * Math.PI * (scanned[i] + scanned[i + 1]) / 2) + height / 2; }).attr('r', function(d) { return radiusScale(d[1]); }).style('fill', function(d) { return colorScale(d[0]); }); var circleMain = g.selectAll('circle#main').data([data[0]]), circleMainEnter = circleMain.enter().append('circle').attr('id', 'main'); circleMain.attr('cx', width / 2).attr('cy', height / 2).attr('r', radiusScale(sum)).style('fill', function(d) { return colorScale(d); }); }); }; result.aspectRatio = function(value) { if(value === undefined) return aspectRatio; aspectRatio = value; return result; }; result.margin = function(value) { if(value === undefined) return margin; margin = value; return result; }; return result; } var myBubbleChart = bubbleChart().margin({ top: 1, right: 1, bottom : 1, left: 1 }); var data = ['Random Names, Random Amounts', [['Immanuel', .4], ['Pascal', 42.9], ['Marisa', 3.3], ['Hadumod', 4.5], ['Folker', 3.2], ['Theo', 4.7], ['Barnabas', 1.0], ['Lysann', 11.1], ['Julia', .7], ['Burgis', 28.2]]]; d3.select('#here').datum(data).call(myBubbleChart); 
 <div class="container"> <div class="row"> <div class="col-xs-12"> <div id="here"></div> </div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 

You can use the pack layout , basically you can bind any data you want to the shapes in the graph and custom parameters for them to position well respect to each other. Another alternative would be the force layout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM