etiquetado del eje d3

94

¿Cómo agrego etiquetas de texto a los ejes en d3?

Por ejemplo, tengo un gráfico lineal simple con un eje xey.

En mi eje x, tengo marcas del 1 al 10. Quiero que la palabra "días" aparezca debajo para que la gente sepa que el eje x está contando días.

De manera similar, en el eje y, tengo los números del 1 al 10 como garrapatas y quiero que las palabras "comidos bocadillos" aparezcan de lado.

¿Existe una forma sencilla de hacer esto?

usuario1474218
fuente

Respuestas:

164

Las etiquetas de eje no están integradas en el componente de eje de D3 , pero puede agregar etiquetas usted mismo simplemente agregando un textelemento SVG . Un buen ejemplo de esto es mi recreación del gráfico de burbujas animado de Gapminder, The Wealth & Health of Nations . La etiqueta del eje x se ve así:

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)");

Y la etiqueta del eje y así:

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)");

También puede usar una hoja de estilo para diseñar estas etiquetas como desee, ya sea juntas ( .label) o individualmente ( .x.label, .y.label).

mbostock
fuente
9
Descubrí que .attr("transform", "rotate(-90)")hace que todo el sistema coordinado gire. Por lo tanto, si está posicionando con "x" e "y", debe cambiar las posiciones de lo que esperaba.
lubar
¿Alguna consideración especial para el caso de varios gráficos y querer etiquetas de eje en todos ellos?
ted.strauss
31

En la nueva versión de D3js (versión 3 en adelante), cuando crea un eje de gráfico a través de la d3.svg.axis()función, tiene acceso a dos métodos llamados tickValuesy tickFormatque están integrados dentro de la función para que pueda especificar para qué valores necesita los ticks y en qué formato que desea que aparezca el texto:

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");
ambodi
fuente
Buena explicación, pero parece que el OP ya tiene tics en sus ejes.
Michael Scheper
1
OP? No entiendo la abreviatura, lo siento.
Ambodi
Sin preocupaciones. OP = 'Publicación original' o 'Póster original'. (Los motores de búsqueda y urbandictionary.com son referencias bastante buenas para abreviaturas como esta).
Michael Scheper
13

Si quieres la etiqueta del eje y en el medio del eje y como hice yo:

  1. Gire el texto 90 grados con el ancla de texto en el medio
  2. Traducir el texto por su punto medio
    • posición x: para evitar la superposición de las etiquetas de marca del eje y ( -50)
    • posición y: para coincidir con el punto medio del eje y ( chartHeight / 2)

Muestra de código:

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')
    ;

Esto evita la rotación de todo el sistema de coordenadas como se menciona en lubar anteriormente.

Michael Clark
fuente
Seguro, he añadido más detalles, ¿es mejor?
Michael Clark
1
¡Sí! Ya lo voté a favor, porque su respuesta original me puso en el camino correcto, pero tal como está ahora, los futuros lectores no tendrán que jugar tanto con eso para descubrir qué significa todo. :-) Salud.
Michael Scheper
2

Si trabaja en d3.v4, como se sugiere, puede usar esta instancia que ofrece todo lo que necesita.

Es posible que desee reemplazar los datos del eje X por sus "días", pero recuerde analizar los valores de cadena correctamente y no aplicar concatenar.

¿parseTime también podría hacer el truco para los días escalando con un formato de fecha?

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)");

jugar con css / js global

因特网 的 小熊
fuente
1

D3 proporciona un conjunto de componentes de nivel bastante bajo que puede utilizar para ensamblar gráficos. Se le proporcionan los bloques de construcción, un componente de eje, unión de datos, selección y SVG. ¡Es tu trabajo juntarlos para formar un gráfico!

Si desea un gráfico convencional, es decir, un par de ejes, etiquetas de eje, un título de gráfico y un área de trazado, ¿por qué no echar un vistazo a d3fc ? es un conjunto de código abierto de componentes D3 de más alto nivel. Incluye un componente de gráfico cartesiano que podría ser lo que necesita:

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);

Puede ver un ejemplo más completo aquí: https://d3fc.io/examples/simple/index.html

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

o

xAxis: {
   axisLabel: 'Label here'
},
Ravi Tej
fuente