简体   繁体   中英

Update d3 data element after chart is drawn

I am working off of the d3 "Calendar View" example and would like to display 1 year at a time with some buttons to progress or regress the year being shown. In this example all of the data (years 1990-2010) arrive with the d3.csv call and is being rendered in a chart defined by...

var svg = d3.select("body")
  .selectAll("svg")
  .data(d3.range(1990, 2011))
  .enter().append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + ((width - cellSize * 53) / 2) + "," + (height - cellSize * 7 - 1) + ")");

I would like to be able to update the data attribute on the d3 class and update the chart via a clickable event.

For example maybe showing the year 2010 is default like this...

var svg = d3.select("body")
  .selectAll("svg")
  .data(d3.range(2010, 2011))
  .enter().append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + ((width - cellSize * 53) / 2) + "," + (height - cellSize * 7 - 1) + ")");

and i just want to modify the data element to d3.range(2009, 2010) on an event and redraw the chart.

I've tried removing and re-rendering the chart but haven't had success. There must be an easier way to do this.

In your code above you are only ever calling enter which is designed to add new elements to the DOM. There's a really good article from the author Mike Bostock called 3 Little Circles that explains how the enter/exit/update pattern works (note that it was for v3 though).

const join = d3
    .select("body")
    .selectAll("svg")
    .data(d3.range(2010, 2011), d => d);

First thing to note is that we've provided a key function to .data() . In this case the key is literally the value d which will return 2010 and 2011 for the two data points.

join.exit().remove();

Get rid of the old calendars!

join.enter()
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + ((width - cellSize * 53) / 2) + "," + (height - cellSize * 7 - 1) + ")")
    .merge(join)
    ... do more stuff

The next importing bit you're missing is to update the existing stuff. You do that by taking your enter selection and calling merge(join) . That gives you all the new and updated items so you can start changing attributes/styles or do further nested joins on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM