Introduzione
Ultimamente mi capita sempre più spesso di dover proporre un ambiente di sviluppo dove poter testare facilmente il codice Javascript necessario a produrre grafici e rappresentazione di dati. Personalmente faccio uso di Aptana IDE come ambiente di sviluppo e utilizzo WAMP (for Windows) e LAMP (for Linux).. Però generalmente durante i vari tutorial, articoli e presentazioni preferisco fare riferimento a jsFiddle: un ambiente online in cui è possibile testare e salvare in tempo reale il codice JavaScript definendo anche le relative dichiarazioni CSS e le tag HTML.
Però chi fa uso di jsFiddle, e soprattutto lo fa per testare vari esempi della libreria D3, troverà abbastanza presto una problematica che non è poi così banale da superare. D3 fa spesso uso di file esterni (JSON, CSV, TSV, ecc) per caricare i dati che dovranno poi essere rappresentati mediante un grafico, ora però jsFiddle al momento attuale non prevede l’import di file esterni.
Dato che jsFiddle è un ambiente online, non ci sarebbe meglio risposta a questa problematica se non quella di caricare file dati immagazzinati all’interno di GitHub. Abbiamo così a disposizione un ambiente “cloud” in cui sia il codice, che i dati che anche l’ambiente di test stesso, vengono messo a disposizione per tutti quelli che hanno un browser, senza preoccuparsi minimanente di installarsi un Web Server, un ambiente di sviluppo come Aptana, evitando inoltre di copiare enormi file contenenti innumerevoli righe di dati e di codice.
Ma vediamo più in dettaglio tutti questi aspetti.
jsFiddle
jsFiddle è una applicazione online che permette agli sviluppatori di gestire in modo rapido e separatamente i 3 elementi base su cui si basa la programmazione Web:
- HTML
- JavaScript
- CSS
Scrivendo separatamente le tre parti di codice di una generica pagina HTML è possibile testare in tempo reale quello che si sta scrivendo, tutto nella stessa pagina. Inoltre i risultati del nostro lavoro potranno in seguito essere salvati per un uso successivo, e persino condivisi in rete.
Infatti è sempre più facile trovare in rete riferimenti e link ad esempi presenti su jsFiddle. Ciò lo rende particolarmente adatto agli autori di tutorial e di esempi che facciano uso di codice JavaScript. Copiando il link di un determinato esempio sviluppato su jsFiddle, si permetterà al lettore di un tutorial di vedere in tempo reale il risultato di ciò che viene descritto. Ma non solo, il lettore potrà testarlo, eseguendolo e modificandolo a sua volta, in modo così da comprendere al meglio il codice descritto in un articolo.
Esempio: il dendrogramma circolare su jsFiddle
Nell’esempio trattato nell’articolo I dendrogrammi circolari, la funzione d3.json() carica la struttura dati contenuta all’interno di un file JSON esterno. Questa di solito è la prassi consueta e normale per lo sviluppo di una pagina web caricata su un Web Server. Mentre se di fa uso di jsFiddle per testare il codice descritto nell’articolo è necessario fare qualche piccola modifica.
L’approccio più semplice è quello che generalmente si trova in tutti gli esempi jsFiddle che ho trovato navigando qua e là in rete. Tale approccio consiste nel definire il contenuto del file JSON all’interno di una variabile definita all’interno della pagine jsFiddle.
Nel nostro caso, (vedi l’esempio direttamente su jsFiddle) sarà quello di definire la struttura JSON del dendrogramma come oggetto nella variabile root. (non dimenticate il punto e virgola alla fine!!!)
var root = { "name": "root",
"children": [
{"name": "parent A",
"children": [
{"name": "child A1"},
{"name": "child A2"},
{"name": "child A3"},
{"name": "child A4"},
{"name": "child A5"},
{"name": "child A6"}
] },
{"name": "parent B",
"children": [
{"name": "child B1"},
{"name": "child B2"},
{"name": "child B3"},
{"name": "child B4"},
{"name": "child B5"},
{"name": "child B6"},
{"name": "child B7"},
{"name": "child B8"}
] },
{"name": "parent C",
"children": [
{"name": "child C1"},
{"name": "child C2"},
{"name": "child C3"},
{"name": "child C4"}
] }
] };
Inoltre sarà necessario cancellare (o commentare) la chiamata alla funzione d3.json() e la parentesi graffa finale.
//d3.json("dendrogram02.json", function(error, root){ ... //});
Alla fine il risultato sulla pagina di jsFiddle sarà identico a quello che si avrebbe su qualsiasi browser.
GitHub
Creazione di un Repository online su GitHub
Dal sito di GitHub.com è possibile creare un nuovo repository
Creazione della tua repository locale con Git
Adesso, questa serie di operazioni verranno effettuate da riga di comando. Si crea una directory che costituirà la versione locale del repository che ci accingiamo a creare.
> mkdir d3.examples
all’interno di essa si lancia il comando di inizializzazione di git
> cd ∼/d3.examples
> git init
All’interno di questa directory copiamo il file JSON contenente la struttura dati del dendrogramma dendrogram02.json. Segnaliamo poi a git il nuovo file appena copiato all’interno del repository locale.
> git add dendrogram02.json
Ora è il momento di effettuare una commit
> git commit -m “Add first json”
Adesso è necessario connettere il repository locale a quello creato su GitHub
> git remote add origin https://github.com/meccanismocomplesso/d3.examples.git
Se invece vogliamo modificare una connessione già esistente:
> git remote set-url origin https://github.com/meccanismocomplesso/d3.examples.git
Se desideri ottenere una lista delle origini remote del tuo repository locale, scrivi il seguente comando
> git remote -v
Infine per fare l’upload del file dal repository locale a quello presente su GitHub, scriviamo:
> git push -u origin master
Giusto per curiosità, se avessimo bisogno di rimuovere un file da Github, prima lo rimuoviamo dal repository locale,
> git rm file.json
e poi rieseguiamo le operazioni precedenti di commit e upload
> git commit -m “Remove JSON”
> git push -u origin master
Riferimenti in rete
Per risolvere l’esigenza di lettura di file di dati immagazzinati all’interno di GitHub facendo uso di jsFiddle ho fatto riferimento all’ esempio di Zalun:
GitHub : https://github.com/zalun/jsFiddleGithubDemo/tree/master/Demo
jsFiddle: http://jsfiddle.net/gh/get/mootools/1.2/zalun/jsFiddleGithubDemo/tree/master/Demo/
che ha sviluppato un’ottimo esempio per capire i meccanismi che stanno alla base del trasferimento dati tra GitHub e jsFiddle.
Ma soprattutto l’esempio di LordBaco si è dimostrato quello di fondamentale importanza per la realizzazione finale dell’esempio trattato in questo articolo.
jsFiddle: http://jsfiddle.net/lordbaco/8KDg6/
Esempio: il dendrogramma circolare con il JSON file su GitHub
Dagli esempi precedenti, il passo finale è quello di realizzare un esempio con la libreria D3 che fa effettivamente uso di dati JSON precedentemente da me immagazzinati in GitHub.
GitHub: https://github.com/meccanismocomplesso/d3.examples
jsFiddle: http://jsfiddle.net/meccanismocomplesso/yLkyt8ow/
Ecco il codice:
var radius = 250;
var margin = 120;
var angle = 360;
var root;
var cluster = d3.layout.cluster()
.size([angle, radius-margin]);
var diagonal = d3.svg.diagonal.radial()
.projection (function(d) { return [d.y, d.x / 180* Math.PI];});
var svg = d3.select("body").append("svg")
.attr("width",2*radius)
.attr("height",2*radius)
.append("g")
.attr("transform","translate("+radius + "," + radius + ")");
var url = '/gh/get/response.json/meccanismocomplesso/d3.examples/tree/master/';
d3.xhr(url)
.header("X-Requested-With", "XMLHttpRequest")
.header("Content-Type", "application/x-www-form-urlencoded")
.post("delay=1", function (error, request) {
if (error) return console.warn(error.responseText);
root = jQuery.parseJSON( request.responseText);
//});
//d3.json("dendrogram02.json", function(error, root){
var nodes = cluster.nodes(root);
var links = cluster.links(nodes);
var link = svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class","link")
.attr("d", diagonal);
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class","node")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; });
node.append("circle")
.attr("r", 4.5);
node.append("text")
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
.text(function(d) { return d.name; });
});
Il risultato è identico a quello precedente solo che questa volta è possibile caricare qualsiasi file JSON presente su GitHub.
Conclusioni
L’esempio precedente può essere immediatamente esteso anche per dataset contenuti in file CSV e TSV. Il meccanismo è pressochè lo stesso.