Newbie here. I am building a D3 bar-chart, and was able to animate the bar height; however, I have a text field next to each bar that shows the values, I was unable to make the text count up as the bar height grows.
I am using the .text attribute with I think where the problem is:
g.selectAll(".myText")
.transition()
.text(function(d){return (d.m6+"%")}) //code for counting from previous d.m6 value?
.attr("transform", function(d) { ...code for moving text location...)
.duration(700)
.ease(d3.easeLinear);
Any help will be greatly appreciated
Transitioning plain text will just result in the end value being displayed on transition start (after any delay):
For each selected element, sets the text content to the specified target value when the transition starts. .... Text is not interpolated by default because it is usually undesirable. (docs).
Here's an example of this at work:
var svg = d3.select("body")
.append("svg");
var text = svg.append("text")
.attr("x", 50)
.attr("y", 50)
.text(1);
text.transition()
.text(1000)
.duration(1000)
.delay(1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
However, you can interpolate text, the most canonical method would be to use transition.tween() (documentation). Though you could use .attrTween or even d3-timer. There are also a few other options out there but they are less straight forward.
A tween takes two arguments. The first argument is the name of the property being modified. The second argument is a tween value which returns a function of the form:
return function(t) { interpolator(t); })
Where t is a number between 0 and 1 representing the progress of the transition (0 = start, 1 = end), and interpolator is some function for interpolating a transition value for any point in the transition. With d3 this might be a d3-interpolator.
var svg = d3.select("body")
.append("svg");
var text = svg.append("text")
.attr("x", 50)
.attr("y", 50)
.text(1);
text.transition()
.tween("text", function() {
var selection = d3.select(this); // selection of node being transitioned
var start = d3.select(this).text(); // start value prior to transition
var end = 1000; // specified end value
var interpolator = d3.interpolateNumber(start,end); // d3 interpolator
return function(t) { selection.text(Math.round(interpolator(t))); }; // return value
})
.duration(10000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
I've just used rounding to keep the number formatted, otherwise the decimal points get pretty obnoxious. You could always apply some actual formatting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With