简体   繁体   中英

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>

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.

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(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

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