admin管理员组文章数量:1421031
For example I have a transition:
var sel = container.selectAll('div')
.transition()
.duration(1000)
.attr('transform', 'translate(100,500)');
At some moment I need to know where some of the elements lands to, e.g.
setTimeout(() => {
var value = d3.select('div#target')
.expectedAttr('transform');
assertEqual(value, 'translate(100,500)');
}, 500);
Is there built-in feature like this in D3? Otherwise I will have to write my own wrapper over d3.transition().attr()
method for storing values passed to it.
Edit
I've found out that D3 creates __transition__
field on elements, which seems to contain info regarding the transition, but I see no way to find a target attribute value there.
For example I have a transition:
var sel = container.selectAll('div')
.transition()
.duration(1000)
.attr('transform', 'translate(100,500)');
At some moment I need to know where some of the elements lands to, e.g.
setTimeout(() => {
var value = d3.select('div#target')
.expectedAttr('transform');
assertEqual(value, 'translate(100,500)');
}, 500);
Is there built-in feature like this in D3? Otherwise I will have to write my own wrapper over d3.transition().attr()
method for storing values passed to it.
Edit
I've found out that D3 creates __transition__
field on elements, which seems to contain info regarding the transition, but I see no way to find a target attribute value there.
- What do you mean by expected value: The value at that particular moment while the transition is still running or the target value it is transitioning to? – altocumulus Commented Aug 18, 2016 at 9:40
-
@altocumulus Right, I need to know the value of an attribute, that element will have when transition ends. Maybe it is stored in some field, like
__data__
field for data bindings. – Alexander Shutau Commented Aug 18, 2016 at 9:45
2 Answers
Reset to default 9At first I thought this would not be possible because the target value seemed to be inaccessibly hidden by a closure. With a little trick, though, this value can be retrieved.
You have to keep in mind that, when calling transition.attr()
, D3 will do the following:
For each selected element, creates an attribute tween for the attribute with the specified name to the specified target value.
This automatically created tween can be accessed by calling transition.attrTween(attrName)
.
When this tween gets called by D3 it will return an interpolator. This in turn has access to the target value which was closed over when creating the interpolator. When reading further down the docs the real trick bees obvious:
The returned interpolator is then invoked for each frame of the transition, in order, being passed the eased time t, typically in the range [0, 1].
Knowing that the final value for t – at the end of the transition – will be 1, you can call the previously obtained interpolator with this value which will yield the target value of the transition.
var targetValue = transition
.attrTween("x2") // Get the tween for the desired attribute
.call(line.node()) // Call the tween to get the interpolator
(1); // Call the interpolator with 1 to get the target value
The following example shows this by printing the target value for an already running transition.
var line = d3.select("line");
line
.transition()
.duration(2000)
.attr("x2", 100);
setTimeout(function() {
var transition = d3.active(line.node()) // Get the active transition on the line
var targetValue = transition
.attrTween("x2") // Get the tween for the desired attribute
.call(line.node()) // Call the tween to get the interpolator
(1); // Call the interpolator with 1 to get the target value
console.log(targetValue); // 100
}, 1000);
<script src="https://d3js/d3.v4.js"></script>
<svg><line x2="0" y2="100" stroke="black"></line></svg>
The same holds true for style transitions where you would use transition.styleTween()
to get the tween.
Ran into this problem today and found altocumulus' answer very helpful. However, I discovered that (at least for the current [email protected]
) if the current value is already at the target value, .call
ing the attrTween
will return null
instead of the interpolator.
My solution wound up looking something like this:
const attrTargetValue = (selection, attr) => {
const interpolator = selection
.attrTween(attr)
.call(selection.node());
return interpolator === null
? selection.selection().attr(attr)
: interpolator(1);
}
本文标签: javascriptGetting expected attribute value in D3 transitionStack Overflow
版权声明:本文标题:javascript - Getting expected attribute value in D3 transition - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745331836a2653851.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论