Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

javascript - Getting expected attribute value in D3 transition

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

At 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 becomes 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.org/d3.v4.js"></script>

<svg><line x2="0" y2="100" stroke="black"></line></svg>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...