Setup Menus in Admin Panel

School.Dataninja.it

Visualizzazioni dati con d3js: gestire animazioni ed effetti speciali

Dai vita alle tue visualizzazioni!

Ti sei ormai cimentato con tutti i metodi fondamentali che d3js mette a disposizione, di fatto sei pronto per costruire una visualizzazione dati efficace. Si tratterebbe però di una visualizzazione sostanzialmente statica, in cui al massimo i cambiamenti nel tempo sono istantanei (con il metodo setInterval()) e con cui l’utente non ha alcun modo di interagire (né con il mouse, né con la tastiera, né con le dita).

Come hai visto nell’unità sul contenuto degli elementi della pagina, ma anche su quella dedicata alla creazione di nuovi elementi, l’aggiornamento del contenuto e degli attributi di un elemento è istantaneo, prende probabilmente pochi millesimi di secondo. Non c’è alcuna transizione tra lo stato iniziale e quello finale dell’elemento. Se per ciò che riguarda il contenuto è abbastanza scontato che sia così, per gli attributi numerici forse preferiresti un passaggio più morbido tra, per esempio, una dimensione del font e un’altra. In fondo tra un carattere 12 e un 32 ci sono molte dimensioni intermedie, che impostate una dopo l’altra, abbastanza rapidamente, ma non troppo, darebbero l’impressione di un’animazione del testo che si ingrandisce. Un po’ come i fotogrammi di un film…

Animazione per interpolazione

In un film però i fotogrammi sono prodotti esplicitamente (al limite uno a uno, come nelle produzioni in stop motion), mentre l’idea qui è simulare il passaggio da uno stato all’altro conoscendo solo lo stato iniziale e quello finale. Il calcolo degli stati intermedi si chiama interpolazione e  si basa su funzioni che indicano il percorso da compiere, dati gli stati estremi, e sono dette funzioni di easing. Ecco una meravigliosa guida interattiva, i cui esempi fanno uso di jQuery: easings.net/it. L’interpolazione più semplice è naturalmente quella lineare, ma ce ne sono tante altre, utili in tutte le occasioni.

D3js gestisce le animazioni con un solo metodo applicabile alle selezioni, transition(), che inizia una transizione con una serie di parametri di default e volendo prende come parametro una stringa che rappresenta il nome univoco della transizione:

  • funzione di easing – cubic-in-out (chiamata easeInOutCubic su easings.net),
  • ritardo – 0, la transizione parte immediatamente,
  • durata – 250 millisecondi (ms).

Per modificare questi parametri bisogna concatenarne i rispettivi metodi:

  • ease() – accetta come primo parametro una stringa (il nome della funzione di easing, i valori accettati sono qui) o anche una funzione di easing personalizzata,
  • delay() – accetta come parametro un numero intero, il ritardo in millisecondi, o la classica funzione con cui accedere ai dati associati all’elemento: function(d,i) { return ...; } ,
  • duration() – accetta come parametro un numero intero, la durata in millisecondi, o la classica funzione con cui accedere ai dati associati all’elemento: function(d,i) { return ...; } .

Dopo di che tutti i metodi a valle che agiscono su stili e attributi interpolabili saranno animati, purché impostino un valore diverso rispetto a quello già presente. Da notare che in d3js le funzioni di easing sono nominate con una sola parola, per esempio cubic (la lista completa è qui e si possono vedere in azione qui). Possono però essere modificate aggiungendo le parole in e/o out per indicane il comportamento all’inizio e alla fine della transizione. Per esempio cubic-in è la transizione semplice, cubic-out è quella invertita, cubic-in-out (quella di default) è diretta nella prima metà, inversa nella seconda, cubic-out-in viceversa. In generale le transizioni [nome]-in-out sono quelle che hanno l’effetto migliore.

Ecco un semplice esempio. Notare che le funzioni di interpolazione funzionano su tutti i numeri semplici, ma anche sulle unità di misura della dimensione (px, em, …), sui colori (sia in formate esadecimale che rgb, rgba, hsl, lab) e su altri attributi come il transform dell’SVG. Possono anche essere interamente personalizzate specificando le opportune funzioni di tweening.

Ed eccole tutte in azione (se vuoi avvia l’animazione cliccando qui).

Dancing bars…

Comporre animazioni

Puoi anche associare allo stesso elemento più transizioni, che possono agire sugli stessi attributi o su attributi diversi. In questo caso devi decidere se le vuoi eseguire in serie (una dopo l’altra), oppure in parallelo (contemporaneamente, naturalmente su attributi diversi).

Animazioni in serie

I metodi transition() si possono concatenare uno dopo l’altro sulla stessa selezione. Ogni animazione partirà quando la precedente si è conclusa, ereditando parametri come la funzione di easing, il ritardo e la durata (che però possono essere nuovamente reimpostate). Attenzione che le transizioni vengono messe in coda solo se concatenate. Se si applicano più transizioni alla stessa selezione (memorizzata per esempio in una variabile), vengono tutte interrotte e annullate tranne l’ultima.

Serial animated bar…

Animazioni in parallelo

Alle transizioni puoi dare un nome, volendo. Transizioni con lo stesso nome (o senza nome), se concatenate, sono eseguite in serie. Se applicate alla stessa selezione, annullano le transizioni precedenti. Se invece dai loro nomi diversi e le applichi alla stessa selezione, sono eseguite in parallelo. Falle agire naturalmente su attributi diversi.

Parallel animated bar…

Animazioni su selezioni annidate

Così come le selezioni si possono annidare, anche le transizioni godono della stessa proprietà. Puoi cioè fare cose del genere: d3.selectAll("p").transition().selectAll("span").transition() . La seconda transizione agisce sugli span figli, mentre la prima sugli elementi p padri. Non sono quindi in concorrenza, ma la seconda eredita i parametri della prima: funzione di easing, ritardo e durata.

Non abusarne…

È indubbio che una visualizzazione animata abbia un fascino particolare, senza contare che d3js mette a disposizione metodi molto potenti e flessibili per gestire anche complesse animazioni multiple su più attributi. Ti consiglio comunque di avere sempre come riferimento il tuo utente e la sua possibile esperienza d’uso: se un’animazione pone per esempio problemi di leggibilità, comprensione o interazione, lasciala perdere. Se non serve davvero a cogliere le informazioni che vuoi veicolare, lasciala perdere. Se alza il prezzo della tua applicazione… beh, facci un pensierino! 😉

Letture: 375