如何将点添加到路径的末尾

时间:2017-09-24 14:00:42

标签: javascript d3.js

我正在添加圆圈,并且对于每个圆圈,我添加一条动画,从第一个圆圈到最后一个圆圈。

enter image description here

在我真正的问题中,我正在使用一个在x和y中返回几个点的Web服务。在settimeout的帮助下,我模拟了当我使用Web服务并返回点数时。我需要通过创建一个圆并使用从最后一个圆创建的线到新圆或新圆来创建一个新点或新点,而不必从头开始重复动画,只需设置动画线创建新圆圈的最后一个圆圈。我该怎么办?

enter image description here

http://jsfiddle.net/kvyr41Lw/

  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 displayCircles(data) {
    var circle = frontLayer.selectAll(null)
      .data(data)
      .enter()
      .append('circle')
      .attr({
        r: 6,
        cx: function(d) {
          return d.x
        },
        cy: function(d) {
          return d.y
        },
        fill: 'white',
        stroke: "black",
        "stroke-width": "3px"
      });
  };

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

  displayCircles(dataSet);
  displayLine(dataSet)

在这里,我需要模拟一段时间之后,网络服务返回了更多的点然后它们应该被添加,并且行已经创建了最后一个圆圈的动画,直到最后一个圆圈将被创建。

  setTimeout(function() {
   console.log("creating new points..")
  }, 5000)

1 个答案:

答案 0 :(得分:2)

调用displayCircles函数获取新数据并调用displayCircles函数 通过将新数据附加到dataSet数组的最后一个元素。

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

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 displayCircles(data) {
  var circle = frontLayer.selectAll(null)
    .data(data)
    .enter()
    .append('circle')
    .attr({
      r: 6,
      cx: function(d) {
        return d.x
      },
      cy: function(d) {
        return d.y
      },
      fill: 'white',
      stroke: "black",
      "stroke-width": "3px"
    });
};

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

displayCircles(dataSet);
displayLine(dataSet)

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

body {
  background: #ffd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.8/d3.min.js"></script>
<svg width="800" height="800"></svg>