D3.js:访问.attrTween()中元素的先前数据

时间:2015-11-10 01:51:40

标签: d3.js svg

有没有办法在attrTween补间函数中访问元素的先前数据?

我想使用先前的startAngle / endAngle值更新我的圆环图的弧线,但似乎访问这些角度的唯一方法是在应用新数据集之前缓存它们。我知道补间函数中有第3个参数是属性的当前值,但在我的例子中,它是SVG路径的d属性的原始字符串值,类似于M53.86870,HURR-DURR...。我想使用由pie布局计算的角度,而不是处理原始字符串。

JSFiddle

2 个答案:

答案 0 :(得分:0)

如果您已经编写了大量代码并且不想重写您的饼图逻辑,那么您可以执行以下操作。它涉及捕捉。此解决方案引入了一个data方法的包装器,每次使用新数据集调用data时,该方法都会在元素上存储绑定元素的先前值。它没有经过测试,因此如果必须,请自行承担风险。

var origData = d3.selection.prototype.data;

d3.selection.prototype.data = function() {
    this.each(function(){
        this.__pdata__ = this.__data__;
    });
    return origData.apply(this, arguments);
};

d3.selectAll('div')
    .data([0,1,2,3])
    .each(function(d){
        console.log(this.__pdata__, d);
    });

d3.selectAll('div')
        .data([0,1,2,3].reverse())
        .each(function(d){
            console.log(this.__pdata__, d);
        });

答案 1 :(得分:0)

我认为值得一提的是d3.local。该解决方案本质上与您自己的解决方案相同,但是数据存储在DOM节点上(例如@sergeyz解决方案),并且prev_data成为访问该数据的引用。

// prev_data provides a getter and setter
var prev_data = d3.local();
function update(data) {
  var $paths = g.selectAll('path');
  // Before we update the data, update the prev_data
  $paths.each(function(d) { prev_data.set(this, d) });
  var join = $paths.data(data);
  join.transition().attrTween('d', function (d) {
    // We can now get the individual datum for this node
    var p = prev_data.get(this, d);
    ...
  }
}

JSFiddle

@sergeyz解决方案很简洁,但猴子补丁D3并深入其内部(__data__)可能并不是每个人都喜欢的。另外,prev_data可用于许多组件。