Компонент ScatterPlot в библиотеке Nivo предназначен для отображения точечных диаграмм, где каждая точка представляет собой объект с координатами в двумерном пространстве. Базовая конфигурация начинается с правильного определения структуры входных данных, так как именно она определяет корректность дальнейшего рендеринга.
Основной формат данных представляет собой массив серий:
const data = [
{
id: 'series A',
data: [
{ x: 1, y: 2 },
{ x: 2, y: 3 },
{ x: 3, y: 5 }
]
},
{
id: 'series B',
data: [
{ x: 1, y: 5 },
{ x: 2, y: 1 },
{ x: 3, y: 4 }
]
}
]
Каждый объект верхнего уровня описывает отдельную серию, а вложенный
массив data содержит координаты точек. Значения
x и y могут быть числовыми, временными или
категориальными в зависимости от конфигурации шкал.
Использование ScatterPlot начинается с импорта компонента:
import { ResponsiveScatterPlot } from '@nivo/scatterplot'
Чаще всего применяется именно ResponsiveScatterPlot, так
как он автоматически адаптируется под размеры контейнера и избавляет от
необходимости вручную управлять шириной и высотой.
Минимальная рабочая конфигурация включает данные, размеры и базовые параметры отображения:
<ResponsiveScatterPlot
data={data}
margin={{ top: 40, right: 40, bottom: 60, left: 60 }}
xScale={{ type: 'linear', min: 0, max: 'auto' }}
yScale={{ type: 'linear', min: 0, max: 'auto' }}
axisBottom={{
legend: 'ось X',
legendPosition: 'middle',
legendOffset: 46
}}
axisLeft={{
legend: 'ось Y',
legendPosition: 'middle',
legendOffset: -50
}}
/>
Ключевые параметры:
Шкалы определяют, как числовые или категориальные значения преобразуются в координаты пикселей.
Наиболее распространённый вариант:
xScale={{ type: 'linear', min: 0, max: 'auto' }}
yScale={{ type: 'linear', min: 0, max: 'auto' }}
Значение auto позволяет библиотеке автоматически
вычислять максимальные границы на основе данных.
Используется при работе с большими диапазонами значений:
xScale={{ type: 'log', base: 10, min: 1, max: 10000 }}
Логарифмическая шкала требует, чтобы значения были строго положительными.
При работе с датами:
xScale={{
type: 'time',
format: 'native',
precision: 'day'
}}
В этом случае значения x должны быть объектами
Date.
Оси в ScatterPlot играют ключевую роль в интерпретации данных.
axisBottom={{
legend: 'Время',
legendPosition: 'middle',
legendOffset: 50,
tickSize: 5,
tickPadding: 5,
tickRotation: 0
}}
axisLeft={{
legend: 'Значение',
legendPosition: 'middle',
legendOffset: -50
}}
Дополнительные параметры позволяют управлять внешним видом делений, их поворотом и отступами.
Каждая точка на графике может быть стилизована через параметры компонента:
nodeSize={12}
colors={{ scheme: 'nivo' }}
blendMode="multiply"
Расширенная настройка цвета:
colors={d => d.seriesId === 'series A' ? '#ff4d4d' : '#4d79ff'}
Tooltip позволяет отображать дополнительную информацию при наведении:
tooltip={({ node }) => (
<div style={{ padding: 12, background: '#fff' }}>
<strong>{node.serieId}</strong><br />
x: {node.data.x}<br />
y: {node.data.y}
</div>
)}
Поведение tooltip полностью настраиваемо, включая форматирование и стили.
Параметр useMesh улучшает область захвата событий
мыши:
useMesh={true}
При активированном режиме создаётся виртуальная сетка, которая упрощает взаимодействие с точками, особенно при плотных данных.
Правильные отступы критичны для читаемости графика:
margin={{
top: 50,
right: 50,
bottom: 80,
left: 80
}}
Недостаточные отступы приводят к обрезанию подписей осей и легенд.
Легенды позволяют различать серии данных:
legends={[
{
anchor: 'bottom-right',
direction: 'column',
translateX: 130,
itemWidth: 100,
itemHeight: 12,
itemsSpacing: 5,
symbolSize: 12
}
]}
Легенды становятся особенно важными при большом количестве серий.
Компонент поддерживает встроенные анимации:
animate={true}
motionConfig="gentle"
Тип motionConfig влияет на плавность переходов между состояниями данных.
Тематизация позволяет унифицировать внешний вид графиков:
theme={{
axis: {
ticks: {
text: {
fontSize: 12,
fill: '#333'
}
}
},
grid: {
line: {
stroke: '#eee'
}
}
}}
Через theme можно контролировать сетку, подписи, легенды и tooltip.
Неправильное определение структуры данных:
// ошибка: отсутствует вложенный data
const data = [
{ id: 'A', x: 1, y: 2 }
]
Несоответствие типов шкал:
xScale={{ type: 'linear' }}
// при этом x = new Date() -> приведёт к некорректному отображению
Отсутствие margin:
margin={{ top: 0, right: 0, bottom: 0, left: 0 }}
Это приводит к визуальному наложению элементов графика на границы контейнера.
<ResponsiveScatterPlot
data={data}
margin={{ top: 40, right: 40, bottom: 60, left: 60 }}
xScale={{ type: 'linear', min: 0, max: 'auto' }}
yScale={{ type: 'linear', min: 0, max: 'auto' }}
nodeSize={10}
useMesh={true}
axisBottom={{ legend: 'X' }}
axisLeft={{ legend: 'Y' }}
colors={{ scheme: 'nivo' }}
animate={true}
/>