0
votes

I have a line chart (or, more properly a connected scatterplot) where I plot pies/donuts around the points. So, there is a data set that specifies the date and mood for plotting the points along with two other parameters, pos and neg, providing the values to go into the pie chart. The overall data that describes the points is called plotPoints.

That all works great, but what I still would like to do is to set the radius of the pie to be a function of the sum of pos + neg.

When I plot out the points, I can access all of the data with a function(d). In each pie, however, function(d) returns the data about the slices, one at a time. d contains the data for the current slice, not the overall data. For each pie, the first time arc is called it has the frequency for the first pie slice and the second time it is called it has the frequency for the second pie slice.

How do I refer to the current plotPoints properties when drawing the arc so that I can change the radius of the pie/donut to represent the sum of plotPoints[i].pos + plotPoints[i].neg?

The relevant code looks like this:

  var arc = d3.svg.arc()
    .outerRadius(radius - 10)
    .innerRadius(8);

  var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d; });


  var p = moodChart.selectAll(".pieContainer")
    .data(plotPoints).enter()
    .append("g")
    .attr("class","pieContainer")
    .attr("transform", function(d,i) {return "translate(" + (x(d.date)) + "," + (y(d.mood)) + ")"});
    p.append("title")
        .text(function(d) { return shortDateFormat(d.date) +", " + d.mood.toFixed(2) });


 var g = p.selectAll(".arc")
  .data(function (d) {return pie([d.neg, d.pos])})
.enter().append("g")
  .attr("class", "arc");




  g.append("path")
    .attr("d", arc)
    .style("fill", function(d,i) { return i==0 ? "brown" : "green"; });
1

1 Answers

0
votes

It's tough to answer this authoritatively without a bit more code/data to look at but in this situation I usually stash the needed variables in my data-bindings so they are available later:

var g = p.selectAll(".arc")
  .data(function (d) {
    var total = d.neg + d.pos,
      pie_data = pie([d.neg, d.pos]),
      point_arc = d3.svg.arc()
        .outerRadius((total * radius) - 10) //<-- set radius based on total
        .innerRadius((total * radius) - 8);

    pie_data.forEach(function(d1){
      d1.data.arc = point_arc; //<-- stash the arc for this point in our data bindings
    });

    return pie_data;
  });
  .enter().append("g")
  .attr("class", "arc");

  g.append("path")
    .attr("d", function(d){
      return d.data.arc
    })
    .style("fill", function(d,i) { return i==0 ? "brown" : "green"; });