2012-11-13 8 views
14

Utilizzando la libreria grafica D3, io non riesco a fare percorsi di disegnare lentamente in modo che possano essere visti in crescita.Non può fare percorsi sorteggio cresce lentamente con D3

This site ha un esempio perfetto nella sezione "Grafico a linee (Srotolare)", ma non viene fornito alcun codice per quella sezione. Qualcuno potrebbe aiutarmi con le linee del codice D3 che potrebbero farlo accadere?

Quando provo ad aggiungere delay() o duration() come nel seguente frammento di codice, il tracciamento si disegna immediatamente e tutto il codice SVG dopo questo segmento non riesce a renderizzare.

var mpath = svg.append ('path'); 
     mpath.attr ('d', 'M35 48 L22 48 L22 35 L22 22 L35 22 L35 35 L48 35 L48 48') 
      .attr ('fill', 'none') 
      .attr ('stroke', 'blue') 
      .duration (1000); 
+2

codice per questo esempio : http://blog.visual.ly/wp-content/uploads/2012/06/transitions.html#13 ... non importa, quando l'eseguo attraverso http://jsbeautifier.org/ posso vedere che l'attuazione è un idiota – nrabinowitz

+0

Wow. Tre diverse soluzioni, ma puoi controllarne solo una. Grazie nrabinowitz, Duopixel e btel! – tgoneil

risposta

17

Credo che la "via D3" per fare questo è con una funzione di interpolazione personalizzata. Potete vedere un'applicazione che lavora qui: http://jsfiddle.net/nrabinowitz/XytnD/

Questo presuppone che si dispone di un generatore di chiamata line impostato con d3.svg.line per calcolare il percorso:

// add element and transition in 
var path = svg.append('path') 
    .attr('class', 'line') 
    .attr('d', line(data[0])) 
    .transition() 
    .duration(1000) 
    .attrTween('d', pathTween); 

function pathTween() { 
    var interpolate = d3.scale.quantile() 
      .domain([0,1]) 
      .range(d3.range(1, data.length + 1)); 
    return function(t) { 
     return line(data.slice(0, interpolate(t))); 
    }; 
}​ 

La funzione pathTween qui restituisce un interpolatore che prende una determinata fetta della linea, definita da quanto siamo lontani dalla transizione e aggiorna il percorso di conseguenza.

Vale la pena notare, tuttavia, che sospetto che otterresti prestazioni migliori e un'animazione più fluida prendendo la strada facile: inserisci un rettangolo bianco (se lo sfondo è semplice) o uno clipPath (se lo sfondo è complesso) oltre la linea e spostarlo verso destra per rivelare la linea sottostante.

+0

Questo sembra certamente il modo d3, ma se rallenti l'animazione i percorsi vengono aggiunti, non animati (almeno in Chrome). – Duopixel

+0

Grazie, lo apprezzo! – tgoneil

+3

Sì, animando un rettangolo per scoprire la linea sarà probabilmente meglio per le prestazioni. Semplici clip-strade si forniscono anche buone prestazioni nella maggior parte dei casi, non è chiaro se sarebbe meglio che modificando il percorso (provare e vedere, le implementazioni probabilmente differiscono un po 'su questo). –

1

Sulla base del post che si collega a, mi si avvicinò con il seguente esempio:

var i = 0, 
    svg = d3.select("#main"); 

String.prototype.repeat = function(times) { 
    return (new Array(times + 1)).join(this); 
} 

segments = [{x:35, y: 48}, {x: 22, y: 48}, {x: 22, y: 35}, {x: 34, y:35}, {x: 34, y:60}]; 
line = "M"+segments[0].x + " " + segments[0].y 

new_line = line + (" L" + segments[0].x + " " + segments[0].y).repeat(segments.length); 
var mpath = svg.append ('path').attr ('d',new_line) 
      .attr ('fill', 'none') 
      .attr ('stroke', 'blue') 

for (i=0; i<segments.length; i++) 
    { 
    new_segment = " " + "L"+segments[i].x + " " + segments[i].y 
    new_line = line + new_segment.repeat(segments.length-i) 
    mpath.transition().attr('d',new_line).duration(1000).delay(i*1000); 
    line = line + new_segment 

    } 

è un po 'brutto, ma funziona. Lo si può vedere sul jsFiddle

+0

Grazie, lo apprezzo! – tgoneil

46

un modello comune quando le linee che animano in SVG è la fissazione di un stroke-dasharray della lunghezza del percorso e quindi animate stroke-dashoffset:

var totalLength = path.node().getTotalLength(); 

path 
    .attr("stroke-dasharray", totalLength + " " + totalLength) 
    .attr("stroke-dashoffset", totalLength) 
    .transition() 
    .duration(2000) 
    .ease("linear") 
    .attr("stroke-dashoffset", 0); 

Potete vedere una demo qui: http://bl.ocks.org/4063326

+3

E 'possibile farlo con d3.svg.area?Fino ad ora non ho avuto successo – mike

+0

Consiglio: invece di 'path.node.getTotalLength()' dovresti avere 'path.attr ('stroke-dashoffset', function() {return this.getTotalLength();})' Altrimenti, se 'percorso' è selezionato su più punti di dati,' totalLength' sarà solo la lunghezza del primo 'percorso' che stai disegnando. Il 'percorso' successivo si animerà in modo molto strano. –

+2

+1 Mi piacerebbe vedere una versione per 'd3.svg.area'. – Baz

Problemi correlati