Форматы данных в @nivo/heatmap определяют, каким образом
визуализация интерпретирует структуру матрицы значений и как
сопоставляет категории по осям X и Y. HeatMap в Nivo построен вокруг
идеи двумерного распределения числовых значений, где каждая ячейка
представляет комбинацию двух категориальных признаков и одного числового
показателя.
Основной формат данных в @nivo/heatmap представляет
собой массив объектов, где каждый объект соответствует строке (или
группе по оси Y), а внутри содержится массив значений по оси X.
const data = [
{
id: 'JavaScript',
data: [
{ x: 'React', y: 120 },
{ x: 'Vue', y: 80 },
{ x: 'Angular', y: 60 }
]
},
{
id: 'Python',
data: [
{ x: 'Django', y: 90 },
{ x: 'Flask', y: 70 },
{ x: 'FastAPI', y: 110 }
]
}
];
Смысл структуры:
id — категория по вертикальной оси (Y-axis)data[] — набор точек внутри строкиx — категория по горизонтальной оси (X-axis)y — числовое значение, отображаемое через цветовую
шкалуТакая модель называется nested row-based format и является основным способом передачи данных в HeatMap Nivo.
HeatMap не использует классические координаты графиков. Вместо этого применяется категориальная матрица:
y, а не координатойВажно понимать: в Nivo HeatMap y — это не позиция, а
величина.
Часто исходные данные приходят в «плоском» формате:
const raw = [
{ language: 'JavaScript', framework: 'React', value: 120 },
{ language: 'JavaScript', framework: 'Vue', value: 80 },
{ language: 'Python', framework: 'Django', value: 90 }
];
Для HeatMap такой формат необходимо преобразовать в структуру
id + data[]:
function transform(raw) {
const grouped = {};
raw.forEach(item => {
if (!grouped[item.language]) {
grouped[item.language] = { id: item.language, data: [] };
}
grouped[item.language].data.push({
x: item.framework,
y: item.value
});
});
return Object.values(grouped);
}
Результат соответствует ожидаемому формату HeatMap.
Хотя Nivo напрямую не требует матрицу, данные часто концептуально представляются как двумерная таблица:
| React | Vue | Angular | |
|---|---|---|---|
| JS | 120 | 80 | 60 |
| Python | 90 | 70 | 110 |
Такое представление удобно для генерации структуры:
const matrix = [
['JavaScript', 120, 80, 60],
['Python', 90, 70, 110]
];
Преобразование в формат Nivo:
const headers = ['React', 'Vue', 'Angular'];
const data = matrix.map(row => ({
id: row[0],
data: row.slice(1).map((value, index) => ({
x: headers[index],
y: value
}))
}));
В некоторых архитектурах данных HeatMap строится через набор троек:
const flatData = [
{ x: 'React', y: 'JavaScript', value: 120 },
{ x: 'Vue', y: 'JavaScript', value: 80 },
{ x: 'React', y: 'Python', value: 90 }
];
Такой формат требует агрегации перед передачей в компонент Nivo:
const grouped = flatData.reduce((acc, curr) => {
if (!acc[curr.y]) {
acc[curr.y] = { id: curr.y, data: [] };
}
acc[curr.y].data.push({
x: curr.x,
y: curr.value
});
return acc;
}, {});
const nivoData = Object.values(grouped);
Категории x должны быть:
idПри несогласованности ключей HeatMap может:
Для корректной визуализации часто требуется приведение данных к полной сетке:
const xKeys = ['React', 'Vue', 'Angular'];
const yKeys = ['JavaScript', 'Python'];
const normalized = yKeys.map(y => ({
id: y,
data: xKeys.map(x => ({
x,
y: findValue(y, x) || 0
}))
}));
Это гарантирует отсутствие «пустых» значений в визуализации.
HeatMap поддерживает:
x как string (категории)y как number (значения)id как string (группы)Пример смешанного набора:
{
id: '2024',
data: [
{ x: 'Q1', y: 100 },
{ x: 'Q2', y: 140 },
{ x: 'Q3', y: 90 }
]
}
Если часть комбинаций отсутствует:
{ x: 'React', y: undefined }
HeatMap интерпретирует это как отсутствие данных. Для контроля визуализации предпочтительно:
0null при использовании специальных режимов
отображения пустотФормат данных напрямую влияет на:
Чем более регулярна структура id → x → y, тем стабильнее
визуальный результат.
При расширении модели данных иногда используется дополнительная группировка:
[
{
id: 'Frontend',
data: [
{ x: 'React', y: 120 },
{ x: 'Vue', y: 80 }
]
},
{
id: 'Backend',
data: [
{ x: 'Django', y: 90 },
{ x: 'Express', y: 110 }
]
}
]
Здесь id становится уровнем группировки домена, а
x — подкатегорией.
При работе с API данные часто приходят постепенно:
const apiData = await fetch('/stats');
const nivoData = transform(apiData);
setData(nivoData);
Критично сохранять:
xidyНаиболее распространённые проблемы:
x (числа + строки)x внутри одного idy как строки вместо чиселКорректный формат всегда строго типизирован по смыслу:
{ x: 'Category', y: 42 }
Nested format (основной):
Flat format:
Matrix format:
Концептуально HeatMap в Nivo опирается на трёхуровневую структуру:
id)x)y)Именно эта модель обеспечивает универсальность визуализации для любых доменных данных — от аналитики продаж до тепловых карт активности пользователей.