繁体   English   中英

D3 v4中的补间数字不再像v3那样有效了

[英]Tweening numbers in D3 v4 not working anymore like in v3

我试图找出为什么我的补间数字(向上或向下计数)D3版本4中的代码不再起作用。

这是我的代码:

var pieText = svg4.append("text")
    .attr("class", "pieLabel")
    .attr("x", 0)
    .attr("y", 0)
    .text(0)
    .attr("dy", "0.2em")
    .style("font-size", 19)
    .style("fill", "#46596b")
    .attr("text-anchor", "middle");

d3.selectAll(".pieLabel").transition()
  .delay(500)
  .duration(1000)
  .tween("text", function(d) {
    var i = d3.interpolate(this.textContent, d.value);
    return function(t) {
      this.textContent = form(i(t));
    };
  });

console.log告诉我插值工作正常。 那变了什么? 我该如何让它发挥作用?

谢谢你的帮助。

这里的问题就是this内部函数,因为它在V3的工作将不再在里面工作。

让我们来证明一下。 看看这里的控制台,使用D3 v3, this是DOM元素:

 d3.select("p").transition() .tween("foo", function(d) { var i = d3.interpolate(0, 1); return function(t) { console.log(this) }; }); 
 <script src="https://getfirebug.com/firebug-lite-debug.js"></script> <script src="https://d3js.org/d3.v3.min.js"></script> <p></p> 

现在是相同的片段,使用D3 v4 ...现在thiswindow对象:

 d3.select("p").transition() .tween("foo", function(d) { var i = d3.interpolate(0, 1); return function(t) { console.log(this) }; }); 
 <script src="https://getfirebug.com/firebug-lite-debug.js"></script> <script src="https://d3js.org/d3.v4.min.js"></script> <p></p> 

解决方案 :在外部函数中将this的引用保留为变量(传统上称为self ,但在此我将其命名为node ):

d3.selectAll(".pieLabel").transition()
    .delay(500)
    .duration(1000)
    .tween("text", function(d) {
        var node = this;
        //keep a reference to 'this'
        var i = d3.interpolate(node.textContent, d.value);
        return function(t) {
            node.textContent = form(i(t));
            //use that reference in the inner function
        };
    });

以下是仅包含此更改的代码:

 var widthpie = 250, heightpie = 300, radius = Math.min(widthpie, heightpie) / 2; var data = [{ antwort: "A", value: 0.5 }, { antwort: "B", value: 0.4 }]; var form = d3.format(",%"); var body4 = d3.select("#chart1"); var svg4 = body4.selectAll("svg.Pie") .data(data) .enter() .append("svg") .attr("width", widthpie) .attr("height", heightpie) .append("g") .attr("transform", "translate(" + widthpie / 2 + "," + heightpie / 2 + ")"); var pieText = svg4.append("text") .attr("class", "pieLabel") .attr("x", 0) .attr("y", 0) .text(0) .attr("dy", "0.2em") .style("font-size", 19) .style("fill", "#46596b") .attr("text-anchor", "middle"); d3.selectAll(".pieLabel").transition() .delay(500) .duration(1000) .tween("text", function(d) { var node = this; var i = d3.interpolate(node.textContent, d.value); return function(t) { node.textContent = form(i(t)); }; }); 
 <script src="https://d3js.org/d3.v4.min.js"></script> <div id="chart1"></div> 

PS:我在片段中使用Firebug,因为SO片段不能正确记录窗口对象。

问题是由更改日志中未记录的更改引起的。 D3 v3 调用传递给transition.tween()的回调返回的内部函数,在每个tick上传递当前节点作为this上下文:

tweens[--n].call(node, e);

但是,从v4开始, 调用内部函数时不再是这种情况:

tween[i].call(null, t);

null传递给该函数将替换为全局对象。 在这种情况下,你的函数中的this不再指向当前元素,正如v3那样。 Gerardo已经在他的回答中提出了补救措施,甚至在v4的文档中也提出了建议:

transition.tween("attr.fill", function() {
  var node = this, i = d3.interpolateRgb(node.getAttribute("fill"), "blue");
  return function(t) {
    node.setAttribute("fill", i(t));
  };
});

因此,你需要一个封闭的参考保持当前元素,因为它是为引用this所提供的回调transition.tween()

我复制这个代码我不知道在哪里,如果有人知道只是给予referance。 我使用它来添加转换到路径,我希望这给你一个想法

使用它来附加转换

.transition()
              .duration(2000)
              .attrTween("stroke-dasharray", tweenDash)

这个功能

function tweenDash() {
    return function(t) {
        var l = path.node().getTotalLength();
        interpolate = d3.interpolateString("0," + l, l + "," + l);

        //t is fraction of time 0-1 since transition began

        var p = path.node().getPointAtLength(t * l);

        return interpolate(t);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM