2013-04-24 9 views
13

Ho un grafico a barre verticale raggruppato in coppie. Stavo cercando di giocare con come capovolgerlo orizzontalmente. Nel mio caso, le parole chiave verrebbero visualizzate sull'asse y e la scala comparirebbe sull'asse x.D3js - modifica il grafico a barre verticale su Grafico a barre orizzontale

Ho provato a cambiare varie variabili x/y, ma questo ovviamente ha prodotto risultati funky. Su quali aree del mio codice devo concentrarmi per passare dalle barre verticali a quelle orizzontali?

My JSFiddle: Full Code

var xScale = d3.scale.ordinal() 
    .domain(d3.range(dataset.length)) 
    .rangeRoundBands([0, w], 0.05); 

// ternary operator to determine if global or local has a larger scale 
var yScale = d3.scale.linear() 
    .domain([0, d3.max(dataset, function (d) { 
    return (d.local > d.global) ? d.local : d.global; 
})]) 
    .range([h, 0]); 

var xAxis = d3.svg.axis() 
    .scale(xScale) 
    .tickFormat(function (d) { 
     return dataset[d].keyword; 
    }) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(yScale) 
    .orient("left") 
    .ticks(5); 

var commaFormat = d3.format(','); 

//SVG element 
var svg = d3.select("#searchVolume") 
    .append("svg") 
    .attr("width", w + margin.left + margin.right) 
    .attr("height", h + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

// Graph Bars 
var sets = svg.selectAll(".set") 
    .data(dataset) 
    .enter() 
    .append("g") 
    .attr("class", "set") 
    .attr("transform", function (d, i) { 
     return "translate(" + xScale(i) + ",0)"; 
    }); 

sets.append("rect") 
    .attr("class", "local") 
    .attr("width", xScale.rangeBand()/2) 
    .attr("y", function (d) { 
     return yScale(d.local); 
    }) 
    .attr("x", xScale.rangeBand()/2) 
    .attr("height", function (d) { 
     return h - yScale(d.local); 
    }) 
    .attr("fill", colors[0][1]) 
    ; 

sets.append("rect") 
    .attr("class", "global") 
    .attr("width", xScale.rangeBand()/2) 
    .attr("y", function (d) { 
     return yScale(d.global); 
    }) 
    .attr("height", function (d) { 
    return h - yScale(d.global); 
    }) 
    .attr("fill", colors[1][1]) 
    ; 

    sets.append("rect") 
     .attr("class", "global") 
     .attr("width", xScale.rangeBand()/2) 
     .attr("y", function (d) { 
     return yScale(d.global); 
    }) 
     .attr("height", function (d) { 
     return h - yScale(d.global); 
    }) 
     .attr("fill", colors[1][1]) 
    ; 

risposta

7

Ho fatto la stessa cosa la notte scorsa, e in pratica ho finito per riscrivere il codice perché era più veloce di correggere tutti i bug ma ecco i suggerimenti che posso darti.

I maggiori problemi con il capovolgimento dell'asse x e y saranno con cose come return h - yScale(d.global) perché l'altezza viene calcolata dalla "parte superiore" della pagina non in basso.

Un'altra cosa fondamentale da ricordare è che quando si imposta .attr("x", ..) assicurarsi che si imposta su 0 (più l'eventuale imbottitura per il lato sinistro) in modo = .attr("x", 0)"

Ho usato questo tutorial per aiutarmi a pensare il mio codice in termini di barre orizzontali, invece - è veramente aiutato

http://hdnrnzk.me/2012/07/04/creating-a-bar-graph-using-d3js/

ecco il mio proprio codice rendendolo orizzontale se aiuta:

var w = 600; 
var h = 600; 
var padding = 30; 

var xScale = d3.scale.linear() 
     .domain([0, d3.max(dataset, function(d){ 
           return d.values[0]; })]) //note I'm using an array here to grab the value hence the [0] 
     .range([padding, w - (padding*2)]); 

     var yScale = d3.scale.ordinal() 
      .domain(d3.range(dataset.length)) 
      .rangeRoundBands([padding, h- padding], 0.05); 

     var svg = d3.select("body") 
      .append("svg") 
      .attr("width", w) 
      .attr("height", h) 

     svg.selectAll("rect") 
      .data(dataset) 
      .enter() 
      .append("rect") 
      .attr("x", 0 + padding) 
      .attr("y", function(d, i){ 
      return yScale(i); 
      }) 
      .attr("width", function(d) { 
       return xScale(d.values[0]); 
      }) 
      .attr("height", yScale.rangeBand()) 
+0

È inoltre possibile fare riferimento a questo https: //gist.github.com/ChandrakantThakkarDigiCorp/9587e667a3fab912537de03717af84a2 Contiene grafico a barre orizzontale con suggerimenti e legenda, inoltre è responsabile nei dispositivi mobili –

1

Ecco la procedura che uso in questo caso:

1) Inverse tutti Xs e Ys

2) Ricordiamo che il 0 per y è in cima , quindi dovrai invertire molti valori come i valori precedenti per y saranno invertiti (non vuoi che il tuo asse x vada da sinistra a destra) e anche il nuovo asse y sarà invertito.

3) Verificare che le barre visualizzate correttamente

4) Adattare leggende se ci sono problemi

Questa domanda può aiutare nel senso che mostra come andare da grafici a barre orizzontali a verticale: d3.js histogram with positive and negative values

5

Un'alternativa è quella di ruotare il grafico (vedere this). Questo è un po 'hacky come allora è necessario mantenere gli assi scambiati nella tua testa (l'altezza è in realtà la larghezza, ecc.), Ma è probabilmente più semplice se hai già un grafico verticale funzionante.

Un esempio di rotazione del grafico è riportato di seguito. Potrebbe essere necessario ruotare anche il testo per renderlo piacevole.

_chart.select('g').attr("transform","rotate(90 200 200)"); 
0

Un altro grafico orizzontale interessante NVD3 che ho trovato utile. Provaci.