Grafi dinamici con in Canvas con Arbor.js

15 novembre 2011

In questo articolo ci serviremo di un semplice esempio per mostrare alcune delle caratteristiche di Arbor.js. Si tratta di un plugin per jQuery che sfrutta in features HTML5 come i Web workers per creare grafi animati e interattivi.

Grazie a Arbor.js possiamo creare un grafo a partire da un insieme di dati, e una volta ottenuto il rendering del grafo, possiamo spostare i nodi del grafo a piacimento. Per questo possiamo impostare anche alcune caratteristiche di archi e nodi, come l’elasticità o la resistenza al movimento.

Il disegno vero e proprio degli elementi è demandato al programmatore, che può sfruttare tecnologie come Canvas, SVG o semplice HTML. Questo ci consente di preoccuparci solo dell’aspetto del grafo, demandando alla libreria la gestione della “fisica” del sistema.

Gli usi possibili di una simile libreria sono diversi, dalla rappresentazione delle distanze tra città alle mappe mentali, dalla creazione di infografiche interattive fino alla visualizzazione di sistemi di particelle.

Figura 1. Esempio di grafo con arbor.js

Esempio di grafo

Installazione di Arbor.js

Per iniziare, come per tutti i plugin per jQuery, abbiamo bisogno di caricare la libreria di base (jQuery appunto) e il file della nostra estensione:

<script src="path/to/jquery.min.js"></script>
<script src="path/to/arbor.js"></script>

La documentazione ci consiglia di includere anche il file arbor-tween.js, che aggiungerà alcuni effetti di movimento all’oggetto ParticleSystem che utilizzeremo.

<script src="path/to/arbor-tween.js"></script>

Definire nodi e vertici del grafo

Creiamo ora il nostro primo grafo. Anzitutto è necessario organizzare i dati secondo una precisa sintassi, che definendo i nodi (o vertici) e gli archi che collegano tra loro questi elementi. Creiamo una semplice pagina che carichi dati JSON di vertici e archi via Ajax secondo questo standard:

        { 
         "nodes": [ 
         {"name": "node_1"}, {"name": "node_2"}, 
         {"name": "node_3"}, {"name": "node_4"}, 
         {"name": "node_5"}, {"name": "node_6"}, 
         {"name": "node_7"}, {"name": "node_8"}, 
         {"name": "node_9"}, {"name": "node_10"} 
         ], 
         "edges": [ 
         {"src": "node_3", "dest": "node_2"}, 
         {"src": "node_5", "dest": "node_3"}, 
         {"src": "node_8", "dest": "node_7"}, 
         {"src ":"node_1", "dest": "node_4"}, 
         {"src": "node_7", "dest": "node_5"}, 
         {"src": "node_3", "dest": "node_9"}, 
         {"src": "node_2", "dest": "node_4"}, 
         {"src": "node_6", "dest": "node_5"}, 
         {"src": "node_9", "dest": "node_1"}, 
         {"src": "node_10", "dest": "node_2"}, 
         {"src": "node_1", "dest": "node_10"} 
         ] 
        }

Nell’elemento nodes vengono specificati i nodi del grafo, mentre in edges sono registrate gli archi, ovvero le relazioni tra i nodi, grazie alle chiavi src e dest.

L’oggetto ParticleSystem

Come abbiamo detto, possiamo scegliere la tecnologia di rappresentazione che più ci è utile, per questo esempio quindi scegliamo il Canvas e aggiungiamo il nostro elemento contenitore all’interno della pagina:

    	<canvas id="viewport" width="800" height="600"></canvas>

Nell’esempio in allegato possiamo trovare tutto il codice necessario a compiere l’animazione, qui limitiamoci a esaminare in astratto il ciclo di vita della creazione del grafo:

  1. Completato il caricamento della pagina inizia la lettura delle impostazioni di Arbor.js e la costruzione del grafico;
  2. Durante il rendering di ogni vertice e nodo si verificano alcuni eventi e vengono chiamati i relativi handler, questo meccanismo ci permette di personalizzare look e comportamenti del grafo.

Vediamo nel dettaglio alcune delle istruzioni invocate nel rendering degli elementi: anzitutto è necessario creare un oggetto ParticleSystem, il sistema di particelle in cui memorizzare archi e vertici, e in cui tenere aggiornate le loro coordinate. Il costruttore del sistema può essere richiamato con:

arbor.ParticleSystem(repulsion, stiffness, friction, gravity, fps, dt, precision)

ecco il dettaglio dei parametri:

ParametroDefaultDescrizione
repulsion1000la forza repulsiva tra i nodi
stiffness600la rigidità degli spigoli
friction0.5la quantità di frizione del sistema
gravityfalseforza supplementare per attrarre i nodi alla posizione originale
fps55frames al secondo
dt0.02tempo di refresh della simulazione
precision0.6Precisione contro velocità nei calcoli della forza (0 è veloce ma nervoso, 1 è lento, ma incice sulla CPU)

I valori di default saranno utilizzati per tutti gli argomenti omessi. Per semplificare, le seguenti chiamate sono tutte equivalenti:

arbor.ParticleSystem()
arbor.ParticleSystem(600)
arbor.ParticleSystem(600, 1000, .5, 55, .02, false)
arbor.ParticleSystem({friction:.5, stiffness:600, repulsion:1000})

Un’altra modalità è creare l’oggetto ParticleSystem, e valorizzare i parametri col metodo parameters():

var sys = arbor.ParticleSystem()
sys.parameters({gravity:true, dt:0.005})

Se vuoi aggiornamenti su Grafi dinamici con in Canvas con Arbor.js inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Grafi dinamici con in Canvas con Arbor.js

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy