Интерактивность в компонентах Nivo реализуется через событийную
модель, встроенную в слои отрисовки (bars, arcs, points, slices).
Основные точки взаимодействия: onMouseEnter,
onMouseLeave, onClick. Эти обработчики
позволяют управлять состоянием визуальных элементов, формировать
подсветку, реализовывать выбор элементов и запускать внешние действия на
основе данных графика.
Каждое событие получает структурированный объект данных элемента, содержащий идентификаторы, числовые значения, метаданные серии и координатную информацию (в зависимости от типа графика).
Событие onMouseEnter срабатывает при попадании курсора
на графический элемент: столбец, точку линии, сектор диаграммы.
Типовой сценарий — изменение визуального состояния элемента и отображение дополнительной информации.
id, value, data,
colorimport { ResponsiveBar } from '@nivo/bar';
const MyBar = ({ data }) => (
<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onMouseEn ter={(datum, event) => {
console.log('hover enter:', datum.id, datum.value);
}}
/>
);
При активации onMouseEnter внутренний state компонента
может переключать элемент в режим hover, влияя на:
onMouseLeave фиксирует момент выхода курсора за пределы
элемента. Используется для сброса визуального состояния или скрытия
вспомогательных слоёв.
<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onMouseEn ter={(datum) => {
console.log('enter', datum.id);
}}
onMouseLe ave={(datum) => {
console.log('leave', datum.id);
}}
/>
После onMouseLeave элемент возвращается к состоянию:
onClick является ключевым событием для построения
интерактивных аналитических интерфейсов. Используется для:
Во всех типах графиков callback получает:
datum — данные элементаevent — DOM-событие<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onCl ick={(datum, event) => {
console.log('clicked bar:', {
id: datum.id,
value: datum.value,
indexValue: datum.indexValue
});
}}
/>
При клике:
В секторных диаграммах событие работает на уровне arc-сегмента.
import { ResponsivePie } from '@nivo/pie';
const Pie = ({ data }) => (
<ResponsivePie
data={data}
onCl ick={(arc, event) => {
console.log('arc id:', arc.id);
console.log('value:', arc.value);
}}
/>
);
arc вместо generic datumid, value,
percent, colorЛинейные графики используют point-level интерактивность.
import { ResponsiveLine } from '@nivo/line';
<ResponsiveLine
data={data}
onMouseEn ter={(point) => {
console.log('hover point:', point.data.x, point.data.y);
}}
onMouseLe ave={(point) => {
console.log('leave point');
}}
/>
{
"id": "seriesA",
"value": 42,
"indexValue": "January",
"color": "#ff0000",
"data": { "label": "January", "value": 42 }
}
{
"id": "Category A",
"value": 120,
"percentage": 35.2,
"color": "#3366cc"
}
{
"data": {
"x": "Jan",
"y": 10
},
"serieId": "temperature",
"color": "#00a3ff"
}
Интерактивные события в Nivo часто используются совместно с внешним состоянием React.
const [active, setActive] = useState(null);
<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onMouseEn ter={(d) => setActive(d.id)}
onMouseLe ave={() => setActive(null)}
onCl ick={(d) => setActive(d.id)}
/>
fillOpacityСложные сценарии интерактивности строятся на комбинации трёх событий:
onMouseEnter — вход в фокусonMouseLeave — выход из фокусаonClick — фиксация выбораconst [selected, setSelected] = useState(null);
const [hovered, setHovered] = useState(null);
<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onMouseEn ter={(d) => setHovered(d.id)}
onMouseLe ave={() => setHovered(null)}
onCl ick={(d) => setSelected(d.id)}
opacity={d =>
selected && selected !== d.id ? 0.3 : 1
}
/>
Tooltip в Nivo синхронизируется с событиями:
onMouseEnter → открытие tooltiponMouseLeave → скрытие tooltip (если не закреплён)onClick → фиксация tooltip (pin state)При кастомной реализации tooltip часто используется внешний state:
tooltip={({ datum }) => (
<div>
{datum.id}: {datum.value}
</div>
)}
| Тип графика | onMouseEnter | onMouseLeave | onClick |
|---|---|---|---|
| Bar | datum bar | datum bar | datum bar |
| Pie | arc | arc | arc |
| Line | point | point | point |
Интерактивность в Nivo часто дополняется кастомными слоями
(layers), где события используются для:
layers={[
'grid',
'axes',
'bars',
(props) => {
return hovered ? (
<line
x1={props.xScale(hovered)}
x2={props.xScale(hovered)}
y1={0}
y2={props.height}
/>
) : null;
}
]}