Генератор дуги в D3.js представляет собой специализированный компонент для построения SVG-путей, описывающих дуги и сегменты кольцевых диаграмм. Он используется для создания круговых и секторных визуализаций, включая pie chart, donut chart, кольцевые прогресс-бары и сложные радиальные структуры.
Основная функция генератора заключается в преобразовании набора параметров (углы, радиусы, отступы) в строку path-данных SVG. Эти данные затем интерпретируются браузером для отрисовки геометрии.
Функция d3.arc() возвращает генератор дуг, который
строит SVG path на основе заданных параметров:
Каждый вызов генератора возвращает строку, совместимую с атрибутом
d в SVG <path>.
const arc = d3.arc();
const pathData = arc({
innerRadius: 50,
outerRadius: 100,
startAngle: 0,
endAngle: Math.PI / 2
});
Результат представляет собой SVG-команду, описывающую сектор четверти круга.
Каждая дуга определяется четырьмя ключевыми параметрами:
Если innerRadius = 0, формируется сектор круга. Если
значение больше нуля, формируется кольцевой сегмент.
Углы отсчитываются от положительной оси X по часовой стрелке.
Генератор дуг поддерживает установку значений по умолчанию через цепочку методов:
const arc = d3.arc()
.innerRadius(40)
.outerRadius(80)
.startAngle(0)
.endAngle(Math.PI);
При таком подходе объект дуги можно вызывать без параметров:
const path = arc();
Наиболее частое применение генератора — построение кольцевых диаграмм.
const arc = d3.arc()
.innerRadius(0)
.outerRadius(100);
const data = {
startAngle: 0,
endAngle: Math.PI / 3
};
const path = arc(data);
Сектор представляет собой часть круга, ограниченную двумя радиальными линиями и дугой окружности.
const arc = d3.arc()
.innerRadius(60)
.outerRadius(100);
const segment = arc({
startAngle: 0,
endAngle: Math.PI / 2
});
Увеличение внутреннего радиуса создаёт эффект «дырки» в центре.
Генератор дуг часто используется совместно с d3.pie(),
который вычисляет углы на основе данных.
const pie = d3.pie();
const data = [10, 20, 30];
const arcs = pie(data);
Каждый элемент массива преобразуется в объект:
{
value: 10,
startAngle: ...,
endAngle: ...
}
Далее d3.arc() превращает эти данные в SVG-пути:
const arc = d3.arc()
.innerRadius(50)
.outerRadius(100);
const paths = arcs.map(d => arc(d));
По умолчанию дуга строится относительно центра (0,0). При
визуализации используется перенос координат через
transform:
svg.append("g")
.attr("transform", "translate(200,200)");
Это позволяет размещать диаграмму в произвольной точке SVG-контейнера.
Параметр padAngle задаёт зазор между сегментами:
const arc = d3.arc()
.innerRadius(50)
.outerRadius(100)
.padAngle(0.02);
Эффект:
Параметр cornerRadius позволяет сглаживать углы
сегментов:
const arc = d3.arc()
.innerRadius(60)
.outerRadius(120)
.cornerRadius(6);
Механизм применяется к угловым точкам сегмента, создавая более мягкую визуальную форму.
Генератор дуг используется не только для диаграмм, но и для построения:
Пример многослойного кольца:
const arc = d3.arc()
.innerRadius(d => d.y0)
.outerRadius(d => d.y1);
const segments = nodes.map(d => arc(d));
Параметры генератора могут задаваться как функции:
const arc = d3.arc()
.innerRadius(d => d.inner)
.outerRadius(d => d.outer)
.startAngle(d => d.a0)
.endAngle(d => d.a1);
Это позволяет напрямую связывать данные с геометрией без промежуточных преобразований.
Генератор дуг часто используется в переходах (transitions), где изменяются углы или радиусы.
path.transition()
.duration(750)
.attrTween("d", function(d) {
const interpolate = d3.interpolate(d.previous, d.current);
return t => arc(interpolate(t));
});
Интерполяция обеспечивает плавное изменение формы сегмента.
Результат работы генератора представляет собой набор команд:
Пример сегмента:
M x y
A r r 0 0 1 x y
L x y
Z
Эти команды формируют замкнутую геометрическую фигуру.
При значении углов, формирующих полный круг, генератор корректно обрабатывает замыкание:
const arc = d3.arc()
.innerRadius(0)
.outerRadius(100);
arc({
startAngle: 0,
endAngle: 2 * Math.PI
});
Результат — полный круг, а не артефакт разрыва.
Все углы задаются в радианах, что требует преобразования при работе с градусами:
const degToRad = deg => deg * (Math.PI / 180);
const arc = d3.arc()
.startAngle(degToRad(0))
.endAngle(degToRad(90));
Использование радианов обеспечивает согласованность с математической моделью окружности.
Генератор поддерживает построение многослойных визуализаций, где каждый слой определяется разными радиусами:
const arc = d3.arc();
const layers = [
{ inner: 0, outer: 50 },
{ inner: 50, outer: 100 },
{ inner: 100, outer: 150 }
];
const paths = layers.map(layer =>
arc({
innerRadius: layer.inner,
outerRadius: layer.outer,
startAngle: 0,
endAngle: Math.PI / 2
})
);
Один и тот же генератор может применяться ко множеству данных без повторной инициализации:
const arc = d3.arc()
.innerRadius(40)
.outerRadius(90);
selection.selectAll("path")
.data(data)
.join("path")
.attr("d", arc);
Такой подход снижает накладные расходы и упрощает структуру кода.
Генератор устойчив к частичным данным, но некорректные параметры могут привести к:
В таких случаях SVG-путь может быть пустым или неотображаемым.
Генератор дуг часто используется как базовый элемент более сложных структур:
Каждый элемент строится на основе одинакового принципа преобразования углов и радиусов в геометрию.