Place pie charts on nodes of force directed layout graph in D3

前端 未结 2 1856
余生分开走
余生分开走 2020-12-10 17:34

I would like to place pie charts on the node of a D3 force directed layout graph using D3.js. This is a common visualization in population genetics, see for example http://m

相关标签:
2条回答
  • 2020-12-10 18:03

    The problem appears to be the last statement in your force-on-tick callback:

    node.attr("x", function(d) { return d.x; })
        .attr("y", function(d) { return d.y; });
    

    SVG paths have no such x/y attributes. Try translating the path instead:

    node.attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
    
    0 讨论(0)
  • 2020-12-10 18:13

    The code as above wasn't working, the snippet below displays both pie charts, in the right location, with edges visible and with pie chart colors:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
    
        <style>
    
            .node {
                stroke: #fff;
                stroke-width: 1.5px;
            }
    
            .link {
                stroke: #808080;
                stroke-opacity: .6;
            }
    
        </style>
    </head>
    <body>
    
    <script type="text/javascript">
    
        graph = { "nodes":[
                        {"proportions": [{"group": 1, "value": 1},
                                         {"group": 2, "value": 2},
                                         {"group": 3, "value": 3}]},
                        {"proportions": [{"group": 1, "value": 2},
                                         {"group": 2, "value": 2},
                                         {"group": 3, "value": 2}]}],
                  "links":[{"source": 0, "target": 1, "length": 500, "width": 1}]
        }
    
        var width = 960,
        height = 500,
        radius = 25,
        color = d3.scale.category10();
    
        var pie = d3.layout.pie()
            .sort(null)
            .value(function(d) { return d.value; });
    
        var arc = d3.svg.arc()
            .outerRadius(radius)
            .innerRadius(0);
    
        var svg = d3.select("body").append("svg")
            .attr("width", width)
            .attr("height", height);
    
        var force = d3.layout.force()
            .charge(-120)
            .linkDistance(4 * radius)
            .size([width, height]);
    
        force.nodes(graph.nodes)
             .links(graph.links)
             .start();
    
        var link = svg.selectAll(".link")
            .data(graph.links)
            .enter().append("line")
            .attr("class", "link");
    
        var node = svg.selectAll(".node")
            .data(graph.nodes)
            .enter().append("g")
            .attr("class", "node");
    
        node.selectAll("path")
            .data(function(d, i) {return pie(d.proportions); })
            .enter()
            .append("svg:path")
            .attr("d", arc)
            .attr("fill", function(d, i) { return color(d.data.group); });;
    
        force.on("tick", function() {
            link.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });
    
            node.attr("x", function(d) { return d.x; })
                .attr("y", function(d) { return d.y; })
                .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"});
        });
    </script>
    </body>
    </html>
    
    0 讨论(0)
提交回复
热议问题