Перекрестье (crosshair) в визуализациях Nivo представляет собой интерактивный элемент, который следует за курсором и визуально фиксирует текущую позицию на графике. Оно используется для повышения читаемости значений в точке наведения и синхронизации визуального контекста между осями.
В зависимости от типа графика (Line, Scatter, Area) перекрестье может работать в связке с сеткой, тултипами и слоями отрисовки, формируя единый механизм навигации по данным.
В Nivo перекрестье концептуально делится на несколько режимов отображения:
Вертикальное перекрестье (x-axis tracking) Отображает линию, фиксирующую положение по оси X. Используется в линейных графиках для анализа временных рядов.
Горизонтальное перекрестье (y-axis tracking) Фиксирует значение по оси Y. Реже используется самостоятельно, чаще — в комбинации с вертикальным режимом.
Полное перекрестье (full crosshair) Сочетает вертикальную и горизонтальную линии, образуя координатную привязку к точке данных.
Тип перекрестья определяется логикой взаимодействия компонента и настройками слоя (layers), а также режимами наведения (mesh/slices).
В ResponsiveLine перекрестье обычно активируется через
комбинацию интерактивных свойств.
import { ResponsiveLine } from '@nivo/line'
const data = [
{
id: 'series-1',
data: [
{ x: 1, y: 10 },
{ x: 2, y: 20 },
{ x: 3, y: 15 },
],
},
]
export default function Chart() {
return (
<ResponsiveLine
data={data}
margin={{ top: 20, right: 20, bottom: 50, left: 50 }}
xScale={{ type: 'linear' }}
yScale={{ type: 'linear', min: 0, max: 'auto' }}
useMesh={true}
enableSlices="x"
/>
)
}
Параметры useMesh и enableSlices косвенно
управляют тем, как формируется область наведения, которая и определяет
поведение перекрестья.
Механизм mesh создаёт невидимую триангуляционную сетку поверх графика. Она обеспечивает точное определение ближайшей точки, даже если реальные данные разрежены.
useMesh={true}
Mesh особенно полезен при:
Slices формируют вертикальные или горизонтальные срезы данных.
enableSlices="x"
Возможные значения:
"x" — вертикальный срез (основной режим для crosshair
по времени)"y" — горизонтальный срезfalse — отключеноСрезы обеспечивают синхронное выделение всех серий на одной координате, что напрямую связано с отображением перекрестья.
В Nivo перекрестье может быть переопределено через кастомные слои
(layers) или стилизовано через theme.
theme={{
crosshair: {
line: {
stroke: '#ff0000',
strokeWidth: 1,
strokeOpacity: 0.8,
strokeDasharray: '4 4',
},
},
}}
Основные параметры:
stroke — цвет линииstrokeWidth — толщинаstrokeOpacity — прозрачностьstrokeDasharray — пунктирный стильПерекрестье может быть полностью переопределено через кастомный слой.
const CustomCrosshair = ({ x, y }) => {
if (!x || !y) return null
return (
<g>
<line
x1={x}
x2={x}
y1={0}
y2="100%"
stroke="black"
strokeWidth={1}
/>
<line
x1={0}
x2="100%"
y1={y}
y2={y}
stroke="black"
strokeWidth={1}
/>
</g>
)
}
Подключение:
<ResponsiveLine
data={data}
layers={[
'grid',
'markers',
'axes',
'areas',
'lines',
CustomCrosshair,
'points',
'legends',
]}
/>
Такой подход полностью заменяет стандартную реализацию перекрестья.
Перекрестье тесно связано с системой tooltip. В Nivo tooltip получает координаты активной точки, которые затем используются для позиционирования линий.
tooltip={({ point }) => (
<div>
x: {point.data.x}
<br />
y: {point.data.y}
</div>
)}
При этом:
В ScatterPlot перекрестье работает через аналогичную механику, но вместо линий чаще используется точечная привязка.
<ResponsiveScatterPlot
data={data}
useMesh={true}
nodeSize={8}
tooltip={({ node }) => (
<div>
x: {node.data.x}
y: {node.data.y}
</div>
)}
/>
Здесь crosshair часто проявляется как связка:
Nivo позволяет отслеживать движение курсора и управлять логикой отображения:
onMouseM ove={(node, event) => {
// node содержит активную точку
}}
onMouseLe ave={() => {
// сброс состояния crosshair
}}
Такая модель используется для:
При включённых анимациях перекрестье может наследовать задержки обновления позиции. Это важно учитывать при высокой частоте обновлений данных.
motionConfig="stiff"
animate={true}
При использовании:
Основные факторы влияния:
1. useMesh
2. enableSlices
3. кастомные layers
Оптимизация обычно достигается через:
Синхронизация нескольких графиков
Перекрестье используется как внешний сигнал:
const [cursor, setCursor] = useState(null)
onMouseM ove={(node) => setCursor(node)}
Глобальный crosshair для dashboard
Общий state курсора передаётся в несколько компонентов, обеспечивая единое положение перекрестья.
Фокус на временных рядах
Наиболее эффективный режим:
enableSlices="x"
useMesh={false}
Он обеспечивает стабильное вертикальное перекрестье, соответствующее временной оси.
Комбинация сетки, slices и mesh формирует основу интерактивной навигации по данным в Nivo, где перекрестье выступает центральным визуальным индикатором текущей позиции анализа.