Aaron Rank
Aaron Rank

Reputation: 111

d3js partition layout error in sunburst visualization

I'm following the example at http://bl.ocks.org/mbostock/4063423 to create a sunburst chart and am receiving Uncaught TypeError: Cannot read property 'length' of undefined error, but am not sure why. Here is an image of what I am logging right before the error:

log

index.html: 49 is return d.children? d.children : d.entries ? d.entries() : d.text? null : d.value.length ? d.value : d.value.entries(); within my partition variable. I realize there is no value key the object, but I am not sure why there isn't or how to fix this so any help would be greatly appreciated! Please see below for the entire code and the link to the data on google sheets.

https://docs.google.com/spreadsheets/d/1d0T0nFJoLcTYtsuEux5yPqNKWUmS9P1PAyh119RVjsQ/edit#gid=638421312

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

var hiearchicalDataScale = d3.scale.linear().range([0,1135840])

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()
    .sort(null)
    .size([2 * Math.PI, radius * radius])
    .value(function(d) { return 1; })
    .children(function(d) {
      console.log(d)
      return d.children? d.children : d.entries ? d.entries() : d.text? null : d.value.length ? d.value : d.value.entries();
    });

var arc = d3.svg.arc()
    .startAngle(function(d) { return d.x; })
    .endAngle(function(d) { return d.x + d.dx; })
    .innerRadius(function(d) { return Math.sqrt(d.y); })
    .outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });

d3.tsv("data.tsv", function(error, root) {


  var data = root.filter(function(d) {
    if(d.OilCum.indexOf("/") === -1 && d.OilCum.indexOf("_") === -1) {
      d.OilCum = +d.OilCum
      return d
    }
  })
  .map(function(d) {
    return { Reservoir: d.Reservoir, OilCum: d.OilCum, Field: d.Field }
  })


  var hiearchicalData = d3.nest()
    .key(function(d) {return d.Reservoir})
    .key(function(d) {return d.Field})
    .map(data, d3.map)

  hiearchicalDataScale.domain([
      d3.min(data, function(d) { return d.OilCum}),
      d3.max(data, function(d) { return d.OilCum})
    ])  

  var path = svg.datum(hiearchicalData).selectAll("path")
      .data(partition.nodes)
    .enter().append("path")
      .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
      .attr("d", arc)
      .style("stroke", "#fff")
      .style("fill", function(d) { 
        return color(d.children ? d.key : d.text);
      })
      .style("fill-rule", "evenodd")
      .each(stash);

  d3.selectAll("input").on("change", function change() {
    var value = this.value === "count"
        ? function() { return 1; }
        : function(d) { return d.OilCum; };

    path
        .data(partition.value(value).nodes)
      .transition()
        .duration(1500)
        .attrTween("d", arcTween);
  });
});

// Stash the old values for transition.
function stash(d) {
  d.x0 = d.x;
  d.dx0 = d.dx;
}

// Interpolate the arcs in data space.
function arcTween(a) {
  var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
  return function(t) {
    var b = i(t);
    a.x0 = b.x;
    a.dx0 = b.dx;
    return arc(b);
  };
}

Upvotes: 0

Views: 2599

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

The problem is here:

var partition = d3.layout.partition()
    .sort(null)
    .size([2 * Math.PI, radius * radius])
    .value(function(d) { return 1; })
    .children(function(d) {
      console.log(d)
      return d.children? d.children : d.entries ? d.entries() : d.text? null : d.value.length ? d.value : d.value.entries();
    });

Its breaking when you do

d.children? d.children : d.entries ? d.entries() : d.text? null : d.value.length ? d.value : d.value.entries();

Note here in d.value.length the d.value for some values it is undefined thus you get the error length of undefined.

I changed this line:

d.children? d.children : d.entries ? d.entries() : d.text? null : d.value ? d.value.entries() : null;

Here I am checking whether d.value is undefined if yes then d.value.entries() is returned else null gets returned.

Upvotes: 1

Related Questions