从最后一个已知点到新添加点(d3)的动画路径(线)

时间:2013-12-03 21:44:54

标签: javascript graphics svg d3.js plot

我还在学习编程,我正在尝试使用d3库。

到目前为止,我对结果非常满意。 fiddle

问:如果您查看链接(或此问题下的部分代码),您应该尝试绘制一个点。这仅适用于x轴刻度。你会看到它的动画,但它并不完全是我想要的。我只想让它为新添加的线设置动画。我已经检查了.enter()和.append()但我收到了错误。我可能做错了。

function lines(x, y) {
  this.x = x;
  this.y = y+h;
}

var lineArray = [{x: 0, y: h}, {x: 1, y: h}];
var lineArrayPrevious = lineArray[lineArray.length -1].x;
var d3line = d3.svg.line()
                  .x(function(d) { return d.x; })
                  .y(function(d) { return d.y; })
                  .interpolate("monotone");


var path = svg.append("path").attr("d", d3line(lineArray)).attr("class", "line");

canPlot = true;

function plot() {
 var m = d3.mouse(this);

 if (m[0]-20 > lineArray[lineArray.length - 1].x)  {
   var lineX = lineArray.push(new lines(m[0], m[1]));

   svg.selectAll("path")
      .data(lineArray)
      .attr("d", d3line(lineArray));

   var point = svg.append("circle")
                  .attr("cx", function(d, i) { return m[0]; })
                  .attr("cy", function(d, i) { return m[1]+h; })
                  .attr("r", 0).transition().delay(150).attr("r", 6);


   var totalLength = path.node().getTotalLength();
   console.log();
   path.attr("stroke-dasharray", totalLength + " " + totalLength)
       .attr("stroke-dashoffset", totalLength)
       .transition().duration(700).ease("linear").attr("stroke-dashoffset", 0).delay(200);

   canPlot = true;
 } else { console.log("error"); canPlot = false; }
}

请原谅我的错误代码,我正在学习并最终将其清理干净。

Q2:制作一个跟随鼠标y位置的圆圈,并且当你靠近一个圆圈时移动时,有多难?

问题3:如果我们解决了第一个问题,那么当我们回答问题2时,是否可以轻松地让线条动画/更新?

提前致谢。

1 个答案:

答案 0 :(得分:1)

我已更新您的jsfiddle here以包含您要求的积分。

关于问题1,我改变了绘制线的方式,使其可以在转换中从前一个插值到当前点。相关的代码是这样的。

svg.select("path.line")
      .attr("d", d3line(lineArray))
      .transition().duration(700)
      .attrTween('d', pathTween)
      .each("end", function() {
           var lineX = lineArray.push(new lines(m[0], m[1]));
      });

   var last = lineArray[lineArray.length-1];

   function pathTween() {
        var xi = d3.interpolate(last.x, m[0]),
            yi = d3.interpolate(last.y, m[1] + h);
        return function(t) {
            return d3line(lineArray.concat([{x: xi(t), y: yi(t)}]));
        };
   }

请注意,转换完成后,新数据点才会添加到点数组中。

关于你的第二个问题,通过将处理程序附加到所有刻度标记并在鼠标悬停上添加标记来处理:

d3.selectAll(".xaxis > .tick").on("mouseenter", mousein)
 .on("mousemove", mousemove)
 .on("mouseleave", mouseout);

function mousein() {
  svg.append("circle").attr("class", "marker").attr("r", 3)
   .attr("pointer-events", "none");
}

function mousemove() {
  d3.select("circle.marker")
    .attr("transform", d3.select(this).attr("transform"))
    .attr("cy", d3.mouse(this)[1] + h);
}

function mouseout() {
  d3.select("circle.marker").remove();
}