маркировка оси d3

94

Как добавить текстовые метки к осям в d3?

Например, у меня есть простой линейный график с осями x и y.

На моей оси X есть отметки от 1 до 10. Я хочу, чтобы под ним появилось слово «дни», чтобы люди знали, что ось x ведет отсчет дней.

Точно так же на оси Y у меня есть числа от 1 до 10 в виде отметок, и я хочу, чтобы слова «съеденные сэндвичи» отображались боком.

Есть простой способ сделать это?

user1474218
источник

Ответы:

164

Метки осей не встроены в компонент оси D3 , но вы можете добавить метки самостоятельно, просто добавив textэлемент SVG . Хорошим примером этого является мое воссоздание анимированной пузырьковой диаграммы Gapminder « Богатство и здоровье народов» . Метка оси x выглядит так:

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 вроде этого:

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

Вы также можете использовать таблицу стилей, чтобы стилизовать эти метки по своему усмотрению, вместе ( .label) или по отдельности ( .x.label, .y.label).

mbostock
источник
9
Я обнаружил, что это .attr("transform", "rotate(-90)")вызывает вращение всей системы координат. Таким образом, если вы позиционируете «x» и «y», вам нужно поменять местами позиции, которые я ожидал.
lubar
какие-либо особые соображения в случае нескольких диаграмм и желающих подписать оси на всех из них?
ted.strauss
31

В новой версии D3js (версия 3 года), при создании оси диаграммы с помощью d3.svg.axis()функции вы доступ к двум методам называются tickValuesи tickFormatкоторые встроены внутри функции , так что вы можете определяешь , какие ценности вы нужны тики для и в каком формат, в котором должен отображаться текст:

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
источник
Хорошее объяснение, но кажется, что у OP уже есть галочки на осях.
Майкл Шепер
1
ОП? Я не понимаю аббревиатуры, извините.
ambodi
Не беспокойся. OP = 'Оригинальный пост' или 'Оригинальный постер'. (Поисковые системы и urbandictionary.com - довольно хорошие ссылки для подобных сокращений.)
Майкл Шепер,
13

Если вы хотите, чтобы метка оси Y находилась посередине оси Y, как я:

  1. Повернуть текст на 90 градусов с привязкой текста посередине
  2. Переведите текст по его середине
    • Положение x: для предотвращения перекрытия меток отметок оси Y (-50 )
    • Положение y: соответствует средней точке оси y ( chartHeight / 2)

Пример кода:

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

Это предотвращает вращение всей системы координат, как упомянуто Любаром выше.

Майкл Кларк
источник
Конечно, я добавил больше деталей, так лучше?
Майкл Кларк
1
Ага! Я уже поддержал его, потому что ваш первоначальный ответ направил меня на правильный путь, но так, как сейчас, будущим читателям не придется так много возиться с ним, чтобы понять, что все это означает. :-) Ура.
Майкл Шепер
3

Если вы работаете с d3.v4, как было предложено, вы можете использовать этот экземпляр, предлагающий все, что вам нужно.

Вы можете просто заменить данные оси X своими «днями», но не забудьте правильно анализировать строковые значения и не применять конкатенацию.

parseTime может также помочь с масштабированием дней с помощью формата даты?

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

скрипка с глобальным css / js

因特网 的 小熊
источник
1

D3 предоставляет довольно низкоуровневый набор компонентов, которые вы можете использовать для сборки диаграмм. Вам предоставляются строительные блоки, компонент оси, соединение данных, выбор и SVG. Ваша работа - собрать их вместе в диаграмму!

Если вам нужна обычная диаграмма, то есть пара осей, метки осей, заголовок диаграммы и область построения, почему бы не взглянуть на d3fc ? это набор компонентов D3 более высокого уровня с открытым исходным кодом. Он включает компонент декартовой диаграммы, который может вам пригодиться:

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

Вы можете увидеть более полный пример здесь: https://d3fc.io/examples/simple/index.html

Колин
источник
0
chart.xAxis.axisLabel('Label here');

или

xAxis: {
   axisLabel: 'Label here'
},
Рави Тедж
источник