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

Javascript 设置从最后一个已知点到新添加点(d3)的路径(线)的动画,javascript,graphics,svg,d3.js,plot,Javascript,Graphics,Svg,D3.js,Plot,我仍在学习编程,目前正在试用d3库 到目前为止,我对结果很满意 Q:如果您查看了链接(或此问题下的部分代码),您应该尝试绘制一个点。这仅在x轴刻度上可行。你会看到它的动画,但这并不完全是我想要的。我只想让它为新添加的线条设置动画。我已签出.enter()和.append(),但出现了错误。我可能做错了什么 function lines(x, y) { this.x = x; this.y = y+h; } var lineArray = [{x: 0, y: h}, {x: 1, y:

我仍在学习编程,目前正在试用d3库

到目前为止,我对结果很满意

Q:如果您查看了链接(或此问题下的部分代码),您应该尝试绘制一个点。这仅在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位置之后画一个圆圈,当你靠近一个圆圈时,在刻度上移动会有多困难

Q3:如果我们解决了我的第一个问题,那么当我们解决第2个问题时,让线条自动动画/更新是否容易


提前感谢。

我已经更新了您的JSFIDLE,以包含您要求的要点

关于问题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();
}

对于Q1-你的小提琴似乎不适合我。你如何绘制点?@Larskothoff你只能绘制灰线。谢谢你的检查。哇!了不起的人!我会继续重读你的代码,直到我得到它100%。我感谢你的帮助。我希望我能给你更多的分数。你也对我之前的问题发表了评论。从你的个人资料中我得知你是d3大师。。。再次感谢,不客气。请注意,您也可以使用以前的方法(破解路径的dasharray)制作动画,但这需要一些心理训练,D3方法肯定是使用插值器,就像我所做的那样。当然,您可以为两个坐标创建一个自定义插值器,而不是两个单独的插值器,从而使其更美观:)