D3.js does not update data

I am updating a D3 bar graph in combination with AngularJS. In this case, all data is initially visible, and updates filter out unwanted data. In the past, it worked without problems using this model:

data = [{ name: John Doe, splits: [{distance: 1, time: 1234},] },...] 

Now I'm trying to add another panel to each stack using this model:

 data = [{ name: John Doe time: 12345, splits: [{distance: 1, time: 1234},] },...] 

My problem is updating the data. My calculated values ​​are recalculated correctly, for example, the domain for scaling. The line for updating time still only recognizes data values ​​before updating (the code fragment is greatly truncated for brevity):

 // Set ranges of values in axes x.domain(data.map(function(d) { return d.name})); y.domain([ min , max]); // Y Axis is updated to the correct time range chart.append('g').attr('class', 'y axis').call(yAxis).selectAll('text').style('font-family','Open Sans').style('font-size', '.9rem'); // data join / Select Athlete var athlete = chart.selectAll(".athlete").data(data), athdata = athlete.enter(), console.log(data) // data is correct here // add container for each athlete athplace = athdata.append("g") .attr("class", "athlete") .attr("transform", function(d) { return "translate(" + x(d.name) + ",0)"; }) .text(function(d) { return d.name}), // ENTER time athplace.append('rect') .attr('class', "time") .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.time.time); }) .attr("height", 0).transition().duration(300) .attr("height", function(d) { return height-y(d.time); }); ... enter splits & labels // exit splits & athlete splitlabels.exit().transition().duration(300).attr('opacity', 0).remove(); splits.exit().transition().duration(300).attr('height', 0).attr('opacity', 0).remove(); athlete.exit().transition().duration(300).attr('width',0).attr('opacity', 0).remove(); console.log(athlete) // data is still correct // UPDATE time, this chain has the problem with data not being updated. "d" is equal to previous values athlete.selectAll('rect.time') .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.time.time); }) .attr("height", function(d) { return height-y(d.time); }); 

Due to these errors, the updated columns present incorrect data and create incorrect visualization. I watched / tested all this time, trying to isolate the problem to what I have now. Can someone more experienced with D3 give me some insight?

Note: for those who are interested, this is all in the Angular directive, where I $watch to change the data values, although I am 100% sure that this is not a problem.

Edit

Here is a JSFiddle that shows the same error as in my script. All code was extracted directly from a script demonstrating the problem. Updating the interval at the bottom imitates the replacement of data that usually occurs.

+6
source share
1 answer

I played a little with your example and made a few changes that may be useful.

First, I reinstalled your global var up the top inside your update function. By doing this, we are not a “double add” where the x and y axes stop. This would seem to draw our chart on top of our old chart.

However, having established this, I gave a new diagram, overlaid on top of our old one. To fix this, I call d3.selectAll("svg > *").remove(); inside update to remove all attached SVG elements and groupings, providing us with a “clean slate” to display our new diagram. This solves the overlap problem.

You mentioned that this is shortened for brevity, so I hope this example can help with your actual application


Updated script

+2
source

Source: https://habr.com/ru/post/980016/


All Articles