rotulagem do eixo d3

94

Como faço para adicionar rótulos de texto aos eixos em d3?

Por exemplo, tenho um gráfico de linha simples com eixos xey.

No meu eixo x, tenho marcações de 1 a 10. Quero que a palavra "dias" apareça abaixo dele para que as pessoas saibam que o eixo x está contando os dias.

Da mesma forma, no eixo y, tenho os números de 1 a 10 como carrapatos e quero que as palavras "sanduíches comidos" apareçam de lado.

Existe uma maneira simples de fazer isso?

user1474218
fonte

Respostas:

164

Os rótulos do eixo não são integrados ao componente do eixo do D3 , mas você mesmo pode adicionar rótulos simplesmente adicionando um textelemento SVG . Um bom exemplo disso é a minha recriação do gráfico de bolhas animado de Gapminder, The Wealth & Health of Nations . O rótulo do eixo x se parece com isto:

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 o rótulo do eixo y assim:

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

Você também pode usar uma folha de estilo para definir o estilo desses rótulos como desejar, juntos ( .label) ou individualmente ( .x.label, .y.label).

mbostock
fonte
9
Descobri que isso .attr("transform", "rotate(-90)")faz com que todo o sistema de coordenadas gire. Assim, se você estiver posicionando com "x" e "y", você precisa trocar as posições do que eu esperava.
lubar
alguma consideração especial para o caso de vários gráficos e querendo rótulos de eixo em todos eles?
ted.strauss
31

Na nova versão do D3js (versão 3 em diante), quando você cria um eixo do gráfico via d3.svg.axis()função, você tem acesso a dois métodos chamados tickValuese tickFormatque estão embutidos na função para que possa especificar quais valores você precisa dos tiques para e em quais formato que você deseja que o texto apareça:

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
fonte
Boa explicação, mas parece que o OP já tem marcações em seus eixos.
Michael Scheper
1
OP? Não entendi a abreviatura, desculpe.
ambodi
Não se preocupe. OP = 'Postagem Original' ou 'Pôster Original'. (Motores de busca e urbandictionary.com são referências muito boas para abreviações como esta.)
Michael Scheper
13

Se você quiser o rótulo do eixo y no meio do eixo y como eu fiz:

  1. Girar texto 90 graus com âncora de texto no meio
  2. Traduza o texto pela metade
    • posição x: para evitar a sobreposição de rótulos de escala do eixo y ( -50)
    • posição y: para coincidir com o ponto médio do eixo y ( chartHeight / 2)

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

Isso evita a rotação de todo o sistema de coordenadas, conforme mencionado por lubar acima.

Michael Clark
fonte
Claro, adicionei mais alguns detalhes, está melhor?
Michael Clark
1
Sim! Já votei positivamente porque sua resposta original me colocou no caminho certo, mas do jeito que está agora, os futuros leitores não terão que mexer tanto nela para descobrir o que tudo isso significa. :-) Felicidades.
Michael Scheper de
2

Se você trabalha em d3.v4, conforme sugerido, você pode usar esta instância oferecendo tudo que você precisa.

Você pode querer apenas substituir os dados do eixo X pelos seus "dias", mas lembre-se de analisar os valores da string corretamente e não aplicar concatenação.

parseTime também pode fazer o truque para escalar dias com um formato de 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)");

mexer com css / js global

因特网 的 小熊
fonte
1

D3 fornece um conjunto de componentes de baixo nível que você pode usar para montar gráficos. Você recebe os blocos de construção, um componente de eixo, junção de dados, seleção e SVG. É seu trabalho colocá-los juntos para formar um gráfico!

Se você deseja um gráfico convencional, ou seja, um par de eixos, rótulos de eixo, um título de gráfico e uma área de plotagem, por que não dar uma olhada no d3fc ? é um conjunto de código aberto de componentes D3 de alto nível. Inclui um componente de gráfico cartesiano que pode ser o que você precisa:

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

Você pode ver um exemplo mais completo aqui: https://d3fc.io/examples/simple/index.html

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

ou

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