Векторная графика в SVG строится на основе описания контуров через
атрибут d элемента <path>. Этот атрибут
представляет собой строку команд, каждая из которых задаёт перемещение,
линии, кривые или замыкание контура. D3.js работает с path
напрямую через генерацию таких строк или их динамическую модификацию на
основе данных.
Контур в path не является набором отдельных фигур — это
единая последовательность команд, интерпретируемая SVG-рендерером как
непрерывная траектория.
dСтрока d состоит из набора команд:
M x y
L x y
C x1 y1, x2 y2, x y
Q x1 y1, x y
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
Z
Команды могут быть в верхнем регистре (абсолютные координаты) или в нижнем (относительные координаты).
Команда M задаёт начальную точку пути без рисования
линии.
M x y
(x, y)MM внутри одного
path начинает новый сегментM 10 10 L 100 10
Команда L создаёт прямую линию от текущей точки к
заданной.
L x y
M 10 10 L 100 10 L 100 100
Формируется ломаная линия из двух сегментов.
Команда C задаёт кубическую кривую Безье с двумя
контрольными точками.
C x1 y1, x2 y2, x y
(x1, y1) — первая контрольная точка(x2, y2) — вторая контрольная точка(x, y) — конечная точка кривойКривая определяется четырьмя точками:
Контрольные точки не лежат на кривой, но управляют её изгибом.
M 10 80 C 40 10, 65 10, 95 80
Команда Q задаёт квадратичную кривую Безье с одной
контрольной точкой.
Q x1 y1, x y
(x1, y1) — контрольная точка(x, y) — конечная точкаКривая формируется тремя точками:
CM 10 80 Q 50 10, 90 80
Команда A строит эллиптическую дугу между точками.
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
rx, ry — радиусы эллипса
x-axis-rotation — поворот эллипса
large-arc-flag:
0 — малая дуга1 — большая дугаsweep-flag:
0 — против часовой1 — по часовой(x, y) — конечная точка
SVG выбирает одну из двух возможных дуг между точками, опираясь на флаги.
M 50 50 A 30 30 0 0 1 100 100
Команда Z замыкает контур, соединяя текущую точку с
начальной.
Z
M 10 10 L 100 10 L 100 100 Z
path в
D3.jsD3.js не заменяет SVG path, а управляет генерацией
строки d через функции и привязку данных.
dconst path = d3.select("svg")
.append("path")
.attr("d", "M 10 10 L 100 100 L 200 50 Z")
.attr("fill", "none")
.attr("stroke", "black");
d3.lineconst data = [
[10, 10],
[100, 100],
[200, 50]
];
const line = d3.line();
d3.select("svg")
.append("path")
.attr("d", line(data))
.attr("fill", "none")
.attr("stroke", "steelblue");
Генератор автоматически использует M для первой точки и
L для остальных.
const line = d3.line()
.curve(d3.curveBasis);
const data = [10, 50, 80, 120, 160];
d3.select("svg")
.append("path")
.attr("d", line(data.map((d, i) => [i * 50, d])));
Хотя внутри используются сглаженные кривые, на уровне SVG это всё
равно преобразуется в C-подобные сегменты.
M,
L, C, Q, A,
ZD3.js оперирует не отдельными командами напрямую, а абстракциями:
M — старт линии (moveTo)L — линейная интерполяцияC — кривые интерполяции (curve*)Q — упрощённые кривые в некоторых режимах
интерполяцииA — используется в d3.arcZ — закрытие формы в генераторах
(closed path)d3.arcconst arc = d3.arc()
.innerRadius(40)
.outerRadius(80)
.startAngle(0)
.endAngle(Math.PI / 2);
d3.select("svg")
.append("path")
.attr("d", arc())
.attr("fill", "orange");
Внутри генератора формируются команды A и
Z, скрытые от прямого управления.
SVG поддерживает две формы:
M, L,
C, Q, A, Z)m, l,
c, q, a, z)D3.js по умолчанию генерирует абсолютные координаты, так как они проще для привязки к данным.
Один path может содержать несколько подмаршрутов:
M 10 10 L 100 10 Z
M 150 10 L 250 100 Z
Каждый новый M начинает независимую фигуру внутри одного
элемента.
M + L формируют ломаные линии, используемые
в:
C и Q используются для:
A применяются в:
Z используется для:
Типичный процесс в D3:
scaleLinear,
scaleTime)d3.line, d3.area,
d3.arc)dpathSVG интерпретирует path как поток команд:
Эта модель делает path универсальным контейнером для
любых 2D-контуров, а D3.js — инструментом динамической генерации таких
структур на основе данных.