Настройка делений: .ticks(), .tickValues(), .tickSize()

Механизм делений (ticks) в D3.js является ключевым элементом при построении осей и визуализации числовых шкал. Он отвечает за формирование набора значений, отображаемых на осях графиков, а также за их визуальное представление: количество, позиционирование и длину штрихов.

Основная работа с делениями происходит через методы генераторов осей, построенных на основе шкал (scaleLinear, scaleTime, scaleLog и других). Эти методы позволяют тонко управлять тем, какие значения будут показаны пользователю и как они будут оформлены визуально.


При использовании стандартного генератора оси D3.js автоматически вычисляет набор значений, называемых ticks. Алгоритм подбирает их на основе:

  • диапазона шкалы (domain)
  • размера визуального пространства (range)
  • типа шкалы
  • внутренней эвристики «читабельности»

Пример поведения:

  • для малого диапазона — больше делений
  • для большого диапазона — меньше делений
  • для временных шкал — адаптация под минуты, часы, дни и т.д.

Автоматическая генерация является отправной точкой, но практически всегда требует уточнения.


.ticks() — управление количеством делений

Метод .ticks() применяется к шкалам и задаёт желаемое количество делений на оси.

Сигнатура

scale.ticks(count)

Поведение

  • count задаёт ориентировочное число делений
  • фактическое количество может отличаться
  • D3 стремится подобрать «красивые» значения

Пример

const scale = d3.scaleLinear()
  .domain([0, 100])
  .range([0, 500]);

const ticks = scale.ticks(5);

В результате формируется набор значений, например:

[0, 20, 40, 60, 80, 100]

Особенности алгоритма

D3 не просто делит диапазон на равные части. Используется подбор «nice numbers»:

  • 1, 2, 5, 10, 20, 50, 100
  • округление границ диапазона
  • адаптация под читаемость

Это означает, что результат может слегка выходить за пределы исходного domain, если включена нормализация через .nice().


.tickValues() — полное управление набором значений

Метод .tickValues() полностью переопределяет автоматическую генерацию делений.

Сигнатура

axis.tickValues(values)

Поведение

  • отключает алгоритм автоматического подбора
  • используется строго заданный массив значений
  • порядок и состав полностью контролируются вручную

Пример

const axis = d3.axisBottom(scale)
  .tickValues([0, 25, 50, 75, 100]);

Применение

Использование оправдано в случаях:

  • фиксированные категории на числовой оси
  • важные контрольные точки
  • нестандартная логика разметки
  • синхронизация нескольких осей

Ограничения

  • отсутствие адаптации под размер графика
  • возможное наложение подписей при большом количестве значений
  • игнорирование эвристик D3

.tickSize() — управление длиной штрихов

Метод .tickSize() определяет длину линий делений (tick marks), отходящих от оси.

Сигнатура

axis.tickSize(size)

Поведение

  • size задаётся в пикселях
  • влияет на визуальную длину линий
  • применяется ко всем делениям оси

Пример

const axis = d3.axisBottom(scale)
  .tickSize(10);

Это создаёт штрихи длиной 10 пикселей.


Разделение внутренней и внешней длины делений

D3 различает два параметра:

  • основная длина (tickSize) — длина в одном направлении
  • внутренняя и внешняя длина

.tickSizeInner()

Определяет длину штрихов внутри области графика:

axis.tickSizeInner(6);

.tickSizeOuter()

Определяет длину крайних делений (на концах оси):

axis.tickSizeOuter(12);

Поведение

  • inner влияет на промежуточные ticks
  • outer влияет на крайние границы оси
  • часто используется для визуального выделения начала и конца шкалы

Комбинирование tickSize, tickValues и ticks

Эти методы могут использоваться совместно, но их взаимодействие подчиняется приоритетам:

  1. tickValues() — абсолютный приоритет (полная фиксация)
  2. ticks() — рекомендация количества
  3. tickSize() — визуальное оформление

Пример комбинированной настройки

const axis = d3.axisBottom(scale)
  .tickValues([0, 30, 60, 90])
  .tickSize(8);

В этом случае:

  • значения строго фиксированы
  • алгоритм подбора отключён
  • визуальная длина штрихов задана явно

Влияние типа шкалы на поведение делений

Линейная шкала

d3.scaleLinear()
  • равномерное распределение
  • наиболее предсказуемые ticks
  • хорошо работает с .ticks()

Временная шкала

d3.scaleTime()
  • автоматическая адаптация к единицам времени
  • дни, недели, месяцы
  • ticks могут меняться динамически

Логарифмическая шкала

d3.scaleLog()
  • деления распределены неравномерно
  • ticks часто соответствуют степеням 10
  • .tickValues() особенно полезен

Практика визуального контроля делений

Настройка ticks напрямую влияет на читаемость графика:

  • слишком много делений приводит к перегрузке
  • слишком мало — к потере точности
  • неравномерные интервалы могут ухудшать восприятие

D3 решает часть этих задач автоматически, но методы .ticks(), .tickValues() и .tickSize() позволяют фиксировать поведение в сложных случаях, где автоматическая логика недостаточна.


Сопутствующие методы форматирования

Хотя они не управляют делениями напрямую, они тесно связаны с их отображением:

axis.tickFormat(d3.format(".2f"))
  • форматирует подписи ticks
  • влияет на читаемость значений
  • часто используется вместе с ограничением количества делений через .ticks()

Поведение при изменении размера графика

При ресайзе контейнера:

  • автоматически пересчитывается набор ticks (если не задан tickValues)
  • меняется плотность делений
  • адаптируется визуальная структура оси

При фиксированном наборе tickValues перерасчёт не влияет на значения, только на их отображение.


Влияние плотности данных на ticks

При визуализации больших диапазонов:

  • D3 уменьшает количество делений
  • увеличивает шаг между ticks
  • округляет значения к «читаемым» интервалам

При малых диапазонах:

  • увеличивается детализация
  • появляются промежуточные значения
  • усиливается роль .tickSize() в разделении пространства

Итоговая структура взаимодействия методов

  • .ticks() — управляет количеством и «разумной» генерацией значений
  • .tickValues() — полностью фиксирует набор делений
  • .tickSize() — определяет визуальную длину штрихов
  • .tickSizeInner() и .tickSizeOuter() — уточняют геометрию оси

Совместное использование этих методов формирует основу точной настройки осей в D3.js, позволяя управлять как математической структурой шкалы, так и её визуальным представлением.