Animation is not working for multiline chart D3 v4
Animation is not working for multiline chart D3 v4
I have created a line chart. Now i am trying to add animations in it. Line chart is multi line chart. When i try to put animation in both lines , code is not working and when i comment animation code of second line , then it works for first line.
Animation in both lines together is not working.
Here is the link of codepen - link
In codepen link "code of second line(animation) is commented"
code:
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div id="lineChartGph" class="lineChartGph"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
initLineChart();
function initLineChart(){
// set the dimensions and margins of the graph
var margin = {top: 20, right: 40, bottom: 30, left: 50},
width = 450 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%Y");
var data =[{"date":"2014","Profit":"34.13","Sales":"24.12"},{"date":"2015","Profit":"63.98","Sales":"45.56"},{"date":"2016","Profit":"67.00","Sales":"54.00"},
{"date":"2017","Profit":"45.00","Sales":"22.17"},{"date":"2018","Profit":"18.32","Sales":"24.13"}];
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the 1st line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.Sales); })
.curve(d3.curveMonotoneX);
// define the 2nd line
var valueline2 = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.Profit); })
.curve(d3.curveMonotoneX);
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("#lineChartGph").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("viewBox", "0 0 " + (width + margin.left + margin.right) + " " + (height + margin.top + margin.bottom))
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.Sales = +d.Sales;
d.Profit = +d.Profit;
});
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function (t) { return i(t); };
}
function transition(path) {
path.transition()
.duration(2000)
.attrTween("stroke-dasharray", tweenDash);
}
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) {
return Math.max(d.Sales, d.Profit); })]);
// Add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "#00357F")
.style("fill", "none")
.style("stroke-width", "3px")
.attr("d", valueline);
svg.select("path")
.datum(data)
.attr("d", valueline)
.call(transition);
/* svg.select("path")
.datum(data)
.attr("d", valueline2)
.call(transition);*/
// Add the valueline2 path.
svg.append("path")
.data([data])
.attr("class", "line")
.style("stroke", "#006600")
.style("fill", "none")
.style("stroke-width", "3px")
.attr("d", valueline2);
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickFormat(d3.timeFormat("%Y")).ticks(d3.timeYear.every(1)));
// Add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.style("fill", "cornflowerblue")
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.Sales); });
// Add the scatterplot
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.style("fill", "darkseagreen")
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.Profit); });
}
</script>
</body>
</html>
@Gerardo Furtado . I posted wrong code by mistake and didnt notice . I will take care from next time :-) . I have edited the post now.
– Pinki Sharma
Jul 2 at 12:01
1 Answer
1
When you do...
svg.select("path")
...the svg
selection will select the first <path>
element it sees in the document. That's clearly not what you want.
svg
<path>
The easiest alternative is setting different IDs for those paths (IDs are unique, anyway...) and selecting by ID. However, the most idiomatic alternative is passing a selection to transition
:
transition
transition(d3.selectAll("path"))
Which can be refactored as follows:
function transition(selection) {
selection.each(function() {
d3.select(this).transition()
.duration(2000)
.attrTween("stroke-dasharray", tweenDash);
})
};
Here is the updated Codepen: https://codepen.io/anon/pen/ERrqmp?editors=0010
thanks for helping me out. I want this animation repeating say after 5 sec with same data set. Could you please help me here?
– Pinki Sharma
Jul 6 at 5:51
If you have a different issue, please post a new question.
– Gerardo Furtado
Jul 6 at 6:10
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
The code in your question is wrong, it's not the multiline chart in the Codepen. Please edit it accordingly.
– Gerardo Furtado
Jul 2 at 9:52