Оси X и Y: типы шкал, форматирование меток

Оси X и Y в визуализациях Nivo определяют структуру координатной системы, в которой отображаются данные. В зависимости от типа графика (линейный, столбчатый, area, scatter и др.) оси могут быть дискретными, линейными, временными или категориальными. Корректная настройка шкал и форматирование меток напрямую влияет на читаемость и интерпретируемость графика, особенно при работе с большими наборами данных или нестандартными форматами значений.

В основе осей лежит концепция шкал, которые преобразуют исходные данные в координаты пикселей.

Линейная шкала (linear)

Используется для числовых значений с равномерным распределением.

scale: {
    type: 'linear',
    min: 0,
    max: 'auto'
}

Линейная шкала применяется по умолчанию в большинстве графиков, где значения имеют количественную природу: доходы, температура, количество пользователей.

Особенности:

  • равномерное расстояние между делениями
  • поддержка отрицательных значений
  • автоматическое вычисление диапазона при max: 'auto'

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

Применяется для данных с экспоненциальным ростом.

scale: {
    type: 'log',
    base: 10
}

Логарифмическая шкала полезна при визуализации:

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

Особенность: нулевые и отрицательные значения не поддерживаются.

Временная шкала (time)

Используется для оси X при работе с датами.

xScale: {
    type: 'time',
    format: '%Y-%m-%d',
    precision: 'day'
}

Ключевые параметры:

  • format — формат входной даты (d3-time-format синтаксис)
  • precision — шаг агрегации (day, month, hour и т.д.)
  • автоматическая интерполяция промежутков времени

Типичный пример данных:

data: [
  { x: '2026-01-01', y: 12 },
  { x: '2026-01-02', y: 18 }
]

Категориальная шкала (point / band)

Используется для дискретных значений.

xScale: {
    type: 'point'
}

или

xScale: {
    type: 'band',
    padding: 0.2
}

Различия:

  • point — фиксированные точки без ширины (часто line chart)
  • band — с шириной (bar chart)

Ось X в Nivo

Ось X задаётся через свойство axisBottom (или axisTop в зависимости от расположения).

axisBottom={{
    legend: 'Дата',
    legendPosition: 'middle',
    legendOffset: 40
}}

Основные параметры оси X

tickSize

Определяет длину засечек.

tickSize={5}

tickPadding

Отступ текста метки от оси.

tickPadding={8}

tickRotation

Поворот меток.

tickRotation={-45}

Поворот особенно полезен при длинных категориях или датах.

format

Форматирование значений оси.

axisBottom={{
    format: v => `${v} ₽`
}}

или с использованием d3-format:

axisBottom={{
    format: '.2s'
}}

Ось Y в Nivo

Ось Y задаётся через axisLeft или axisRight.

axisLeft={{
    legend: 'Продажи',
    legendPosition: 'middle',
    legendOffset: -50
}}

Особенности оси Y

Ось Y чаще всего:

  • числовая (linear scale)
  • отображает зависимую переменную
  • требует аккуратного форматирования больших чисел

Инверсия и диапазон

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

yScale={{
    type: 'linear',
    min: 0,
    max: 1000
}}

Форматирование меток (ticks formatting)

Форматирование меток — ключевой аспект читаемости графиков.

Числовые форматы

Используется d3-format.

axisLeft={{
    format: value => value.toFixed(2)
}}

или компактная запись:

axisLeft={{
    format: '.1f'
}}

Примеры:

  • .0f — целые числа
  • .2f — два знака после запятой
  • .2s — сокращённый формат (1k, 1M)

Форматирование валюты

axisLeft={{
    format: value => `$${value}`
}}

или через Intl API:

axisLeft={{
    format: value =>
        new Intl.NumberFormat('en-US', {
            style: 'currency',
            currency: 'USD'
        }).format(value)
}}

Форматирование дат

Для временных шкал:

axisBottom={{
    format: '%d.%m.%Y'
}}

или через кастомную функцию:

import { format } from 'date-fns'

axisBottom={{
    format: v => format(new Date(v), 'dd.MM')
}}

Синхронизация шкалы и данных

Некорректное соответствие типа шкалы и данных приводит к искажениям графика.

Типичные ошибки:

  • использование linear для строковых значений
  • передача дат без преобразования в time
  • отсутствие сортировки данных по X в временных рядах

Пример корректной структуры:

const data = [
  { x: new Date('2026-01-01'), y: 10 },
  { x: new Date('2026-01-02'), y: 15 }
]

Настройка плотности меток

При большом количестве данных Nivo автоматически скрывает часть ticks, но поведение можно контролировать.

axisBottom={{
    tickValues: 5
}}

или явно:

axisBottom={{
    tickValues: [
        '2026-01-01',
        '2026-01-10',
        '2026-01-20'
    ]
}}

Кастомный рендер меток

Для полного контроля используется renderTick.

axisBottom={{
    renderTick: tick => {
        return (
            <g transform={`translate(${tick.x},${tick.y})`}>
                <text
                    textAnchor="middle"
                    dy="0.71em"
                >
                    {tick.value}
                </text>
            </g>
        )
    }
}}

Это позволяет:

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

Работа с переполнением меток

При длинных значениях применяются стратегии:

Обрезка текста

axisBottom={{
    format: v =>
        v.length > 10 ? v.slice(0, 10) + '…' : v
}}

Многострочные метки

axisBottom={{
    renderTick: tick => {
        const parts = tick.value.split(' ')
        return (
            <g transform={`translate(${tick.x},${tick.y})`}>
                <text>
                    {parts.map((p, i) => (
                        <tspan x={0} dy={i === 0 ? 0 : 12}>
                            {p}
                        </tspan>
                    ))}
                </text>
            </g>
        )
    }
}}

Стилизация осей

Оси в Nivo стилизуются через свойства:

axisLeft={{
    tickSize: 0,
    tickPadding: 12,
    tickRotation: 0,
    legend: 'Значения',
    legendOffset: -40,
    legendPosition: 'middle'
}}

Часто используется минималистичный стиль:

  • отключение засечек (tickSize: 0)
  • уменьшение визуального шума
  • акцент на данные, а не на сетку

Координация осей X и Y

Для сложных графиков важно согласование:

  • одинаковая логика округления
  • синхронные диапазоны (при сравнении графиков)
  • единый формат чисел

Пример:

xScale={{ type: 'point' }}
yScale={{ type: 'linear', min: 0, max: 'auto' }}

При сравнении нескольких серий данных используется одинаковая шкала Y для избежания визуального искажения.

Поведение при переполнении диапазона

Если значения выходят за пределы шкалы:

  • Nivo автоматически расширяет диапазон при auto
  • при фиксированном диапазоне данные обрезаются визуально
  • возможны “обрывы” линии на графике

Ручной контроль:

yScale={{
    type: 'linear',
    min: 'auto',
    max: 'auto'
}}

Использование нескольких осей Y

В некоторых композициях применяется двойная ось:

  • левая — основная метрика
  • правая — вспомогательная
axisLeft={{ legend: 'Пользователи' }}
axisRight={{ legend: 'Конверсия' }}

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

Практика выбора шкалы

  • количественные данные → linear
  • рост/масштабирование → log
  • даты → time
  • категории → point/band

Корректный выбор шкалы определяет не только внешний вид графика, но и корректность восприятия трендов, особенно при анализе временных рядов и распределений.