2016-08-15 3 views
2

Ich versuche, eine weitere Zeile zum Liniendiagramm um http://bl.ocks.org/mbostock/1642874 hinzuzufügen.Mehrere Zeilenübergänge in d3.js

Der Code ist

var n = 40, 
    random = d3.randomNormal(0, .2), 
    data = d3.range(n).map(random); 

var svg = d3.select("svg"), 
    margin = {top: 20, right: 20, bottom: 20, left: 40}, 
    width = +svg.attr("width") - margin.left - margin.right, 
    height = +svg.attr("height") - margin.top - margin.bottom, 
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var x = d3.scaleLinear() 
    .domain([0, n - 1]) 
    .range([0, width]); 

var y = d3.scaleLinear() 
    .domain([-1, 1]) 
    .range([height, 0]); 

var line = d3.line() 
    .x(function(d, i) { return x(i); }) 
    .y(function(d, i) { return y(d); }); 

g.append("defs").append("clipPath") 
    .attr("id", "clip") 
    .append("rect") 
    .attr("width", width) 
    .attr("height", height); 

g.append("g") 
    .attr("class", "axis axis--x") 
    .attr("transform", "translate(0," + y(0) + ")") 
    .call(d3.axisBottom(x)); 

g.append("g") 
    .attr("class", "axis axis--y") 
    .call(d3.axisLeft(y)); 

g.append("g") 
    .attr("clip-path", "url(#clip)") 
    .append("path") 
    .datum(data) 
    .attr("class", "line") 
    .transition() 
    .duration(500) 
    .ease(d3.easeLinear) 
    .on("start", tick); 

function tick() { 

    // Push a new data point onto the back. 
    data.push(random()); 

    // Redraw the line. 
    d3.select(this) 
     .attr("d", line) 
     .attr("transform", null); 

    // Slide it to the left. 
    d3.active(this) 
     .attr("transform", "translate(" + x(-1) + ",0)") 
    .transition() 
     .on("start", tick); 

    // Pop the old data point off the front. 
    data.shift(); 

} 

Ich habe im Grunde nur versucht, einen anderen Datensatz mit data2 = d3.range(n).map(random); Erstellen und eine Linie für den neuen Datensatz hinzugefügt (mit gleichen Code wie im ursprünglichen Code, sondern verändert den Datensatz Variablenname)

Es fügt eine weitere Zeile mit anderen zufälligen Punkten hinzu, aber die Animation ist nicht mehr glatt.

Ich weiß nicht, was die Animation glatt macht.

ich das gleiche Problem mit dem ursprünglichen Code, wenn ich n - 1-n, das heißt

Ändern
var x = d3.scaleLinear() 
    .domain([0, n - 1]) 
    .range([0, width]); 

zu

var x = d3.scaleLinear() 
    .domain([0, n]) 
    .range([0, width]); 

ändern kann ich nicht sehen, warum dies die Glätte ändert.

Antwort

2

In the tutorial in Ihrem verknüpften Kern erwähnt, Mike Bostock erklärt, warum, dass die Domain sein sollte:

Wenn ein neuer Datenpunkt ankommt, wir die Linie sofort neu zu zeichnen und entfernen Sie die vorherige (falls vorhanden) zu transformieren. Der neue Datenpunkt ist somit zunächst unsichtbar am rechten Rand des Diagramms. Dann animieren wir den x-Offset des Pfadelements von 0 bis zu einem negativen Wert, wodurch er nach links verschoben wird.

Etwas unterhalb, fügt er hinzu:

Wenn Sie Spline-Interpolation für die Pfaddaten verwenden, dann beachten Sie, dass eine Steuerdatenpunkt Hinzufügen ändert die Tangenten des vorherigen Kontrollpunkt und damit die Form der zugehörigen Segmente. Um ein weiteres Wackeln zu vermeiden, wenn die Kontrollpunkte geändert werden, schränken Sie den sichtbaren Bereich (die X-Domäne) weiter ein, sodass der zusätzliche Kontrollpunkt ausgeblendet wird.

Und Sie werden feststellen, dass in the next gist, Mike Bostock schreibt:

Wenn ein auf einem Pfad Basis Interpolation Transformation übergeht, müssen Sie den Pfad durch zwei zusätzliche Kontrollpunkte Clip so dass die Änderung der Tangente ist nicht sichtbar, während der Pfad nach links gleitet.

Und dass die x-Skala wird wie folgt erstellt:

var x = d3.scaleLinear() 
    .domain([1, n - 2]) 
    .range([0, width]); 

Da nur die Domäne n-2 geht, dann sind die n-1 und n Punkte sind nicht sichtbar (aufgrund der clipPath).

+0

Ok danke. Weißt du, wie ich die zusätzliche Linie hinzufüge? – Jamgreen

+0

Könnten Sie bitte in einem Film zeigen, was Sie probiert haben? – Ashitaka

+0

Es funktioniert tatsächlich bei https: // jsfiddle.net/j6zj9wf7/aber es scheint dumm, nicht die gleiche Funktion 'tick' für beide Zeilen zu verwenden. Wie kann ich den Code sauber machen? – Jamgreen