Getting transition values ​​in D3

I get positions every 100 ms and apply them to the DOM as follows:

const div = d3.select(container).selectAll('div').data(positions) div.enter() .append('div') div.transition() .duration(100) .style({ top: d => dy, left: d => dx, }) div.exit() .remove() 

Thus, the elements receive smooth animation for new positions of 100 ms, which are necessary to obtain the following positions. It works great.

But I have different elements in the DOM, which depend on the position of the first elements. They are displayed with the same position data, but in a different software module.

My problem is that this transition interpolates data not available to other modules. Elements of these other modules appear to provide "optically incorrect" visualizations, since they are based on raw data.

Example: a point moves to a square and the square is highlighted, but the position of the point is interpolated, and the position that the square uses to check whether it should be highlighted is not. Thus, the square is highlighted, even if the point is not inside it.

How do I get around this? Can I capture these interpolated values ​​somewhere?

+5
source share
2 answers

If I understand you correctly, you want to completely control the tween function:

  div .transition() .duration(1000) .tween("postion", function(d) { var div = d3.select(this), startTop = parseInt(div.style('top')), startLeft = parseInt(div.style('left')), yInterp = d3.interpolateRound(startTop, dy), xInterp = d3.interpolateRound(startLeft, dx); return function(t) { div.style("top", yInterp(t) + "px"); div.style("left", xInterp(t) + "px"); }; }); 

Work code:

 <!DOCTYPE html> <html> <head> <script data-require=" d3@3.5.3 " data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> </head> <body> <div id="parent"> <div style="width: 20px; top: 20px; left: 30px; height: 20px; background-color: steelblue; position: absolute"></div> <div style="width: 20px; top: 0px; left: 40px; height: 20px; background-color: orange; position: absolute"></div> </div> <script> var positions = [ {x: 50, y: 50}, {x: 100, y: 100} ]; var div = d3.select('#parent') .selectAll('div') .data(positions); div .transition() .duration(1000) .tween("postion", function(d) { var div = d3.select(this), startTop = parseInt(div.style('top')), startLeft = parseInt(div.style('left')), yInterp = d3.interpolateRound(startTop, dy), xInterp = d3.interpolateRound(startLeft, dx); return function(t) { div.style("top", yInterp(t) + "px"); div.style("left", xInterp(t) + "px"); }; }); </script> </body> </html> 
+2
source

The easiest way I can come up with is to use the attrTween, styleTween, or tween methods to navigate ( https://github.com/mbostock/d3/wiki/Transitions#attrTween ). They take a function that should return a function (interpolator). This interpolator will be called many times to complete the transition, so you can continue to call your callback (cb), which will notify other modules of the change.

 selection.styleTween('top', function(){ var interpol = d3.interpolate(0,10); //interpolate from 0 to 10 return function(t) { // this guy will be called many times to calc transition // t will be changing from 0 to 1 var val = interpol(t); cb(val); // <-- callback that will notify other modules about the change in value return val; // <-- you have to return val so d3 transitions element } }); 
+3
source

Source: https://habr.com/ru/post/1235563/


All Articles