2015-05-10 12 views
9

Voglio ottenere qualcosa come un arco crescente che indica 5 livelli (vedi immagine). I miei dati hanno solo un valore intero compreso tra 1-5. Puoi ignorare l'icona nel mezzo per ora. C'è qualche possibilità di ottenere qualcosa del genere in d3? Non ho trovato alcun esempio per questo. Inoltre l'ho provato con un approccio a torta a torta (ciambella), ma non sono riuscito a fare l'arco in crescita ... Apprezzerei qualsiasi aiuto! Grazie per quello.D3: grafico di gauge con arco crescente

enter image description here enter image description here

+0

Grazie per le vostre risposte finora. Speriamo che qualcun altro abbia una soluzione d3. Altrimenti devo accettare una delle tue risposte. –

risposta

7

Si può fare ciò con d3 senza dipendere da immagini esterne, sprite SVG o altro nel DOM - solo d3.js.

Ecco uno working fiddle. L'implementazione è spiegata di seguito. Ma anche, ecco un violino more advanced che anima un percorso di ritaglio sull'arco crescente. Controlla its predecessor per vedere come appare la maschera senza ritaglio.

Innanzitutto, è necessario rappresentare la grafica come una matrice di dati a cui si associa con d3. In particolare, è necessario un colore e di una "riga di comando" (la stringa che si assegna a d come in <path d="..."> Qualcosa di simile a questo:.

var segmentData = [ 
    { color:"#ED6000", cmd:"M42.6,115.3c5.2,1.5,11,2.4,16.8,2.4c1.1,0,2.7,0,3.7-0.1v-2.2c-7,0-13.1-1.3-18.8-3.6L42.6,115.3z" }, 
    { color:"#EF7D00", cmd:"M25.7,99.3c4.3,4.7,9.5,8.6,15.3,11.3l-1.4,3.8c-6.9-2.4-13.2-6.1-18.6-10.8L25.7,99.3z" }, 
    { color:"#F4A300", cmd:"M23.7,97c-5.2-6.4-8.8-14-10.3-22.4L2.9,75.7c2.9,10,8.5,18.9,15.8,25.9L23.7,97z" }, 
    { color:"#F7BC00", cmd:"M13,71.5c-0.2-2-0.4-4-0.4-6c0-10.7,3.4-20.6,9.2-28.8L9.4,28.3c-5.6,9-8.9,19.6-8.9,30.9 c0,4.6,0.6,9.1,1.6,13.5L13,71.5z" }, 
    { color:"#FFCF36", cmd:"M63,15.7V0.8c-1-0.1-2.5-0.1-3.7-0.1c-19.9,0-37.5,9.9-48.1,25l12.7,8.6C33.1,23,46,15.7,63,15.7z" } 
]; 

Allora avete bisogno di un vuoto <svg> e probabilmente un <g> al suo interno, in cui disegnare la grafica:

var svg = d3.select("body").append("svg") 
    .attr("width", 125) 
    .attr("height", 125); 

var gauge = svg.append("g"); 

quindi si utilizza D3 vincolante per creare i segmenti:

var segments = gauge.selectAll(".segment") 
    .data(segmentData); 
segments.enter() 
    .append("path") 
    .attr("fill", function(d) { return d.color; }) 
    .attr("d", function(d) { return d.cmd; }); 

Questo crea solo la gr aphic, ma non colora in base a un valore intero. Per questo, è possibile definire una funzione update:

function update(value) { 
    segments 
     .transition() 
     .attr("fill", function(d, i) { 
      return i < value ? d.color : "#ccc"; 
     }) 
} 

Calling update(4) coloreranno tutti, ma l'ultimo segmento. Chiamando il colore update(0) nessuno (lasciandoli tutti in grigio).

Nel violino, c'è anche una funzione tick() che chiama update con un nuovo valore su base setTimeout, ma è solo per demo.

Infine, se si desidera, è possibile avvolgere tutto ciò che il codice e creare un componente riutilizzabile seguendo i consigli di [questo articolo]. (http://bost.ocks.org/mike/chart/)

+0

Esattamente quello che stavo cercando. Grazie per quello! Inoltre sarebbe interessante come hai raggiunto i dati del cmd del segmento. –

+1

Oh sì, ho dimenticato di menzionare che i dati del percorso provengono dallo svg che @krzysiej ha collegato al di sotto. Non sono sicuro da dove venisse quel svg. – meetamit

+0

@ user1189762 grazie! – meetamit

4

dal momento che è relativamente semplice immagine, userei un folletto, con 5 variazioni. Questo sarebbe molto più semplice dell'uso di d3 e dà lo stesso risultato. (potresti usare qualche strumento online come http://spritepad.wearekiss.com/)

+0

come opzione che consente di risparmiare traffico Suggerirei solo due immagini: una completamente completa e una completamente vuota. Dovrebbero essere posizionati in modo identico in posizione assoluta. E l'immagine _full dovrebbe essere ritagliata da un contenitore. Dimensione del contenitore controllata da javascript ...Ma generalmente presumo l'approccio corretto dal momento che d3 non è destinato a roba del genere –