在d3.js中从一个圆形到另一个圆形画一条线

6

我将解释我在实际项目中遇到的问题。我正在使用一个Web服务,它会返回n个点x、y。我正在使用settimeout来模拟Web服务。我想在这些坐标上放置一个圆,并为每个圆画一条连接它们的线,就像这样:

enter image description here

我想在圆圈之间添加一条线,并显示动画效果,类似于这样:

http://bl.ocks.org/duopixel/4063326

比如这个动画,但是要逐点进行

当我运行我的应用程序时,我希望该线条从初始圆圈到终点具有动画效果。如果我添加了一个新的圆圈,我希望创建一条线并对其进行动画处理以连接两个圆圈。我该怎么做呢?

http://jsfiddle.net/2rv0o8da/

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

  var dataSet = [10, 20, 30, 40];
  function display(data){
  var circle = svg.selectAll('circle')
      .data(data)
      .enter()
      .append('circle')
      .attr({
          r:function(d){ return d },
          cx:function(d, i){ return i * 100 + 50 },
          cy:50,
          fill: 'red'
      });
  } 
  display(dataSet);


  setTimeout(function(){
    display([5]);
  },2000)

你在这里有两个问题,我建议你只选择一个。另外,关于你的数据集:圆圈的y位置始终相同吗?因为数据集只是x位置值的数组。 - Gerardo Furtado
@GerardoFurtado 在我的实际问题中,如果我有2个x和y位置。对于这种情况,它们具有相同的“y”并不重要。问题是如何连接两个圆之间的线条并进行动画处理。 - yavg
好的,那么。我会回答它。 - Gerardo Furtado
谢谢,伙计!你明白我的意思吗?首先,我需要在所有圆圈中动画化线条,稍后使用settimeout模拟Web服务以添加具有相同动画的其他圆圈。 - yavg
那么,我就退出了。我本来想向您展示如何为线条添加动画效果,而不是如何添加更多的点。正如我所说,这是两个问题。在S.O.这里,我特别不喜欢回答一次性提出多个问题的问题。 - Gerardo Furtado
显示剩余2条评论
2个回答

6

如何连接圆点:

要创建连接您的圆圈的路径,您只需创建一个使用相同数据的线条生成器

例如,这将创建一个具有10个对象的数组,每个对象都具有xy位置:

var dataSet = d3.range(10).map(function(d) {
    return {x: someValue, y: someValue}
});

因此,由于我们使用这些属性来定位圆形,我们只需在线条生成器中使用相同的属性:
var lineGenerator = d3.svg.line()
    .x(function(d) {return d.x})
    .y(function(d) {return d.y})
    .interpolate("monotone")

然后,在您链接的 bl.ocks 中使用该函数:
var totalLength = path.node().getTotalLength();

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

这是演示文稿:

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.append("path")
    .datum(data)
    .attr({
      d: lineGenerator(data),
      fill: 'none',
      stroke: "red",
      "stroke-width": "3px",
      "shape-rendering": "geometricPrecision"
    });

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

setTimeout(function() {
  displayLine(dataSet)
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg></svg>


0

您的演示代码向我们展示了一种非常聪明的路径动画方式,我将提供使用attrTween的另一种不同解决方案:

var w = 500, h = 100;
var data = d3.range(100).map(function(d){
    return Math.random() * 5 + 5;
});
var x = d3.scale.linear().domain([0, 50]).range([0, 500]);
var y = d3.scale.linear().domain([0, 10]).range([0, 100]);
var line = d3.svg.line()
      .interpolate("cardinal")
      .x(function(d,i) {return x(i);})
      .y(function(d) {return y(d);})

var svg = d3.select("#container")
    .append("svg")
    .attr({ width: w, height: h })
    .style("border", "1px solid #ccc")
    .append("path")
    .datum(data)
    .attr({
        d: line(data.slice(0,1)),
        fill: "none",
        stroke: "#CB6154",
        "stroke-width": 2
    })
    .transition()
    .duration(2000)
    .attrTween("d", function(d){
        var f = d3.interpolate(0,50);
        return function(t){
            return line(d.slice(0, Math.ceil(f(t))));
        };
    })

这是jsfiddle的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接