2015-11-09 7 views
5

Ich erhalte alle 100ms Positionen und sie auf das DOM wie folgt aus:Erste Übergangswerte in D3

const div = d3.select(container).selectAll('div').data(positions) 

div.enter() 
    .append('div') 

div.transition() 
    .duration(100) 
    .style({ 
    top: d => d.y, 
    left: d => d.x, 
    }) 

div.exit() 
    .remove() 

So sind die Elemente erhalten eine glatte Animation an die neuen Positionen in den 100ms es das bekommen nimmt nächste Positionen. Das funktioniert gut.

Aber ich habe verschiedene Elemente im DOM, der auf der Position der ersten Elemente abhängen. Sie werden mit den gleichen Positionsdaten gerendert, jedoch in einem anderen Modul der Software.

Mein Problem ist, dass dieser Übergang Daten interpoliert, die nicht zu den anderen Modulen. Die Elemente dieser anderen Module scheinen "optisch falsche" Visualisierungen zu liefern, weil sie auf den Rohdaten basieren.

Beispiel: Ein Punkt bewegt sich in ein Quadrat und das Quadrat wird hervorgehoben, aber die Position des Punkts ist interpoliert und die Position, die das Quadrat verwendet, um zu prüfen, ob es hervorgehoben werden soll, ist es nicht. So wird das Quadrat hervorgehoben, auch wenn der Punkt nicht darin ist.

Wie kann ich das umgehen? Kann ich diese interpolierten Werte irgendwo finden?

Antwort

2

Wenn ich Sie richtig verstehen, wollen Sie die vollständige Kontrolle über die Tween-Funktion zu übernehmen:

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, d.y), 
     xInterp = d3.interpolateRound(startLeft, d.x); 
     return function(t) {    
     div.style("top", yInterp(t) + "px"); 
     div.style("left", xInterp(t) + "px"); 
     }; 
    }); 

Arbeitscode:

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]" 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, d.y), 
 
      xInterp = d3.interpolateRound(startLeft, d.x); 
 
      return function(t) {    
 
      div.style("top", yInterp(t) + "px"); 
 
      div.style("left", xInterp(t) + "px"); 
 
      }; 
 
     }); 
 
    </script> 
 
    </body> 
 

 
</html>

+0

Das Problem ist, ich interpoliere nicht von 0, sondern von der alten Position. Aber wenn ich versuche, das div in der Tween-Funktion zu wählen und seinen Top-Stil zu bekommen, bekomme ich nur "auto" und nicht die letzte Position: \ –

+1

@K .., ich bin mir nicht sicher, ob ich das verstehe Startpositionen in der Funktion. Siehe Aktualisierungen oben. – Mark

+0

In Ihrem Beispiel verwenden Sie 0, aber wenn ich dies tue, jedes Mal, wenn sich 'd.x' ändert, wird es von 0 nicht von seiner letzten Position interpoliert. –

3

Der einfachste Weg, an den ich denken kann, ist die Verwendung von attrTween, styleTween oder tween Methoden des Übergangs (https://github.com/mbostock/d3/wiki/Transitions#attrTween). Sie nehmen eine Funktion an, die eine Funktion (Interpolator) zurückgeben muss. Dieser Interpolator wird viele Male aufgerufen, um einen Übergang durchzuführen, so dass Sie weiterhin Ihren Callback (cb) aufrufen können, der andere Module über die Änderung informiert.

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 
    } 
}); 
+0

Gibt es keine Möglichkeit, den bereits laufenden Übergang ohne eigene zu implementieren? Es gibt einen, ich mag es, ich will nur seine Werte. –

+1

Ich habe deine Frage nicht bekommen. Bitte umformulieren. – sergeyz

+0

Ihr Beispiel mit dem 'styleTween' zwingt mich, meinen eigenen Übergang mit Hilfe von' d3.interpolate() 'zu implementieren. Ich habe nur auf eine Lösung gehofft, die den Übergang, den ich bereits im Beispiel beschrieben hatte, nutzen kann interpolierte Werte irgendwie :) –