Библиотека Nivo построена поверх React и использует декларативный подход к визуализации данных, где интерактивность является частью конфигурации графика, а не отдельным слоем логики. Основная идея заключается в том, что визуальные компоненты реагируют на события пользовательского ввода через свойства (props), сохраняя при этом управление состоянием на стороне приложения.
Интерактивность в Nivo включает несколько ключевых механизмов:
Каждый из этих механизмов работает поверх единой модели данных, где визуальные элементы графика соответствуют конкретным сущностям в наборе данных.
Большинство компонентов Nivo поддерживают стандартные события:
onClickonMouseEnteronMouseLeaveonMouseMoveЭти события привязываются к элементам графика (точкам, сегментам, столбцам и т.д.), позволяя реагировать на взаимодействие пользователя.
Пример работы с кликом по элементу диаграммы:
<ResponsiveBar
data={data}
keys={['value']}
indexBy="label"
onCl ick={(datum, event) => {
console.log('Выбран элемент:', datum);
}}
/>
События передают не только координаты, но и объект данных, связанный с визуальным элементом. Это позволяет строить поверх графиков сложную бизнес-логику: фильтрацию, детализацию, переходы между уровнями данных.
Hover является ключевым элементом интерактивности. В Nivo он используется для подсветки элементов, изменения прозрачности и акцентирования выбранных данных.
Во многих компонентах присутствуют свойства:
isInteractiveactiveOpacityinactiveOpacityenableGridX / enableGridY (косвенная визуальная помощь
при наведении)Пример управления прозрачностью:
<ResponsiveLine
data={data}
enablePoints={true}
pointSize={8}
pointBorderWidth={2}
useMesh={true}
inactiveOpacity={0.2}
/>
Использование useMesh особенно важно: оно создаёт
невидимую сетку Вороного, которая расширяет зону реагирования точек,
улучшая UX на плотных графиках.
Tooltip в Nivo не является статическим компонентом — это функция, возвращающая React-элемент, основанный на текущем элементе данных.
Стандартная конфигурация:
<ResponsiveBar
data={data}
tooltip={({ id, value, color }) => (
<div style={{ padding: 12, background: '#222', color: '#fff' }}>
<strong>{id}</strong>: {value}
</div>
)}
/>
Tooltips могут:
При этом tooltip вызывается только при необходимости, что снижает нагрузку на рендеринг.
Клик по элементам графика часто используется как триггер изменения состояния приложения. В отличие от hover, click предполагает фиксацию выбора.
Типичный паттерн:
const [selected, setSelected] = useState(null);
<ResponsivePie
data={data}
onCl ick={(datum) => setSelected(datum.id)}
activeOuterRadiusOffset={8}
/>
Активные элементы могут визуально выделяться через:
Такой подход позволяет строить интерактивные аналитические панели, где график становится интерфейсом навигации по данным.
Легенды в Nivo не ограничиваются отображением подписей. Они могут быть интерактивными элементами управления.
Поддерживаются события:
onClickonMouseEnteronMouseLeaveПример интерактивной легенды:
<ResponsiveLine
data={data}
legends={[
{
anchor: 'bottom-right',
direction: 'column',
onClick: (datum) => {
console.log('Переключение серии:', datum.id);
}
}
]}
/>
Через легенды реализуются сценарии:
Интерактивные графики часто используются как интерфейс фильтрации. В этом случае Nivo выступает не просто визуализацией, а управляющим компонентом.
Пример логики:
const [hidden, setHidden] = useState([]);
const toggleSeries = (id) => {
setHidden((prev) =>
prev.includes(id)
? prev.filter(x => x !== id)
: [...prev, id]
);
};
<ResponsiveBar
data={data.filter(d => !hidden.includes(d.id))}
onCl ick={(datum) => toggleSeries(datum.id)}
/>
Такой подход позволяет:
Сам Nivo не предоставляет полноценного drag-and-drop API для
элементов графика, однако архитектура React-компонентов позволяет
интегрировать внешние библиотеки перетаскивания, такие как
react-dnd или dnd-kit.
На практике перетаскивание применяется в нескольких сценариях:
Пример интеграции с состоянием порядка:
const [order, setOrder] = useState(['A', 'B', 'C']);
const sortedData = order.map(id =>
data.find(d => d.id === id)
);
<ResponsiveBar
data={sortedData}
/>
Перетаскивание реализуется вне графика, а Nivo получает уже обновлённый массив данных, что соответствует принципу “data-driven rendering”.
Наиболее распространённый подход — использование drag-and-drop для легенды, где пользователь изменяет порядок серий, влияющий на визуализацию.
Схема взаимодействия:
Такой подход особенно эффективен в сложных аналитических панелях с большим числом метрик.
При плотных данных стандартные зоны наведения становятся недостаточными. Nivo использует технологию Voronoi mesh, которая расширяет область взаимодействия.
<ResponsiveLine
data={data}
useMesh={true}
/>
Это особенно важно при сочетании с:
Mesh снижает количество “промахов” при наведении и делает интерфейс предсказуемым.
В сложных приложениях несколько графиков могут реагировать на одни и те же события.
Пример синхронизации:
const [activePoint, setActivePoint] = useState(null);
<ResponsiveLine
data={data}
onMouseM ove={(point) => setActivePoint(point)}
/>
<ResponsiveBar
data={data}
highlight={activePoint?.id}
/>
Так формируется связанная интерактивная система, где один график влияет на другой.
Интерактивность увеличивает количество перерендеров, поэтому важно учитывать оптимизацию:
useMemo для данных;animate: false.Особенно критично это при работе с:
Любая форма взаимодействия в Nivo в конечном итоге сводится к управлению состоянием React. График не хранит бизнес-логику, а только отражает текущее состояние данных и UI-параметров.
Типовая модель:
Такая схема обеспечивает предсказуемость и масштабируемость интерактивных визуализаций даже при высокой сложности интерфейса.