Точки на линии: размер, форма, цвет

Линейные графики в Nivo (@nivo/line) используют точки (points) как визуальные маркеры значений временных или категориальных рядов. Эти элементы являются не просто декоративными объектами, а ключевым механизмом интерпретации данных: они фиксируют дискретные измерения на непрерывной линии и позволяют точно считывать значения.


Размер точек

Размер точек в линейном графике определяется через параметр pointSize. Он задаёт радиус окружности (или базовый размер фигуры, если используется кастомная форма).

<ResponsiveLine
    data={data}
    margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
    pointSize={10}
/>

Изменение размера влияет не только на визуальную плотность графика, но и на его читаемость. При работе с большим количеством серий увеличение pointSize приводит к визуальному шуму, тогда как уменьшение делает график более «гладким», но снижает точность восприятия отдельных значений.

На практике используются несколько режимов:

  • Малые значения (4–6) — для плотных временных рядов
  • Средние (7–10) — универсальный вариант
  • Крупные (11–16) — для акцентирования редких точек

Дополнительно можно управлять толщиной обводки:

pointBorderWidth={2}

Это позволяет отделять точки от фона и линии даже при совпадении цветов.


Цвет точек

Цветовая настройка точек в Nivo может задаваться несколькими способами: через фиксированное значение, функцию или привязку к серии данных.

Фиксированный цвет

pointColor="#ff6600"

Все точки получают единый цвет, что уместно в односерийных графиках или в случаях, когда линии уже несут смысловую дифференциацию.

Цвет по серии

pointColor={{ from: 'serieColor' }}

Такой подход синхронизирует цвет точки с цветом линии, что создаёт визуальную целостность графика.

Функциональное управление цветом

pointColor={(point) => point.serieColor}

Функция позволяет вводить условную логику: изменение цвета в зависимости от значения, индекса или внешних условий.

Примеры использования:

  • выделение максимальных значений
  • маркировка аномалий
  • подсветка последних точек ряда

Обводка и контраст точек

Для повышения читаемости используется комбинация pointBorderWidth и pointBorderColor.

pointBorderWidth={2}
pointBorderColor="#ffffff"

Белая обводка часто применяется на тёмных или насыщенных графиках, где точки иначе теряются на фоне линий.

Контрастная обводка выполняет две функции:

  • визуальное отделение точки от линии
  • повышение различимости при наложении серий

Форма точек

Базовая форма точек в Nivo — окружность, но библиотека позволяет заменять её через pointSymbol.

pointSymbol={(props) => (
    <rect
        x={-6}
        y={-6}
        width={12}
        height={12}
        fill={props.color}
    />
)}

Возможные формы:

  • круг (по умолчанию)
  • квадрат
  • ромб
  • треугольник
  • пользовательские SVG-формы

Кастомизация формы используется для:

  • различения серий без изменения цвета
  • создания семантической кодировки (например, тип события)
  • визуального упрощения при дальнем просмотре

Поворот и геометрия кастомных точек

При использовании SVG-фигур важно учитывать систему координат Nivo: центр точки находится в (0,0), поэтому геометрия строится относительно центра.

Пример ромба:

pointSymbol={(props) => (
    <g>
        <path
            d="M0,-6 L6,0 L0,6 L-6,0 Z"
            fill={props.color}
        />
    </g>
)}

Такой подход позволяет точно контролировать визуальную форму без зависимости от стандартных примитивов.


Динамическая стилизация точек

Nivo допускает динамическое изменение параметров точек на основе данных.

Изменение размера по значению

pointSize={(point) => Math.sqrt(point.data.y)}

Такой приём создаёт эффект «веса» значений: чем выше показатель, тем крупнее точка.

Цвет по условию

pointColor={(point) =>
    point.data.y > 100 ? '#e74c3c' : '#2ecc71'
}

Это позволяет мгновенно выделять критические зоны данных.


Взаимодействие с hover-состояниями

Точки в Nivo поддерживают интерактивность: при наведении изменяются масштаб, цвет и прозрачность.

Основные параметры:

activeSize={14}
inactiveOpacity={0.3}
  • activeSize увеличивает точку при наведении
  • inactiveOpacity затемняет остальные элементы

Такой механизм используется для фокусировки внимания на одной серии или одном значении.


Слои и кастомные точки

Nivo строит графики через систему слоёв (layers). Точки являются частью слоя points, который можно переопределить.

layers={[
    'grid',
    'markers',
    'areas',
    'lines',
    'points',
    CustomPointsLayer,
    'legends'
]}

Кастомный слой точек позволяет полностью заменить стандартную отрисовку:

const CustomPointsLayer = ({ points }) => (
    <g>
        {points.map(point => (
            <circle
                key={point.id}
                cx={point.x}
                cy={point.y}
                r={8}
                fill={point.color}
                stroke="#000"
            />
        ))}
    </g>
)

Такой подход используется при необходимости:

  • добавления сложной анимации
  • интеграции нестандартных форм
  • оптимизации рендеринга при большом объёме данных

Комбинация параметров: визуальные паттерны

Плотный аналитический график

  • pointSize={4}
  • pointBorderWidth={1}
  • inactiveOpacity={0.2}

Характеристика: минимальная визуальная нагрузка, акцент на линиях.


Акцент на отдельных значениях

  • pointSize={10}
  • динамический pointColor
  • activeSize={14}

Характеристика: выделение ключевых точек, удобство анализа пиков.


Категориальная визуализация

  • кастомный pointSymbol
  • цвет по серии
  • средний размер точек

Характеристика: различение групп данных без перегрузки цветом линий.


Влияние точек на восприятие временных рядов

Временные ряды в Nivo становятся интерпретируемыми именно благодаря точкам. Линия интерполирует значения, но не фиксирует дискретность. Точки выполняют роль «якорей данных», обеспечивая:

  • точное считывание значений
  • визуальную проверку экстремумов
  • подтверждение структуры ряда

При отключении точек (enablePoints={false}) график становится более гладким, но теряет точность восприятия отдельных измерений, особенно при редких или нерегулярных данных.


Оптимизация производительности

При большом количестве точек критично учитывать нагрузку на DOM и SVG-рендеринг.

Подходы:

  • уменьшение pointSize
  • отключение обводки
  • использование enablePoints={false} для больших наборов данных
  • упрощение pointSymbol до базовых форм

Особенно важным становится отказ от сложных SVG-компонентов в кастомных точках, так как они масштабируются на каждый элемент серии.


Согласование точек с темой графика

В Nivo темы (theme) позволяют централизованно управлять стилями:

theme={{
    axis: {
        ticks: {
            text: {
                fill: '#666'
            }
        }
    },
    crosshair: {
        line: {
            stroke: '#999'
        }
    }
}}

Хотя точки задаются отдельно, их визуальная согласованность с темой достигается через:

  • наследование цвета серии
  • контраст обводки
  • согласование hover-эффектов с палитрой

Состояния и семантика точек

Каждая точка в Nivo несёт в себе набор состояний:

  • базовое состояние
  • активное (hover)
  • неактивное (dimmed)
  • выделенное через внешнюю логику

Эти состояния позволяют строить семантические графики, где точка становится носителем дополнительного смысла, а не только координаты.


Гибридные подходы визуализации

Комбинация стандартных и кастомных точек используется для построения многослойных визуализаций:

  • стандартные точки для всех значений
  • кастомные точки для экстремумов
  • изменённый размер для последних значений
pointSize={(point) =>
    point.index === point.data.length - 1 ? 12 : 6
}

Такой подход создаёт естественную иерархию данных внутри одного графика.