В основе любой визуализации в Nivo лежит преобразование исходных данных в координаты пикселей. Это преобразование выполняется через шкалы (scales), которые определяют, как числовые, категориальные или временные значения отображаются на осях графика.
Nivo использует подход, основанный на D3-scale, где каждая ось графика опирается на строго определённый тип шкалы: линейную, логарифмическую, временную или категориальную. Управление этими шкалами позволяет тонко настраивать поведение диаграмм и адаптировать визуализацию под структуру данных.
Линейная шкала используется для непрерывных числовых значений. Она применяется в большинстве стандартных графиков.
{
xScale: {
type: 'linear',
min: 'auto',
max: 'auto'
}
}
Линейная шкала предполагает равномерное распределение значений по оси. Она подходит для метрик, где важны абсолютные различия.
Логарифмическая шкала используется для данных с экспоненциальным ростом.
{
yScale: {
type: 'log',
base: 10,
min: 1,
max: 'auto'
}
}
Такая шкала особенно полезна при визуализации финансовых данных, метрик роста и любых значений с большим диапазоном разброса.
Временные шкалы применяются для осей, основанных на датах.
{
xScale: {
type: 'time',
format: '%Y-%m-%d',
precision: 'day'
}
}
Данные интерпретируются как временные метки, что позволяет корректно отображать интервалы между датами.
Категориальные шкалы используются для дискретных значений.
{
xScale: {
type: 'band',
padding: 0.2
}
}
Такая шкала часто применяется в bar chart и grouped bar chart, где каждая категория занимает отдельную позицию на оси.
Шкала определяет размещение данных, но форматтеры управляют их отображением.
В Nivo форматирование осей задаётся через свойства
axisBottom, axisLeft и аналогичные.
axisBottom={{
format: value => `${value} ₽`
}}
Функция format позволяет преобразовать исходное значение
перед отображением. Это может быть добавление единиц измерения,
округление или кастомная логика отображения.
Для сложного форматирования применяется библиотека d3-format.
import { format } from 'd3-format';
const moneyFormat = format(',.2f');
axisLeft={{
format: value => `${moneyFormat(value)} $`
}}
Подобный подход обеспечивает единообразное отображение чисел: разделители тысяч, фиксированное количество знаков после запятой, экспоненциальная форма.
Tooltips часто требуют отдельного форматирования, независимого от осей.
tooltip={({ point }) => (
<div>
<strong>{point.data.x}</strong>: {point.data.y} units
</div>
)}
Форматтер позволяет преобразовать как X, так и Y значения, а также добавить дополнительный контекст.
В line chart можно управлять отображением значений на самих точках.
pointLabel={d => `${d.y} kWh`}
Такой формат позволяет визуально закрепить значение прямо на графике.
<ResponsiveLine
data={data}
xScale={{
type: 'time',
format: 'native',
precision: 'day'
}}
yScale={{
type: 'linear',
min: 0,
max: 'auto'
}}
axisBottom={{
format: value => new Date(value).toLocaleDateString()
}}
/>
Временная шкала на оси X обеспечивает корректное распределение точек по времени, а форматтер оси преобразует дату в читаемый вид.
<ResponsiveBar
data={data}
indexBy="country"
keys={['value']}
xScale={{
type: 'band',
padding: 0.3
}}
axisBottom={{
format: value => value.toUpperCase()
}}
/>
Категориальная шкала band определяет равномерное распределение столбцов, а форматтер управляет отображением категорий.
Nivo позволяет переопределять поведение шкал, используя кастомные D3-scale функции.
import { scaleLinear } from 'd3-scale';
const customScale = scaleLinear()
.domain([0, 100])
.range([0, 1]);
<ResponsiveLine
data={data}
xScale={customScale}
/>
Подобный подход используется при необходимости строгого контроля над диапазонами, особенно в научной и аналитической визуализации.
Для временных шкал часто используется date-fns или
стандартный Intl.DateTimeFormat.
axisBottom={{
format: value =>
new Intl.DateTimeFormat('ru-RU', {
day: '2-digit',
month: 'short'
}).format(new Date(value))
}}
Такой формат обеспечивает локализованное отображение дат без дополнительных зависимостей.
Шкалы в Nivo позволяют явно задавать значения тиков (ticks), что даёт полный контроль над разметкой осей.
axisLeft={{
tickValues: [0, 20, 40, 60, 80, 100]
}}
Для временных шкал можно задавать массив дат:
axisBottom={{
tickValues: [
'2024-01-01',
'2024-06-01',
'2024-12-01'
]
}}
Легенды также могут использовать форматтеры для отображения значений.
legends={[
{
anchor: 'bottom',
direction: 'row',
itemTextColor: '#999',
formatter: value => `${value} %`
}
]}
Это особенно полезно при работе с процентными распределениями и нормированными данными.
Форматтеры могут включать логику на основе диапазонов значений.
axisLeft={{
format: value => {
if (value > 1000) return `${value / 1000}k`;
if (value > 0) return value;
return '0';
}
}}
Подобная логика часто используется для сокращённого отображения больших чисел.
В комбинированных визуализациях (line + bar) важно синхронизировать шкалы и форматтеры, чтобы избежать несоответствий в восприятии данных.
xScale={{
type: 'point'
}}
axisBottom={{
format: value => `Q${value}`
}}
Шкала point фиксирует категории без интерполяции, а
форматтер задаёт бизнес-уровень представления данных.
Шкала определяет геометрию данных, форматтер — их смысловое отображение. Разделение этих уровней позволяет строить гибкие визуализации:
Такой подход делает визуализации устойчивыми к изменениям структуры данных и требованиям интерфейса.