Make multiple line with animation from the last position to the new positions

前端 未结 3 997
挽巷
挽巷 2021-01-29 06:58

In my real problem I\'m consuming a web service that returns an array with points in x and y. this is the structure of the array that I can receive.

  var dataSe         


        
3条回答
  •  北恋
    北恋 (楼主)
    2021-01-29 07:41

    Is it something like this that your are looking for?

    There is a variable that stores the last data points for each series (if it exists, or create a new entry in the lastData array if there is no last data point for this series) and starts the new paths from these values. So even if you add new series of data, this should take care of creating a new line automatically.

    Note: this uses D3.v4 (and not D3.v3 as in your example), since v3 is not maintained anymore.

    var svg = d3.select('svg');
    var backLayer = svg.append("g");
    
    //variable to store last data points the paths will have to start from
    let lastData = []
    
    //color scale
    const colorScale = d3.scaleOrdinal()
    	.domain([0, 1, 2])
      .range(["blue", "red", "green"])
    
    //line generator
    let lineGenerator = d3.line()
        .x(function(d) {
          return d.corriente
        })
        .y(function(d) {
          return d.voltaje
        })
        .curve(d3.curveBasis)
    
    
    
    function extractLastPoint(data){
      let lastDataPoint = []
      data.forEach(d => {
        lastDataPoint.push(d[d.length-1])
      })
      return lastDataPoint
    }
    
    
    function displayLine(data) {
    
      //adjust lastData array if discrepency of size
      if (lastData.length {
    
        d.unshift(lastData[i])
    
        let line = backLayer.append("path")
          .datum(d)
          .attr("d", p => lineGenerator(p))
          .attr("class", `line${i}`)
          .attr("fill", "none")
          .attr("stroke", colorScale(i))
          .attr("stroke-width", "3px") 
      
        let totalLength = line.node().getTotalLength();
      
        line
          .attr("stroke-dasharray", totalLength + " " + totalLength)
          .attr("stroke-dashoffset", totalLength)
          .transition()
          .duration(2000)
          .ease(d3.easeLinear)
          .attr("stroke-dashoffset", 0);
      })
    
      //save new last points of data to start next path from it
      lastData = extractLastPoint(data)
    }
    
    
    //initial line
    let dataSet=[
          [
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10}
          ],
           [
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10}
          ]
        ]
    
      displayLine(dataSet)
    
    //add new data every 3 sec
    d3.interval(function() {
      let dataSet=[
          [
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10}
          ],
           [
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10},
            { "voltaje":  Math.random() * 200 + 10, "corriente": Math.random() * 550 + 10}
          ]
        ]
    
      displayLine(dataSet)
    
    }, 3000)
    * {
      margin: 0;
      padding: 0;
      border: 0;
    }
    
    body {
      background: #ffd;
    }
    
    

提交回复
热议问题