etichettatura asse d3


94

Come si aggiungono etichette di testo agli assi in d3?

Ad esempio, ho un semplice grafico a linee con un asse x e y.

Sul mio asse x, ho segni di graduazione da 1 a 10. Voglio che la parola "giorni" appaia sotto di essa in modo che le persone sappiano che l'asse x sta contando i giorni.

Allo stesso modo, sull'asse y, ho i numeri da 1 a 10 come segni di spunta e voglio che le parole "panini mangiati" appaiano lateralmente.

C'è un modo semplice per fare questo?

Risposte:


164

Le etichette degli assi non sono integrate nel componente degli assi di D3 , ma puoi aggiungere etichette da solo semplicemente aggiungendo un textelemento SVG . Un buon esempio di ciò è la mia ricreazione del grafico a bolle animato di Gapminder, The Wealth & Health of Nations . L'etichetta dell'asse x ha questo aspetto:

svg.append("text")
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width)
    .attr("y", height - 6)
    .text("income per capita, inflation-adjusted (dollars)");

E l'etichetta dell'asse y in questo modo:

svg.append("text")
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .text("life expectancy (years)");

Puoi anche utilizzare un foglio di stile per definire lo stile di queste etichette come preferisci, insieme ( .label) o individualmente ( .x.label, .y.label).


9
Ho scoperto che questo .attr("transform", "rotate(-90)")fa ruotare l'intero sistema di coordinate. Quindi, se stai posizionando con "x" e "y", devi scambiare le posizioni da quello che mi aspettavo.
lubar

qualche considerazione speciale per il caso di più grafici e che vogliono le etichette degli assi su tutti loro?
ted.strauss

31

Nella nuova versione D3js (dalla versione 3 in poi), quando crei un asse del grafico tramite la d3.svg.axis()funzione hai accesso a due metodi chiamati tickValuese tickFormatche sono incorporati all'interno della funzione in modo da poter specificare per quali valori hai bisogno dei tick e in cosa formato in cui desideri che appaia il testo:

var formatAxis = d3.format("  0");
var axis = d3.svg.axis()
        .scale(xScale)
        .tickFormat(formatAxis)
        .ticks(3)
        .tickValues([100, 200, 300]) //specify an array here for values
        .orient("bottom");

Bella spiegazione, ma sembra che l'OP abbia già le zecche sui loro assi.
Michael Scheper

1
OPERAZIONE? Non capisco l'abbreviazione, mi dispiace.
ambodi

Nessun problema. OP = "Post originale" o "Poster originale". (I motori di ricerca e urbandictionary.com sono ottimi riferimenti per abbreviazioni come questa.)
Michael Scheper,

13

Se vuoi l'etichetta dell'asse y al centro dell'asse y come ho fatto io:

  1. Ruota il testo di 90 gradi con l'ancoraggio del testo al centro
  2. Traduci il testo dal suo punto medio
    • Posizione x: per evitare la sovrapposizione delle etichette di graduazione dell'asse y ( -50)
    • posizione y: per abbinare il punto medio dell'asse y ( chartHeight / 2)

Esempio di codice:

var axisLabelX = -50;
var axisLabelY = chartHeight / 2;

chartArea
    .append('g')
    .attr('transform', 'translate(' + axisLabelX + ', ' + axisLabelY + ')')
    .append('text')
    .attr('text-anchor', 'middle')
    .attr('transform', 'rotate(-90)')
    .text('Y Axis Label')
    ;

Ciò impedisce la rotazione dell'intero sistema di coordinate come menzionato da lubar sopra.


Certo, ho aggiunto qualche dettaglio in più, va meglio?
Michael Clark

1
Sì! L'ho già votato positivamente, perché la tua risposta originale mi ha messo sulla strada giusta, ma com'è adesso, i futuri lettori non dovranno giocherellarci tanto per capire cosa significa tutto questo. :-) Saluti.
Michael Scheper

2

Se lavori in d3.v4, come suggerito, puoi utilizzare questa istanza che offre tutto ciò di cui hai bisogno.

Potresti semplicemente sostituire i dati dell'asse X con i tuoi "giorni", ma ricorda di analizzare correttamente i valori delle stringhe e non applicare la concatenazione.

parseTime potrebbe anche fare il trucco per i giorni che ridimensionano con un formato di data?

d3.json("data.json", function(error, data) {
if (error) throw error;

data.forEach(function(d) {
  d.year = parseTime(d.year);
  d.value = +d.value;
});

x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([d3.min(data, function(d) { return d.value; }) / 1.005, d3.max(data, function(d) { return d.value; }) * 1.005]);

g.append("g")
    .attr("class", "axis axis--x")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x));


g.append("g")
    .attr("class", "axis axis--y")
    .call(d3.axisLeft(y).ticks(6).tickFormat(function(d) { return parseInt(d / 1000) + "k"; }))
  .append("text")
    .attr("class", "axis-title")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .attr("fill", "#5D6971")
    .text("Population)");

giocherellare con css / js globale


1

D3 fornisce un set di componenti di livello piuttosto basso che puoi utilizzare per assemblare i grafici. Vengono forniti gli elementi costitutivi, un componente dell'asse, l'unione dei dati, la selezione e SVG. È il tuo lavoro metterli insieme per formare un grafico!

Se desideri un grafico convenzionale, ovvero una coppia di assi, etichette degli assi, un titolo del grafico e un'area del tracciato, perché non dare un'occhiata a d3fc ? è un insieme open source di più componenti D3 di alto livello. Include un componente grafico cartesiano che potrebbe essere ciò di cui hai bisogno:

var chart = fc.chartSvgCartesian(
    d3.scaleLinear(),
    d3.scaleLinear()
  )
  .xLabel('Value')
  .yLabel('Sine / Cosine')
  .chartLabel('Sine and Cosine')
  .yDomain(yExtent(data))
  .xDomain(xExtent(data))
  .plotArea(multi);

// render
d3.select('#sine')
  .datum(data)
  .call(chart);

Puoi vedere un esempio più completo qui: https://d3fc.io/examples/simple/index.html


0
chart.xAxis.axisLabel('Label here');

o

xAxis: {
   axisLabel: 'Label here'
},
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.