In questa puntata, impariamo ad usare d3.js per creare un semplice grafico a torta, di quelli che vanno molto di moda, soprattutto in campo televisivo.
Innanzitutto, occorre sottolineare come il grafico a torta e il grafico ad anello vengano creati utilizzando esattamente lo stesso processo in d3.js.
La creazione di un grafico a torta in d3.js inizia sempre utilizzando la funzione d3.pie()
. Questa funzione trasforma il valore di ogni gruppo in un raggio che verrà visualizzato sul grafico. Questo raggio viene quindi fornito alla funzione d3.arc()
che disegna l’arco per gruppo.
Innanzitutto, come abbiamo già visto nelle puntate precedenti, inseriamo il riferimento alla libreria nella sezione del file html.
Poi va aperto un tag script in cui indicare i dati per costruire la torta e i suoi spicchi. L’intero script viene riportato in coda. Analizziamo le singole parti.
Innanzitutto occorre indicare le dimensioni del canvas dell’immagine (le coordinate sono due, larghezza e lunghezza, ovvero width e lenght, in quanto la tela è un quadrilatero, in questo caso un quadrato) e i suoi margini (per comodità stabiliremo un solo valore per il margine, in modo che la distanza dai bordi del canvas sia uniforme per le quattro direzioni). Per farlo, occorre definire una variabile per ciascuno dei paragrafi
var width = 450
height = 450
margin = 40
Ora un po’ di geometria: per calcolare l’area del cerchio serve il raggio. Il raggio è quel segmento che congiunge il centro del cerchio a qualsiasi punto della circonferenza (la circonferenza è il luogo geometrico dei punti equidistanti da un punto interno detto centro, mi ripeteva sempre la buonanima del mio prof. Di Matematica al Liceo). Come si fa a sapere quanto è il raggio, avendo solo le misure della tela, cioè del quadrato che contiene il cerchio?
No, non affollatevi, velo dico io: supponendo di porre il nostro diagramma al centro della tela, la formula consiste nel ridurre a metà altezza del canvas e sottrarre il valore margine (che, come abbiamo detto, è la distanza della circonferenza dal bordo del canvas) al risultato.
var radius = Math.min(width, height) / 2 – margin
Creato il cerchio, occorre disegnarlo.
La funzione .append
ci consente di creare un file svg collocandolo in un contenitore div che chiameremo, per essere originali mydata per poi fornire alla libreria tutto quello che serve per disegnarlo:
var svg = d3.select("#my_data")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
Ora riempiamolo con dati a caso. Per ora, li inseriremo direttamente nello script, ma in altre puntate vedremo come far estrarre i dati da un file esterno.
Per rendere più evidente, occorre anche settare colori diversi per le diverse fette.
var data = {a: 9, b: 20, c:30, d:8, e:12}
var color = d3.scaleOrdinal()
.domain(data)
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"])
Poi facciamo calcolare alla libreria javascript il grafico distribuendo i singoli gruppi
var pie = d3.pie()
.value(function(d) {return d.value; })
var data_ready = pie(d3.entries(data))
infine facciamogli disegnare sul canvas il grafico. Per farlo, useremo la funzione arco (d3.arc()), come detto prima:
svg
.selectAll('whatever')
.data(data_ready)
.enter()
.append('path')
.attr('d', d3.arc()
.innerRadius(0)
.outerRadius(radius)
)
.attr('fill', function(d){ return(color(d.data.key)) })
.attr("stroke", "black")
.style("stroke-width", "2px")
.style("opacity", 0.7)
Questo è il risultato
E questo è lo script
// set the dimensions and margins of the graph var width = 450 height = 450 margin = 40
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. var radius = Math.min(width, height) / 2 - margin
// append the svg object to the div called 'my_data' var svg = d3.select("#my_data") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// Create dummy data var data = {a: 9, b: 20, c:30, d:8, e:12}
// set the color scale var color = d3.scaleOrdinal() .domain(data) .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"])
// Compute the position of each group on the pie: var pie = d3.pie() .value(function(d) {return d.value; }) var data_ready = pie(d3.entries(data))
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function. svg .selectAll('whatever') .data(data_ready) .enter() .append('path') .attr('d', d3.arc() .innerRadius(0) .outerRadius(radius) ) .attr('fill', function(d){ return(color(d.data.key)) }) .attr("stroke", "black") .style("stroke-width", "2px") .style("opacity", 0.7)