2013-07-24 16 views
5

Ecco il codice: http://jsfiddle.net/fJAwW/velocità Cambio della D3 percorso di animazione

Questo è ciò che mi interessa in:

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

ho la mia variabile di dati Linedata, che aggiungo al percorso con

.attr("d", line(lineData)) 

Per la sezione di transizione:

.transition() 
    .duration(2000) 

vorrei fare qualcosa di simile

.transition() 
    .duration(function(d) { 
     return d.x; 
    }) 

Dove d è uno dei miei punti di dati.

Ho problemi a capire le strutture dati e come interagiscono in d3.js, quindi qualsiasi aiuto sarebbe apprezzato.

+0

vuoi dire che si desidera l'animazione per muoversi più velocemente o più lentamente in punti diversi lungo la linea, ad esempio, a seconda che stia andando "in salita" o "in discesa"? – explunit

+0

Sì, fondamentalmente. Alla fine mi piacerebbe avere i miei dati come {x: 1, y: 2, velocità: 50}, ed essere in grado di controllare la transizione tra i punti con l'attributo di velocità. –

risposta

2

Una cosa interessante su d3 è che i dati non sono memorizzati nell'attributo d, è nell'attributo __data__. I percorsi sono speciali in quanto in realtà non è dove sono memorizzati i dati sul percorso. Sebbene sia possibile aggirarlo, raccomando vivamente di utilizzare il modello di dati standard d3, con .data(), .enter() e .append().

Perché in realtà non si immettono dati, __data__ è vuoto e, di conseguenza, d non è definito se si utilizza .duration(function(d) {}).

In generale, quando si passa una funzione del genere, la variabile stessa non ha importanza. La prima variabile viene sempre assegnata a __data__ per la selezione e la seconda è sempre l'indice.

Probabilmente il miglior esempio del modello di aggiornamento è this block di Mike Bostock. Ci sono anche alcune ottime informazioni nell'API se rimani bloccato, così come circa dieci miliardi di tutorial su come realizzare una trama a dispersione che tutti dicono della stessa cosa.

È possibile utilizzare .data() di mettere alcuni dati nel percorso, e poi accedervi con una funzione in .duration(), in questo modo:

path.data([{'duration':1000}]) 
    .transition() 
    .duration(function(d){return d.duration}) 
+0

Se sto leggendo correttamente, ciò che proponi gli consente di cambiare la velocità per percorso, ma sta cercando di cambiare la velocità tra i punti all'interno di un percorso. – explunit

+0

corretto! Una specie di. Il problema è che i dati inseriti in un percorso sono accessibili solo tramite 'path [0] [0] .pathSegList.getItem (i)', che ti darà un segmento di percorso specifico che è in qualche modo incomprensibile. Se vuoi accedere ai punti sul percorso, questi punti possono essere collocati in 'd', con' path.data ([lineData]) '(nota che, senza parentesi, solo il primo punto finirà nei dati). Questi punti potrebbero quindi essere usati per impostare una funzione di andamento personalizzata che varierebbe la velocità con il posto sul percorso usando una 'funzione (d) {}'. In questo modo, non è difficile codificare i nomi dei dati ovunque. – ckersch

4

credo che sarà necessario creare un insieme di transizioni incatenati per cambiare il valore stroke-dashoffset in ogni punto della linea. Come ha sottolineato @ckersch, il percorso è diverso dalla maggior parte delle cose in d3 perché i dati vengono compressi in una singola stringa di percorso anziché rappresentati come singoli valori.

È possibile concatenare la transizione iniziale dalla variabile path come si è fatto e quindi concatenare le ulteriori transizioni da quella precedente. Qualcosa di simile a questo:

// Add the path 
    var path = svg.append('path') 
    .attr({d: line(lineData), stroke: "steelblue", 'stroke-width': 2, fill: 'none'}); 

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

    // start with the line totally hidden 
    path.attr({'stroke-dasharray': totalLength + " " + totalLength, 'stroke-dashoffset': totalLength }); 

    // transition will be chained from either the original path or the last transition 
    var transitionFrom = path; 
    // start at 1 since no transition needed to first point 
    for (var i = 1; i < lineData.length; i++) { 
    transitionFrom = transitionFrom.transition() 
     .duration(lineData[i].speed) 
     .ease("linear") 
     .attr("stroke-dashoffset", lengthAt[i-1] || 0); 
    }; 

Da dove viene questo array lengthAt viene? Sì, questa è la parte brutta.Le mie abilità geometriche non sono abbastanza buone da sapere in modo approssimativo come approssimare quella per l'interpolazione 'cardinale' nella funzione del generatore di linee, ma in questo esempio ho violato un modo per farlo disegnando linee nascoste e rileggendole di svg:

http://bl.ocks.org/explunit/6082362

+0

Grazie per l'esempio. Hai mai capito se c'è un modo per ottenere sottosezioni del percorso invece di creare linee nascoste? – TheComeOnMan

Problemi correlati