В D3.js форма линии, построенной через d3.line(),
определяется не только набором точек, но и способом интерполяции между
ними. Именно кривые (curve functions) отвечают за то, как именно
соединяются точки: прямыми отрезками, сглаженными сплайнами,
ступенчатыми переходами или специальными математическими
интерполяциями.
Каждая кривая в D3 представляет собой функцию, которая передаётся в
генератор линии:
d3.line()
.curve(d3.curveBasis);
Кривая не изменяет данные, а управляет алгоритмом построения SVG-пути
(d атрибут).
Архитектура кривых в D3
Кривые в D3 реализуют интерфейс curve factory, который определяет
методы:
lineStart() — начало новой линии
lineEnd() — завершение линии
point(x, y) — добавление точки
areaStart() / areaEnd() — для областей
(area generator)
curve() — внутренние вычисления интерполяции
Каждая кривая решает одну задачу: как интерполировать
последовательность точек в плавную или дискретную форму.
Линейная кривая: curveLinear
Базовая форма без сглаживания:
d3.line()
.curve(d3.curveLinear);
Поведение
- Точки соединяются прямыми отрезками
- Отсутствует интерполяция
- Максимальная точность исходных данных
Использование
- Графики с дискретными значениями
- Геометрические построения
- Отладка данных
Ступенчатые кривые: curveStep
Ступенчатая интерполяция создаёт «ломаную лестницу».
curveStep
d3.line()
.curve(d3.curveStep);
Форма:
- горизонтальный сегмент
- затем вертикальный переход
curveStepBefore
d3.line()
.curve(d3.curveStepBefore);
Изменение порядка:
- сначала вертикальный переход
- затем горизонталь
curveStepAfter
d3.line()
.curve(d3.curveStepAfter);
- сначала горизонталь
- затем вертикальный переход
Особенности ступенчатых
кривых
- подходят для отображения событий во времени
- часто используются в таймлайнах
- подчёркивают дискретность данных
Сглаженные сплайны:
curveBasis
Кривая B-spline обеспечивает мягкое сглаживание без прохождения через
все точки.
d3.line()
.curve(d3.curveBasis);
Свойства
- линия не обязана проходить через исходные точки
- формируется плавная аппроксимация
- используется локальная интерполяция
Поведение
Каждая точка влияет на соседние сегменты, создавая непрерывную кривую
без резких углов.
Применение
- визуализация трендов
- сглаживание шумных данных
- эстетические графики
Важная особенность
Кривая может визуально «сдвигать» экстремумы относительно исходных
значений.
curveBasisClosed и
curveBasisOpen
curveBasisClosed
Замыкает кривую в кольцо:
d3.line()
.curve(d3.curveBasisClosed);
- последняя точка соединяется с первой
- используется в полярных диаграммах и замкнутых формах
curveBasisOpen
d3.line()
.curve(d3.curveBasisOpen);
- открытая форма без замыкания
- более контролируемое сглаживание на краях
curveCardinal:
контролируемое сглаживание
Cardinal spline даёт баланс между точностью и сглаживанием.
d3.line()
.curve(d3.curveCardinal);
Параметр tension
d3.curveCardinal.tension(0.5);
tension = 0 → сильное сглаживание
tension → 1 → приближение к линейной форме
Особенности
- кривая проходит через все точки
- сглаживание управляется натяжением
- возможны небольшие «перерегулирования»
Использование
- финансовые графики
- данные с естественными колебаниями
- визуализация физических процессов
curveCardinalClosed и
curveCardinalOpen
curveCardinalClosed
d3.curveCardinalClosed
- замкнутая форма
- полезна для круговых диаграмм и циклических данных
curveCardinalOpen
d3.curveCardinalOpen
- открытая форма с контролем краевых сегментов
- предотвращает резкие артефакты на концах линии
curveCatmullRom:
интерполяция через точки
Catmull-Rom spline — одна из наиболее используемых кривых в D3 для
гладких линий, проходящих через все точки.
d3.line()
.curve(d3.curveCatmullRom);
Параметр alpha
d3.curveCatmullRom.alpha(0.5);
Режимы поведения alpha
alpha = 0 — uniform (равномерная интерполяция)
alpha = 0.5 — centripetal (наиболее стабильная
форма)
alpha = 1 — chordal (более «резкая» геометрия)
Особенности
- линия проходит через все точки
- минимизирует резкие перегибы
- более предсказуема, чем Cardinal
Использование
- графики движения
- траектории
- временные ряды с высокой плотностью точек
curveCatmullRomClosed и
curveCatmullRomOpen
curveCatmullRomClosed
d3.curveCatmullRomClosed
- формирует замкнутую интерполяцию
- используется для циклических структур
curveCatmullRomOpen
d3.curveCatmullRomOpen
- открытая форма
- корректное поведение на концах без фиктивных точек
curveMonotoneX и
curveMonotoneY
Монотонные кривые предотвращают появление локальных экстремумов.
curveMonotoneX
d3.line()
.curve(d3.curveMonotoneX);
- сохраняет монотонность по оси X
- исключает «петли»
curveMonotoneY
d3.line()
.curve(d3.curveMonotoneY);
- сохраняет монотонность по Y
Особенности
- гарантируют отсутствие артефактных перегибов
- подходят для строгих научных графиков
- не всегда выглядят максимально «гладко», но математически
корректны
curveNatural:
естественная интерполяция
d3.line()
.curve(d3.curveNatural);
Поведение
- имитирует физически естественное движение
- сглаживание основано на внутренней аппроксимации
Характеристики
- мягкие переходы
- визуально «органические» линии
- не гарантирует прохождение через точки с высокой точностью
curveBundle:
сглаживание графовых структур
d3.line()
.curve(d3.curveBundle.beta(0.8));
Параметр beta
- низкое значение → сильное сглаживание
- высокое значение → ближе к прямым линиям
Использование
- иерархические структуры
- визуализация графов
- маршруты связей
Особенность
Кривая работает лучше всего в связке с d3.hierarchy и
edge bundling техниками.
curveLinearClosed
d3.curveLinearClosed
- соединяет последнюю и первую точки
- не выполняет сглаживание
- используется для полигональных форм
Сравнение поведения
основных кривых
Без сглаживания
Мягкое сглаживание
Контролируемое
сглаживание через точки
- curveCatmullRom
- curveCardinal
Строгая геометрическая
устойчивость
- curveMonotoneX
- curveMonotoneY
Специальные структуры
Влияние кривой на SVG path
Каждая кривая влияет на структуру атрибута d:
- количество сегментов
- наличие контрольных точек Bézier
- плавность переходов
- плотность команд
C, L, S
Например:
curveLinear → только L
curveBasis → множество кубических Bézier
(C)
curveStep → чередование H и V
логики
Комбинирование кривых с
генераторами
Кривые применяются не только к line, но и к:
d3.area()
d3.radialLine()
d3.linkHorizontal() / linkVertical()
d3.area()
.curve(d3.curveCatmullRom);
В областях кривая влияет как на верхнюю, так и на нижнюю границу,
создавая симметричную интерполяцию.
Производительность
и поведение на больших наборах данных
curveLinear — минимальная нагрузка
curveStep — низкая сложность
curveBasis — умеренная нагрузка
curveCatmullRom — более затратная интерполяция
curveBundle — может быть вычислительно тяжёлой при
больших графах
Оптимизация часто достигается выбором более простой кривой при
высокой плотности точек.
Практика выбора кривой по
типу данных
- финансовые данные с шумом → curveCardinal или curveCatmullRom
- строгие измерения → curveLinear или curveMonotoneX
- событийные временные ряды → curveStep
- визуализация трендов → curveBasis
- графовые структуры → curveBundle