从最后一个位置到新位置用动画制作多行 [英] Make multiple line with animation from the last position to the new positions

查看:50
本文介绍了从最后一个位置到新位置用动画制作多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我真正的问题中,我正在使用一个Web服务,该服务返回一个在x和y中具有点的数组.这就是我可以接收的数组的结构.

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 dataSet=[
    [
      { "voltaje":  10, "corriente": Math.random() * 130 + 10},
      { "voltaje":  40, "corriente": Math.random() * 130 + 10},
      { "voltaje": 70, "corriente": Math.random() * 130 + 10}
    ],
     [
      { "voltaje": 100, "corriente": Math.random() * 130 + 10},
      { "voltaje":  130, "corriente": Math.random() * 130 + 10},
      { "voltaje":  160, "corriente": Math.random() * 130 + 10},
      { "voltaje":  190, "corriente": Math.random() * 130 + 10}
    ]
  ];

我目前有这段代码适用于这样的结构:

I currently have this code that works for a structure like this:

var dataset=  [{
  x: d * 30 + 10,
  y: Math.random() * 130 + 10
},
{
  x: d * 30 + 10,
  y: Math.random() * 130 + 10
}
]

,在这段代码中,我得到了想要的东西.有些线条是用动画绘制的.并进行模拟,就像Web服务返回一些点一样,然后添加这些新点,并且该线的动画从最后一个点继续到新点.

and in this code I get what I want. some lines are painted with an animation. and it is simulated as if the web service returns some points, then these new points are added and the animation of the line continues from the last point to the new point.

我想分别获取每个数组的点和动画,例如:

I want to have the points and the animation of each array separately, for example:

我想使我的新结构适应此代码,并使其分成多行,但我却没有能力.我该怎么办?

I would like to adapt my new structure to this code and make it separated to multiple lines, but I have not been able to. How can I do it?

http://jsfiddle.net/3ok8uuj3/

  var svg = d3.select('svg');

  var backLayer = svg.append("g");
  var frontLayer = svg.append("g");

  var dataSet = d3.range(10).map(function(d) {
    return {
      x: d * 30 + 10,
      y: Math.random() * 130 + 10
    }
  });

  var lineGenerator = d3.svg.line()
    .x(function(d) {
      return d.x
    })
    .y(function(d) {
      return d.y
    })
    .interpolate("monotone")

  function displayLine(data) {
    var line = backLayer.selectAll(null)
      .data(data)
      .enter()
      .append("path")
      .attr({
        d: lineGenerator(data),
        fill: 'none',
        stroke: "red",
        "stroke-width": "3px"
      });

    var totalLength = line.node().getTotalLength();

    line.attr("stroke-dasharray", totalLength + " " + totalLength)
      .attr("stroke-dashoffset", totalLength)
      .transition()
      .duration(2000)
      .ease("linear")
      .attr("stroke-dashoffset", 0);
  }

  displayLine(dataSet)

  setTimeout(function() {
   setInterval(function() {
   var newData = { x: (dataSet.length) * 30 + 10, y: Math.random() * 130 + 10 };
   displayLine([dataSet[dataSet.length - 1], newData]);
   dataSet.push(newData);
  }, 2000);
  }, 2000);

推荐答案

您正在寻找类似这样的东西吗?

Is it something like this that your are looking for?

有一个变量存储每个系列的最后一个数据点(如果存在),或者如果没有该系列的最后一个数据点,则在lastData数组中创建一个新条目),并从这些值开始新的路径.因此,即使您添加了一系列新数据,这也应自动创建新行.

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.

注意:由于不再维护v3,因此使用的是D3.v4(而不是您的示例中的D3.v3).

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<data.length) {
    let diffSize = data.length - lastData.length
    let firstPos = data.length - diffSize

    for (let i=firstPos; i<data.length; i++){
      lastData.push(data[i][0])
    }
  }

  //add a path for each series and animate it
  data.forEach((d, i) => {

    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;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="800" height="800"></svg>

这篇关于从最后一个位置到新位置用动画制作多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆