Элемент path: команды M, L, C, Q, A, Z

Векторная графика в 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 — Move To

Команда M задаёт начальную точку пути без рисования линии.

Синтаксис

M x y

Поведение

  • Перемещает “перо” в точку (x, y)
  • Начинает новый подконтур
  • Не создаёт визуальной линии

Особенности

  • Первая команда почти всегда M
  • Повторное использование M внутри одного path начинает новый сегмент

Пример

M 10 10 L 100 10

Команда L — Line To

Команда L создаёт прямую линию от текущей точки к заданной.

Синтаксис

L x y

Поведение

  • Рисуется линия
  • Текущая точка обновляется

Пример

M 10 10 L 100 10 L 100 100

Формируется ломаная линия из двух сегментов.


Команда C — Cubic Bézier Curve

Команда 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 — Quadratic Bézier Curve

Команда Q задаёт квадратичную кривую Безье с одной контрольной точкой.

Синтаксис

Q x1 y1, x y
  • (x1, y1) — контрольная точка
  • (x, y) — конечная точка

Поведение

Кривая формируется тремя точками:

  • стартовая
  • контрольная
  • конечная

Отличие от C

  • одна контрольная точка вместо двух
  • более простая форма
  • менее гибкая кривизна

Пример

M 10 80 Q 50 10, 90 80

Команда A — Arc (дуга эллипса)

Команда 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 — Close Path

Команда Z замыкает контур, соединяя текущую точку с начальной.

Синтаксис

Z

Поведение

  • создаётся замыкающая линия
  • путь становится замкнутым контуром

Пример

M 10 10 L 100 10 L 100 100 Z

Использование path в D3.js

D3.js не заменяет SVG path, а управляет генерацией строки d через функции и привязку данных.


Ручное формирование d

const 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.line

const 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 для остальных.


Кривые Безье в D3

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-подобные сегменты.


Связь D3 и команд M, L, C, Q, A, Z

D3.js оперирует не отдельными командами напрямую, а абстракциями:

  • M — старт линии (moveTo)
  • L — линейная интерполяция
  • C — кривые интерполяции (curve*)
  • Q — упрощённые кривые в некоторых режимах интерполяции
  • A — используется в d3.arc
  • Z — закрытие формы в генераторах (closed path)

Генерация дуг через d3.arc

const 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 используется для:

  • заливки фигур
  • корректного вычисления площадей
  • построения полигонов

Преобразование данных в path-строки

Типичный процесс в D3:

  1. массив данных
  2. масштабирование (scaleLinear, scaleTime)
  3. генератор (d3.line, d3.area, d3.arc)
  4. формирование d
  5. рендер SVG path

Внутренние особенности интерпретации SVG path

SVG интерпретирует path как поток команд:

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

Эта модель делает path универсальным контейнером для любых 2D-контуров, а D3.js — инструментом динамической генерации таких структур на основе данных.