Adding elements to a D3 circle pack nodes

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

I am trying to make a zoomable circle packing chart. I'd like each child circle to contain a smaller chart which would always have the same structure (i.e. 4 columns, only the heights of the bars would change).

I have tried adding a simple rect to my chart so far but the rects are not added in the circle and are statics:

JS:

  var margin = 20,       diameter = 400;    var color = d3.scale.linear()       .domain([-1, 5])       .range(["hsl(152,80%,80%)", "hsl(228,30%,40%)"])       .interpolate(d3.interpolateHcl);    var pack = d3.layout.pack()       .padding(2)       .size([diameter - margin, diameter - margin])       .value(function(d) { return d.size; })    var svg = d3.select(".container").append("svg")       .attr("width", diameter)       .attr("height", diameter)     .append("g")       .attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");    d3.json("flare.json", function(error, root) {     if (error) return console.error(error);      var focus = root,         nodes = pack.nodes(root),         view;      var circle = svg.selectAll("circle")         .data(nodes)       .enter().append("circle")         .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })         .style("fill", function(d) { return d.children ? color(d.depth) : null; })         .on("click", function(d) { if (focus !== d) zoom(d), d3.event.stopPropagation(); });      var text = svg.selectAll("text")         .data(nodes)       .enter().append("text")         .attr("class", "label")         .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })         .style("display", function(d) { return d.parent === root ? null : "none"; })         .text(function(d) { return d.name; });       // Adding Rect to each child circle     var bar = svg.selectAll(".bar")         .data(nodes)       .enter().append("rect")         .attr("class", "bar")         .style("fill", function(d) { return d.children ? color(d.depth) : null; })         .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })         .style("display", function(d) { return d.parent === root ? null : "none"; })         .attr("width", 20)         .attr("x", 100)         .attr("height", function(d) { return 40; });      var node = svg.selectAll("circle,text");      d3.select(".container")         .style("background", color(-1))         .on("click", function() { zoom(root); });      zoomTo([root.x, root.y, root.r * 2 + margin]);      function zoom(d) {       var focus0 = focus; focus = d;        var transition = d3.transition()           .duration(d3.event.altKey ? 7500 : 750)           .tween("zoom", function(d) {             var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);             return function(t) { zoomTo(i(t)); };           });        transition.selectAll("text")         .filter(function(d) { return d.parent === focus || this.style.display === "inline"; })           .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; })           .each("start", function(d) { if (d.parent === focus) this.style.display = "inline"; })           .each("end", function(d) { if (d.parent !== focus) this.style.display = "none"; });     }      function zoomTo(v) {       var k = diameter / v[2]; view = v;       node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });       circle.attr("r", function(d) { return d.r * k; });     }   });    d3.select(self.frameElement).style("height", diameter + "px"); 

I have also added a plunkr: http://plnkr.co/edit/CfJqUQMISDzed2F71JpT?p=preview

How can I add this rect inside the child circles only?

Many thanks

回答1:

Yes, zooming feature adds some difficulty.

Here is a little bit dirty example of how this can be achieved: plunkr

The key code is:

// Adding Rects to each child circle var bar1 = svg.selectAll(".bar1")     .data(nodes)   .enter().append("rect")     .attr("class", "bar1")     .style("fill", "red")     .style("display", function(d) { return (d.depth == 4) ? null : "none"; }); var bar2 = svg.selectAll(".bar2")     .data(nodes)   .enter().append("rect")     .attr("class", "bar2")     .style("fill", "green")     .style("display", function(d) { return (d.depth == 4) ? null : "none"; }); var bar3 = svg.selectAll(".bar3")     .data(nodes)   .enter().append("rect")     .attr("class", "bar3")     .style("fill", "blue")     .style("display", function(d) { return (d.depth == 4) ? null : "none"; }); 

and

var node = svg.selectAll("circle,text,rect"); 

and

  bar1.attr("y", function(d) { return -d.r/2 * k - d.r/4; })   bar1.attr("x", function(d) { return -d.r/20 * k; })   bar1.attr("width", function(d) { return d.r/10 * k -1; });   bar1.attr("height", function(d) { return d.r/2 * k; });   bar2.attr("y", function(d) { return -d.r/2 * k - d.r/4; })   bar2.attr("x", function(d) { return -d.r/20 * k + d.r/10 * k; })   bar2.attr("width", function(d) { return d.r/10 * k-1; });   bar2.attr("height", function(d) { return d.r/2 * k; });   bar3.attr("y", function(d) { return -d.r/2 * k - d.r/4; })   bar3.attr("x", function(d) { return -d.r/20 * k - d.r/10 * k; })   bar3.attr("width", function(d) { return d.r/10 * k-1; });   bar3.attr("height", function(d) { return d.r/2 * k; }); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!