D3.JS – Aggiungere una griglia

Miglioriamo lo stile del nostro grafico aggiungendo una griglia che aiuti l’utente a leggere meglio i dati rappresentati nel grafico. L’SVG che andremo a creare sarà un contenitore con classe grid e all’interno le linee – elemento g – con classe tick.
Il css risulterà quindi come il seguente.

Definiamo due funzioni che resituiscono gli svg.axis dell’asse x e y. Le chiameremo rispettivamente make_x_axis e make_y_axis.
Andiamo successivamente a richiamarle richiamando le funzioni tickSize per definire l’altezza del tick e tickFormat per definire la label vuota. Trasliamo la griglia in base ai margini precedentemente definiti.

D3.JS – Tooltip ed eventi

Continuiamo a modificare il nostro grafico aggiungendo un tooltip per mostrare l’esatto valore del punto. Al evento “mouseover” apparirà un tooltip che mostra l’esatto valore di quel punto. Ci serviremo delle transaction per aggiungere un’effetto fade in e fade out.

Alcuni degli eventi disponibili in D3 sono:

  • mousedown: lanciato quando viene premuto il tasto sinistro del mouse
  • mouseup: lanciato quando viene rilasciato il tasto sinistro del mouse
  • mouseover: lanciato quando il mouse va dentro un elemeto
  • mouseout: lanciato quando il mouse va fuori un elemeto
  • mousemove: lanciato quando il mouse si sposta dentro un elemeto
  • click: lanciato al click (mousedown e mouseup)
  • contextmenu: lanciato quando viene premuto il tasto destro del mouse
  • dblclick: lanciato al doppio click del mouse

Come prima cosa definiamo lo stile css del nostro tooltip posizionato in absolute e con proprietà pointer-events a none. Modifichiamo la nostra funzione javascript e aggiungiamo la dichiarazione del blocco div che si limita ad appendere al div target un div con classe tooltip nascosto – opacità a 0 -. Il tooltip sarà quindi un’unico div che viene nascosto, spostato e modificato a seconda della posizione del mouse.

Modifichiamo infine il codice che disegna i cerchi aggiungendo alla fine della generazione gli eventi mouseover e mouseout.
All’evento over applicatiomo una transaction di 200 millisecondi e cambiamo l’opacità del nostro div, che in questo momento comincerà a mostarsi. Cambiamo il suo contenuto modificando l’html – html(“codice html da visualizzare”) – e spostiamolo modificando la posizione left e top.
Al mouseout ci limitiamo ad applicare una transaction di mezzo secondo in cui l’opacità viene portata a 0 per nascondere il nostro div alla visione dell’utente.

D3.JS – Clean Code

Dopo aver creato i nostri primi grafici con i tutorial precedenti è giunto il momento di riordinare il codice per mantenere lo script creato più organizzato e maggiormente mantenibile.

I problemi che saltano subito all’occhio riguardano la mancanza di variabili per definire il margine e la dimensione del grafico e alcuni pezzi di codice – come il parsing della data – che vengono riscritti più volte.

Creiamo le variabili margin, width e height, dove height e width dipendono dal margine assegnato e definiamo una funzione per il parsing della data.
Al posto dei numeri hard code utilizziamo le variabili width, height e data per impostare i range a traslare gli elementi.
Racchiudiamo il tutto in una funzione e richiamiamola passando l’array di elementi da rappresentare e il target su cui andare a rappresentare il nostro grafico.

Ricordiamoci che stile e html saranno i seguenti:

D3.JS – Il grafico

Dopo aver creato gli assi del nostro grafico dobbiamo procedere all’inserimento dei dati nel nostro grafico.
Ci basterà aggiungere al nostro elemento svg degli elementi a barre e posizionare gli elementi all’interno del grafico traslandoli – nel caso della barra con gli attributi x e y – dei pixel restituiti dalle funzioni x e y dichiarate in precedenza. Per semplicità limitiamoci a traslare i risultati di 40 pixel, il margine definito in precedenza. In un secondo momento andremo a riscrivere il codice ripulendolo e semplificandolo – da notare che al momento la scala inizia dal valore 10 e non da zero -.

Possiamo facilmente cambiare il grafico con un grafico con dei cerchi modificando solamente questa parte di codice. Dicendo a D3 di disegnare dei cerchi e impostando la posizione con gli attributi cx e xy.

Se invece vogliamo collegare i vari elementi con una linea ci è sufficente definire una svg.line mappando i valori di x e y con i nostri dati e aggiungerla al nostro grafico. Non dimentichiamoci di modificare anche il css per un risultato più gradevole.

Possiamo combinare i circle e la line per creare un grafico dove i valori effettivi sono marcati con il circle e disegnare una linea che li collega per mostrarne l’andamento nel tempo.

Questi semplici esempi mostrano la flessibilità di D3, dopo una prima configurazione iniziale, la modifica e la creazione del grafico diventa incredibilmente agile e veloce permettendoci di cambiare tipo di grafico o sovrapporre due grafici semplicemente modificando pochissime righe di codice.

D3.JS – Gli assi

Supponiamo di avere una tabella excel contenente un mese e i soldi ricavati in quel relativo mese. D3 ci permette di creare un grafico a linea per rappresentare i seguenti dati:

Date Amount
2014-01-01 10
2014-02-01 20
2014-03-01 40
2014-04-01 80

Gli assi

La costruzione del grafico inizia dai due assi principali. L’asse x (asse delle ordinate) avrà dei valori che vanno da Gennaio 2014 a Aprile 2014, mentre l’asse y (asse delle ascisse) avrò dei valori che vanno da 0 a 80.
Definiamo la dimensione del grafico a 200x300px, ma siamo liberi di scegliere qualsiasi altra dimensione.
I dati in nostro possesso rappresentano un grafico con 4 punti, il nostro obiettivo è disegnare una linea che collega questi punti creando un senso di continuità temporale.

Iniziamo la costruzione del grafico definendo i dati da rappresentare creando un semplice oggetto Javascript – D3 permette di richiamare vari formati, dai CSV ai JSON, ma lo vedremo più avanti -. Creiamo un oggetto data contenente un array di oggetti che rappresentano la nostra tabella con le key che sono data e amount.
Richiamiamo poi le funzioni max e min per ottenere il massimo o il minimo per l’asse y di questo array, specificando che il valore max e min deve essere ricercato in amount.
In alternativa possiamo utilizzare la funzione extent che restituisce un array con il valore massimo e minimo.

D3 ha un oggetto chiamato “scales” che aiuta a mappare i valori nel sistema di coordinate. Sono possibili tre tipi di scale: lineare, logaritmica e lineare per il tempo. Per configurare una scala dobbiamo specificare un dominio e un range. Il range rappresenta lo spazio in pixel disponibile, mentre il dominio rappresenta il dominio dei dati da rappresentare.
Possiamo utilizzare le funzioni viste in precedenza per configurare il dominio in automatico.
La chiamata a scale ritorna una funzione chiamata y, che dato il dato in input ritorna la posizione occupata nello spazio – ricordiamoci che l’asse delle y va dal basso verso l’alto -.

Possiamo applicare la stessa procedura anche per l’asse delle x, infatti D3 ci permette di lavorare con le date con la funzione time.scale().

Definiamo ora gli assi veri e propri. Utilizziamo la funzione svg.axis per dichiarare un nuovo asse – in questo caso l’asse x – scalato su x, che è la variabile dominio/range definita in precedenza, in cui il testo dell’asse è sotto e sono presenti 4 separatori.
Appendiamo al body un elemento svg di altezza e larghezza definita e successivamente diciamo a D3 tramite la funzione call di renderizzare il nostro asse xAxis precedentemente definito.

Per una corretta renderizzazione dobbiamo aggiungere queste righe di css che ridefiniscono il riempimento della linea del nostro asse.

Applichiamo la stessa logica anche per l’altro asse spostando leggermente gli assi di 40 pixel per creare un po’ di margine attorno ai nostri assi e traslando l’asse delle x a fondo grafico con l’attributo transform – translate(x,y). Il codice finale è quindi il seguente.

D3.JS – Primi esempi

Come anticipato nell’articolo di introduzione D3JS non è una semplice libreria per creare grafici, ma permette di manipolare il DOM in modo più profondo.

Eventi e selezioni

D3, come jQuery, permette di interagire con il DOM e “ascoltare” gli eventi. Nel seguente esempio all’evento mouse hover cambiamo lo sfondo del div con classe hover-me.

Per modificare lo stile di tutti i nodi “p” presenti in pagina la sintassi da utilizzare è la seguente

Il codice utilizzato selezionerà tutti i nodi “p” presenti in pagina. Se invece vogliamo selezionare solamente un nodo ci dobbiamo affidare a “select”

Come in JQuery i div si selezionano con “#nomediv” e le classi con “.nomeclasse”.

Dynamic Property

Un’altra funzionalità interessante sono le dynamic property che permettono di definire una proprietà dinamicamente. Il seguente codice per ogni nodo “p” imposta il colore bianco se è un elemento di indice pari e grigio se è un elemento di indice dispari

Possiamo inoltre associare dei dati al nostro nodo “p”. Per ogni elemento trovato viene associato il valore dell’array passato tramite la funzione data e la funzione style cambia la dimensione del font a seconda del valore associato

Una volta che i dati sono stati legati al documento, è possibile omettere l’operatore dei dati. D3 recupererà i dati precedentemente consentendo di ricalcolare le proprietà senza rebinding.

Enter, Exit e Transitions

Usando le funzioni enter e exit di D3 si possono creare nuovi nodi o rimuoverli se non sono più necessari.

L’aggiornamento dei nodi è l’opzione di default e vengono selezionati solo gli elementi per i quali esiste un corrispondente del dato. Per permettere l’aggiornamento completo dei dati si procede quindi a spezzare il problema in tre parti. Prima si aggiornano i nodi da modificare, poi si aggiungono i nodi nuovi e successivamente si eliminano i nodi non in più necessari.
La gestione separata di questi tre casi permette un maggiore controllo sulle transazioni, ad esempio in un grafico a barre è possibile inizializzare le barre che entrano con la vecchia scala e inserire le nuove in contemporanea all’aggiornamento della scala delle vecchie barre creando un effetto ottico più piacevole all’utente.

D3 consente di modificare un documento esistente in risposta all’interazione con l’utente, l’animazione nel corso del tempo, o la notifica anche asincrona proveniente da una terza parte.
L’approccio di D3 è basato sulla trasformazione e non sulla rappresentazione. Infatti non viene cancellato il dom e ricreato, ma viene modificato e trasformato in base alle iterazioni richieste.
Infatti il seguente codice permette di modificare la dimensione di un cerchio

D3.JS – Introduzione

D3.js è una libreria JavaScript per la manipolazione di documenti. D3 permette di “portare in vita” i dati utilizzando HTML, SVG e CSS. Essendo una libreria puramente scritta in Javascript è compatibile con i browser web recenti e meno, infatti funziona correttamente con tutti i browser che supportano SVG, supporta oltre a Chrome, Fireox anche Internet Explorer dalla versione 9 in poi.
L’approccio utilizzato è basato sul data-driven programming, ovvero le istruzioni descrivono i dati da rappresentare piuttosto che la sequenza di step da intraprendere. Da questo approccio deriva il nome della libreria d3: Data-Driven Documents

La libreria è disponibile a questo indirizzo http://d3js.org/

o in alternativa è disponibile tramite cdn:

Introduzione

D3 consente di associare dati arbitrari a un Document Object Model (DOM), e poi applicare trasformazioni basate sui dati al documento. E’ possibile utilizzare D3 per generare una tabella HTML da una matrice di numeri o utilizzare gli stessi dati per creare un grafico interattivo a barre con tecnologia SVG applicando iterazioni e/o animazioni.

D3 è uno strumento avanzato per la manipolazione di documenti in base ai dati forniti. Questo approccio permette una straordinario flessibilità e compatibilità allo standard web e permette di gestire una grande quantità di dati e comportamenti dinamici senza sovraccaricare il client.
Questa grande flessibilità e compatibilità di contro aumentano la curva di apprendimento di questa libreria, che non si propone come semplice tool per creare i grafici “standard” – come può essere Google Chart, ma un vero e proprio strumento di sviluppo per creare strumenti di visualizzazione dati altamente personalizzati e flessibili.
La grande quantità di esempi ne è la dimostrazione.

Expedia e Priceline (booking.com) detengono il 90% del mercato delle prenotazioni

Expedia e Priceline, che tra le altre detiene anche booking.com detengono dall’80% al 90% del mercato delle prenotazioni online.

Dalla parte di Priceline troviamo siti come:

  • booking.com
  • priceline.com
  • kayak
  • agoda
  • Rentalcars, leader per il noleggio di macchine
  • OpenTable, leader per la prenotazione di ristoranti

Mentre Expedia detiene, tra gli altri:

  • expedia
  • hotels.com
  • travelocity
  • hotwire
  • trivago
  • venere
  • egencia

E’ abbastanza plausibile, leggendo i nomi qui sopra, che questi due giganti delle prenotazioni online detengono la quasi totalità delle prenotazioni online in settori che esulano anche dal settore prettamente turistico.

Giusto per fare un altro esempio booking.com nel 2012 aveva – da solo – il 31% del mercato delle prenotazioni in Europa.

Una delle ultime acquisizioni di Expedia è Orbitz, per la cifra di 1.33 miliardi di dollari, andando a consolidare ulteriormente la sua posizione di leader. Negli stati uniti Orbitz ha il 21% del mercato.

Tra i partecipanti a questa “guerra” c’è anche Google, attraverso lo strumento denominato “Google Hotel Finder” che consente di trovare rapidamente gli hotel e confrontarne il prezzo fra le maggiori OTA.

Tra i nuovi arrivati troviamo anche Airbnb, anche se vende stanze o appartamenti privati e non solo hotel o strutture ricettive.