2016-03-30 6 views
1

Mit d3 versuche ich eine Animation zwischen zwei Zeilen zu erstellen, die eine unterschiedliche Anzahl von Datenpunkten haben.Übergang zwischen Pfaden mit unterschiedlicher Anzahl von Datenpunkten

Ich habe auf Mike Bostocks Beitrag verwiesen: https://bl.ocks.org/mbostock/3916621, der eine pathTween-Methode für zwei Pfade enthält, die im Format "M0 ..." beschrieben sind.

Die Daten, die ich zu zeichnen versuche, sind Rohdatenpunkte. Zum Beispiel:

var line = d3.svg.line().interpolate("monotone") 
    .x(function(d){ return d.x; }) 
    .y(function(d){ return d.y; }); 

low_res = [ 
    {x: 0  , y: 4 }, 
    {x: 5  , y: 14 }, 
    {x: 10 , y: 11 }, 
    {x: 85 , y: 14 }, 
    {x: 90 , y: 11 }, 
    {x: 95 , y: 7 }, 
    {x: 100 , y: 4 }, 
    ]; 
    var high_res = [[ 
    {x: 0  , y: 4 }, 
    {x: 1  , y: 12 }, 
    {x: 2  , y: 11 }, 
    {x: 3  , y: 11 }, 
    {x: 4  , y: 14 }, 
    {x: 5  , y: 14 }, 
    {x: 6  , y: 12 }, 
    {x: 7  , y: 4 }, 
    {x: 8  , y: 3 }, 
    {x: 9  , y: 1 }, 
    {x: 10 , y: 11 }, 
    {x: 11 , y: 11 }, 
    {x: 12 , y: 1 }, 
    {x: 13 , y: 13 }, 
    {x: 14 , y: 1 }, 
    {x: 15 , y: 5 }, 
    {x: 16 , y: 13 }, 
    {x: 17 , y: 10 }, 
    ]] 
    var lines = svg.selectAll(".line").data(high_res) 
      .enter() 
      .append("path") 
      .attr("class","line") 
      .attr("d", line) 
      .style("stroke", "blue"); 

Dies funktioniert für die Anzeige der loestes Grundstück finden. Mike Bostock des Beispiel lautet wie folgt:

var d0 = "M0,0c100,0 0,100 100,100c100,0 0,-100 100,-100", 
      d1 = "M0,0c100,0 0,100 100,100c100,0 0,-100 100,-100c100,0 0,100 100,100"; 
    svg.append("path") 
      .attr("transform", "translate(180,150)scale(2,2)") 
      .attr("d", d0) 
      .call(transition, d0, d1); 

    function transition(path, d0, d1) { 
     path.transition() 
       .duration(2000) 
       .attrTween("d", pathTween(d1, 4)) 
       .each("end", function() { d3.select(this).call(transition, d1, d0); }); 
    } 

    function pathTween(d1, precision) { 
     return function() { 
      var path0 = this, 
        path1 = path0.cloneNode(), 
        n0 = path0.getTotalLength(), 
        n1 = (path1.setAttribute("d", d1), path1).getTotalLength(); 

      // Uniform sampling of distance based on specified precision. 
      var distances = [0], i = 0, dt = precision/Math.max(n0, n1); 
      while ((i += dt) < 1) distances.push(i); 
      distances.push(1); 

      // Compute point-interpolators at each distance. 
      var points = distances.map(function(t) { 
       var p0 = path0.getPointAtLength(t * n0), 
         p1 = path1.getPointAtLength(t * n1); 
       return d3.interpolate([p0.x, p0.y], [p1.x, p1.y]); 
      }); 

      return function(t) { 
       return t < 1 ? "M" + points.map(function(p) { return p(t); }).join("L") : d1; 
      }; 
     }; 
    } 

ich, um herauszufinden, habe Schwierigkeiten, wie ein native Pfad-Objekt zu erstellen, wie d0, d1 im zweiten Beispiel aus meinem Satz von Rohdaten, die in den Übergang geführt werden können Funktion dh:

.call(transition, d0, d1); 

Vielen Dank im Voraus für einen Rat.

Antwort

1

Ihre Frage scheint zu einkochen:

Wie kann ich generieren einen Weg für meine Datenpunkte?

Dies ist tatsächlich, was die Linienfunktion tut. Es ist so einfach wie:

var low_res = [ 
 
    {x: 0 , y: 4 }, 
 
    {x: 5 , y: 14 }, 
 
    {x: 10 , y: 11 }, 
 
    {x: 85 , y: 14 }, 
 
    {x: 90 , y: 11 }, 
 
    {x: 95 , y: 7 }, 
 
    {x: 100 , y: 4 }, 
 
    ], 
 
    high_res = [ 
 
    {x: 0  , y: 4 }, 
 
    {x: 1  , y: 12 }, 
 
    {x: 2  , y: 11 }, 
 
    {x: 3  , y: 11 }, 
 
    {x: 4  , y: 14 }, 
 
    {x: 5  , y: 14 }, 
 
    {x: 6  , y: 12 }, 
 
    {x: 7  , y: 4 }, 
 
    {x: 8  , y: 3 }, 
 
    {x: 9  , y: 1 }, 
 
    {x: 10 , y: 11 }, 
 
    {x: 11 , y: 11 }, 
 
    {x: 12 , y: 1 }, 
 
    {x: 13 , y: 13 }, 
 
    {x: 14 , y: 1 }, 
 
    {x: 15 , y: 5 }, 
 
    {x: 16 , y: 13 }, 
 
    {x: 17 , y: 10 }, 
 
    ]; 
 
    
 
var line = d3.svg.line().interpolate("monotone") 
 
    .x(function(d){ return d.x; }) 
 
    .y(function(d){ return d.y; }); 
 
    
 
var d0 = line(low_res), 
 
    d1 = line(high_res); 
 
    
 
console.log(d0); 
 
console.log(d1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

Vielen Dank für diese :) – schuess

Verwandte Themen