Reputation: 141
I have created a simple bar chart in D3.js where there are two bars to start out with, and and you have the ability to add a new bar to the bar chart. The animation for the new bar is to slide in from the right, and then be placed at it's position. The sizes of the bars are also updated as to be normalized by the highest y value possible for the graph, which is updated when the new bar is added. This itself does not work, and only the two bars that are on the graph themselves slide correctly. Also, whenever the current bars on the graph are updated and shrink to be normalized to the new highest y value, there seems to be some 'leftover' of the animation, almost like a ghost of the bars in current spots before it is placed in its current position. I've attached an image for help in explaining. I've also been able to replicate it through a jsfiddle here jsFiddle. Here is also the code for the animation when a new bar is added:
$('button#add').on('click', function( e ) {
var datum = Math.round ( d3.max(data) + 200 );
data.push( datum );
xScale.domain( d3.range( data.length ) );
var yMax = d3.max( data );
yScale.domain( [ 0, yMax ] );
var bars = svg.selectAll('rect')
.data( data );
bars.enter()
.append( 'rect' )
.attr( 'x', function( d, i ) {
return width;
})
.attr( 'y', function( d, i ) {
return yScale( d );
})
.attr( 'width', xScale.bandwidth() )
.attr( 'height', function( d, i ) {
return height - yScale( d );
})
.attr( 'fill', function( d, i ) {
return colors[ i ];
});
bars.transition( )
.duration( 1500 )
.attr( 'x', function( d, i ) {
return xScale( i );
})
.attr( 'y' , function( d, i ) {
return yScale( d );
})
.attr( 'width', xScale.bandwidth() )
.attr( 'height', function( d, i ) {
return height - yScale( d );
})
.attr( 'fill', function( d, i ) {
return colors[ i ];
});
});
I'm hypothesizing that it is possibly caused by the animation, and if I may be doing something incorrectly there, but not sure how or why. Any help would be greatly appreciated.
Thanks!
Upvotes: 1
Views: 367
Reputation: 21578
For this to work you need to keep in mind, that as of D3 v4…
selection.append no longer merges entering nodes into the update selection; use selection.merge
This is the reason why the rect
s you append using the enter selection bars.enter()
will not get added to the update selection bars
. To make life easy you can call .merge()
to merge both selection into one:
var barsEnter = bars.enter() // Save the enter selection
.append( 'rect' )
// ...
bars.merge(barsEnter).transition( ) // Merge into update selection to act on all rects
.duration( 1500 )
Have a look at the updated JSFiddle for a working example.
Upvotes: 1