D3.js Sunburst Incorrect Arc Scales

704 views Asked by At

I have a Zoomable Sunburst diagram exhibiting strange problems with arc sizing.

http://colinwhite.net/Sunburst/

I would expect the size the arcs to be proportional to number of children (shown in the tool tip). Yet, I have parent arcs with few children, that are proportionally larger than their peers with far more children. Arc size is not reflective of number of children. I've tried various other d3.scales which haven't helped. What am I doing wrong?

My code is largely boiler plate from the D3 examples.

var width = 760, height = 700,
    radius = Math.min(width, height) / 2.25,
    color = d3.scale.category20c();

var x = d3.scale.linear().range([0, 2 * Math.PI]),
    y = d3.scale.sqrt().range([0, radius]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height * .52 + ")");

var partition = d3.layout.partition()
    .value(function(d) { return 1; });

var arc = d3.svg.arc()
    .startAngle(function(d) { return Math.max(0, Math.min( 2 * Math.PI, x(d.x))); })
    .endAngle(function(d) { return Math.max(0, Math.min( 2 * Math.PI, x(d.x + d.x))); })
    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });

var tooltip = d3.select("body")
    .append("div")
    .attr("class", "tooltip")
    .style("position", "absolute")
    .style("z-index", "10")
    .style("opacity", 0);

d3.json("data/getJson.php", function(error, data) {

var treeData = genJSON(data, ['Location', 'Provider', 'Diagnosis', 'Procedure']);

console.log(treeData);

var path = svg.selectAll("path")
    .data(partition.nodes(treeData))
    .enter().append("svg:path")
    .attr("d", arc)
    .style("fill-rule", "evenodd")
    .style("fill", function(d) { return color((d.children ? d : d.parent).name); }) 
    .on("click", click)

    .on("mouseover", function(d) {
          tooltip.html(function() {
              return (d.children ? d : d.parent).name + " (" + d.value + ")";
         });
          return tooltip.transition()
            .duration(50)
            .style("opacity", 0.9);
        })
        .on("mousemove", function(d) {
          return tooltip
            .style("top", (d3.event.pageY-10)+"px")
            .style("left", (d3.event.pageX+10)+"px");
        })
        .on("mouseout", function(){return tooltip.style("opacity", 0);});

  function click(d) {
    path.transition()
    .duration(750)
    .attrTween("d", arcTween(d));
  }

});

function arcTween(d) {
  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
      yd = d3.interpolate(y.domain(), [d.y, 1]),
      yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
  return function(d,i) {
    return i
        ? function(t) { return arc(d); }
        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
  };
}

The JSON is nested with this genJSON function -http://colinwhite.net/Sunburst/js/treeRemapper.js

Thanks for any help or advice.

1

There are 1 answers

0
Colin On BEST ANSWER

Changing the partition call, to include a .sort(null) like this -

var partition = d3.layout.partition()
    .sort(null) //<-- was missing this
    .value(function(d) { return 1; });

Seems to have resolved the strange arc scale problems.