В столбчатых диаграммах Nivo метки (labels) являются производным
элементом, который рассчитывается на основе геометрии каждого бара. Их
основная задача — передавать значение серии без необходимости считывания
шкалы. В компоненте ResponsiveBar управление отображением
меток строится через набор параметров, влияющих на видимость,
расположение и условия рендера.
По умолчанию метки размещаются внутри геометрии столбца и центрируются относительно его прямоугольной области. Такое поведение обеспечивает читаемость при достаточной высоте или ширине элемента, но требует настройки при плотной визуализации.
Ключевые аспекты позиционирования:
Контроль смещения возможен через кастомный компонент метки, где
координаты x, y, а также размеры
width и height передаются как аргументы
функции рендера.
Пример кастомного позиционирования:
const CustomLabel = ({ x, y, width, height, value }) => (
<text
x={x + width / 2}
y={y + height / 2}
textAnchor="middle"
dominantBaseline="central"
>
{value}
</text>
)
Такой подход позволяет полностью переопределить алгоритм размещения и использовать собственные правила центрирования, выравнивания или смещения.
Визуально перегруженные диаграммы требуют механизма автоматического скрытия меток. В Nivo он реализован через параметры порогов:
labelSkipWidthlabelSkipHeightЭти параметры определяют минимальные размеры столбца, при которых метка отображается. Если бар меньше заданного значения, текст не рендерится.
Типичный сценарий:
labelSkipWidth={24}
labelSkipHeight={12}
Такая конфигурация предотвращает наложение текста на узких столбцах и улучшает общую читаемость.
Дополнительно учитывается радиус и геометрия элемента. При сложных наборах данных (например, большое количество категорий) пропуск меток становится основным инструментом оптимизации визуального шума.
Форматирование значений осуществляется через несколько механизмов, каждый из которых отвечает за определённый уровень преобразования данных.
labelПараметр label определяет, какое значение отображается в
метке. По умолчанию используется числовое значение серии, но его можно
заменить вычисляемым выражением:
label={d => `${d.value} шт.`}
Функция получает объект данных, содержащий:
id серииvalueindexdataЭто позволяет строить составные подписи, включающие контекст категории или процентное соотношение.
valueFormatАльтернативный способ — использование форматтера:
valueFormat={value => `${value.toFixed(1)}%`}
Этот подход отделяет логику отображения от структуры данных и удобен для унифицированного форматирования чисел.
Часто применяется при:
Контраст текста относительно фона столбца управляется через
labelTextColor. Это может быть как фиксированное значение,
так и функция.
Функциональный вариант:
labelTextColor={d => (d.value > 50 ? '#ffffff' : '#000000')}
Более универсальный подход — использование контраста относительно заливки:
labelTextColor={{ from: 'color', modifiers: [['darker', 2]] }}
Такая конфигурация автоматически адаптирует цвет текста под текущую палитру, обеспечивая читаемость без ручной настройки для каждой серии.
Полный контроль над отображением достигается через
labelComponent. В этом случае Nivo перестаёт рендерить
стандартный текст и передаёт управление пользовательскому
компоненту.
const Label = ({ x, y, width, height, value, data }) => (
<g transform={`translate(${x}, ${y})`}>
<rect width={width} height={height} fill="transparent" />
<text
x={width / 2}
y={height / 2}
textAnchor="middle"
dominantBaseline="central"
>
{value}
</text>
</g>
)
Такой подход применяется при необходимости:
Ориентация графика напрямую влияет на поведение меток.
labelSkipHeight.labelSkipWidth;layout="horizontal"
В горизонтальном режиме особое значение приобретает выравнивание текста по оси X, особенно при длинных числовых значениях.
При большом количестве категорий возникает проблема наложения меток. Стандартные механизмы Nivo решают её комбинацией:
Дополнительно используется стратегия условного отображения:
label={d => (d.value < 10 ? '' : d.value)}
Такая логика снижает визуальный шум без изменения структуры данных.
В некоторых сценариях требуется отображение не только значения, но и дополнительного контекста (категория, процент, группа). Это реализуется через составные строки:
label={d => `${d.indexValue}: ${d.value}`}
или через вычисления:
label={d => `${Math.round(d.value / d.total * 100)}%`}
При этом важно учитывать ограничение пространства, особенно в вертикальных диаграммах, где длина текста напрямую влияет на перекрытие.
Nivo поддерживает централизованное оформление через
theme, включая параметры текста:
theme={{
labels: {
text: {
fontSize: 12,
fontWeight: 500
}
}
}}
Такой подход позволяет синхронизировать метки с общей визуальной системой интерфейса без дублирования настроек в каждом графике.