在下面的最小示例中,SVG元素转换为不同的状态,然后恢复为原始状态。如何分解原始属性,以便不必重复? selection.each()
和transition.each()
给了我意想不到的令人困惑的结果。
var circle = d3.select('svg').append('circle')
.attr('cx', 50) // this part should be factored out
.attr('cy', 130)
.attr('r', 25)
.attr('fill', 'blue');
circle.transition().duration(1000).delay(500)
.attr('cx', 200)
.attr('cy', 50)
.attr('r', 50)
.attr('fill', 'red')
.transition().duration(1000).delay(500)
.attr('cx', 50) // repeated
.attr('cy', 130)
.attr('r', 25)
.attr('fill', 'blue');

<!DOCTYPE html>
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width='300' height='170'>
</svg>
&#13;
答案 0 :(得分:1)
一种解决方案可能是利用D3的data binding的力量。您可以定义包含两者的配置对象,稍后要还原的原始值以及元素应转换到的值。通过将此信息绑定到D3创建的DOM元素,您可以在以后的调用中访问它们。这些配置对象可能如下所示:
var circle = [{ // D3 binds data contained in arrays
orig: { // The original values
"cx": 50,
// ...
},
trans: { // The values to transition to
"cx": 200,
// ...
}
}];
投入d3-selection-multi模块,您可以直接使用上面定义的配置对象,方法是将它们交给selection.attrs()
方法:
函数的返回值必须是带有字符串值的对象,然后用于设置当前元素的属性。
// Array of configuration objects
var circle = [{
orig: {
"cx": 50,
"cy": 130,
"r": 25,
"fill": "red"
},
trans: {
"cx": 200,
"cy": 50,
"r": 50,
"fill": "blue"
}
}];
// Create new elements by binding data and using data joins
var circle = d3.select('svg').selectAll('circle')
.data(circle) // Bind configuration objects to elements
.enter().append('circle')
.attrs(function(d) { return d.orig; }); // Use the original values
circle.transition().duration(1000).delay(500)
.attrs(function(d) { return d.trans; }) // Transition to new values
.transition().duration(1000).delay(500)
.attrs(function(d) { return d.orig; }); // And transition back to original values
<!DOCTYPE html>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<svg width='300' height='170'>
</svg>
答案 1 :(得分:0)
我需要的是call()
而不是each()
。我知道这是可能的!
function revert(selection) {
selection
.attr('cx', 50)
.attr('cy', 130)
.attr('r', 25)
.attr('fill','blue');
}
var circle = d3.select('svg').append('circle')
.call(revert);
circle.transition().duration(1000).delay(500)
.attr('cx', 200)
.attr('cy', 50)
.attr('r', 50)
.attr('fill','red')
.transition().duration(1000).delay(500)
.call(revert);
<!DOCTYPE html>
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width='300' height='170'>
</svg>