Connor Atherton
Connor Atherton

Reputation: 161

How to update pie chart using d3.js

I have two different data sets and I am trying to create pie charts with the first set and then listen for an event and transition to the second set.

I can successfully create the pie charts from the first set of data using this code

var data = [[70, 30],[60, 40],[50, 50],[95, 5],[87, 13]];

progress.pie.vars.svg = d3.select( progress.pie.vars.pieEl ).selectAll("svg")
          .data(data)
          .enter()
          .append("svg")
            .attr("width", 150)
            .attr("height", 150)
          .each(function(d) { this.currentAngles = d; }); // store the initial angles;

progress.pie.vars.path = progress.pie.vars.svg.selectAll("path")
          .data(function(d, i){ return pie(d) })
          .enter().append("path")
            .attr("fill", function(d, i) { return color(i); })
            .attr("transform", "translate(" + 75 + ", " + 75 + ")")
            .attr("d", arc);

Note: I am using hardcoded data here, I can replicate using JSON but I wanted to simplify things just so I can get the transitions working.

This creates the svg's and renders them on the page but the problem occurs when I use the other data set and try to update the paths. Like this...

var data = [[60, 40], [10, 10, 10, 70], [30, 70], [25, 25, 25, 25], [30, 35, 35]];

progress.pie.vars.svg = progress.pie.vars.svg.selectAll("svg")
          .data(data);

progress.pie.vars.path = progress.pie.vars.path
          .data(function(d, i){ return pie(d) })
          .enter().append("path")
            .transition()
            .duration(5000);

I have researched the d3 general update pattern but I don't quite understand it yet.

If anyone has any suggestions how to solve my problem or improve my code then its much appreciated :)

Thanks

Upvotes: 0

Views: 5976

Answers (1)

Scott Cameron
Scott Cameron

Reputation: 5333

Since progress.pie.vars.svg contains the newly appended elements, you don't need to selectAll("svg"). That would be selecting for any svg elements under your svg elements. You should be able to just call data directly on the selection you have.

For the progress.pie.vars.path data bind, it looks like you're only handling the enter case for adding new paths (although you're not assigning a d path attribute as you did with the original pies). You'll want to add new arcs for new data and update the arcs for updated data. You can do this by keeping the update selection separate from the enter selection:

progress.pie.vars.path = progress.pie.vars.path
    .data(function(d, i){ return pie(d) });

progress.pie.vars.path.enter().append("path");

progress.pie.vars.path.attr("d", arc);

New nodes added to the enter selection are implicitly added to the update selection so that last line will be operating on both the new and existings. (Note this doesn't handle exit).

You should check out Mike Bostock's excellent tutorial Thinking With Joins.

Upvotes: 1

Related Questions