Генератор площади d3.area() предназначен для построения
площадных графиков, где важна не только линия изменения значений, но и
заполненная область под кривой. Он формирует SVG-путь на основе массива
данных, интерпретируя каждую точку как координаты верхней и нижней
границы области.
Площадной график описывается двумя основными линиями:
Между этими границами формируется залитая область. В
d3.area() эта логика инкапсулирована в генератор пути SVG,
который автоматически строит замкнутую фигуру.
Генератор возвращает строку для атрибута d элемента
<path>.
Создание генератора площади выполняется через:
const area = d3.area();
Далее задаются функции доступа к координатам:
x() — горизонтальная координатаy0() — нижняя граница областиy1() — верхняя граница областиПростейшая конфигурация:
const area = d3.area()
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.y));
В этом случае нижняя граница фиксирована на уровне
height, что соответствует оси X в нижней части SVG.
Почти всегда d3.area() используется совместно с
масштабами d3.scaleLinear() или другими шкалами.
const xScale = d3.scaleLinear()
.domain([0, 10])
.range([0, width]);
const yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
Инверсия диапазона yScale (от height к
0) необходима, так как в SVG ось Y направлена вниз.
После этого генератор связывается со шкалами:
const area = d3.area()
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.y));
Одно из ключевых применений — визуализация диапазонов или двух временных рядов.
Структура данных:
const data = [
{ x: 0, min: 30, max: 80 },
{ x: 1, min: 20, max: 70 },
{ x: 2, min: 25, max: 90 }
];
Настройка генератора:
const area = d3.area()
.x(d => xScale(d.x))
.y0(d => yScale(d.min))
.y1(d => yScale(d.max));
В этом случае формируется область неопределённости или диапазона значений.
Функции доступа могут принимать не только поля объектов, но и индексы:
.x((d, i) => xScale(i))
Это позволяет использовать массивы без структурированных объектов:
const data = [10, 20, 15, 40];
const area = d3.area()
.x((d, i) => xScale(i))
.y0(height)
.y1(d => yScale(d));
d3.area() поддерживает различные типы сглаживания через
метод curve().
Примеры кривых:
d3.curveLinear — линейные сегментыd3.curveBasis — сглаженная кривая Безьеd3.curveStep — ступенчатая линияd3.curveCardinal — мягкая интерполяция с контролем
натяженияПример применения:
const area = d3.area()
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.y))
.curve(d3.curveBasis);
Выбор кривой влияет на восприятие данных: линейная точность или визуальная плавность.
По умолчанию область замыкается автоматически. Однако важно понимать, как формируется путь:
Z)Это обеспечивает корректное заполнение через fill.
При наличии пропущенных значений используется метод:
defined(d => d.value !== null)
Пример:
const area = d3.area()
.defined(d => d.value != null)
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.value));
Разрыв данных приводит к разделению области на несколько независимых сегментов.
Одно из наиболее распространённых применений — стековые диаграммы.
Данные обрабатываются через d3.stack():
const stack = d3.stack()
.keys(["a", "b", "c"]);
const series = stack(data);
Каждый слой передаётся в d3.area():
const area = d3.area()
.x(d => xScale(d.data.x))
.y0(d => yScale(d[0]))
.y1(d => yScale(d[1]));
Каждый элемент d в stack содержит диапазон
[y0, y1], определяющий слой.
SVG-путь, созданный d3.area(), можно анимировать через
переходы:
path.datum(data)
.transition()
.duration(750)
.attr("d", area);
При изменении данных генератор пересчитывает все координаты, формируя новую форму области.
d3.area() строит строку path-данных SVG на основе
последовательности команд:
M — перемещение в начальную точкуL — линия к следующей точкеZ — замыкание путиПример логики:
Нижняя линия может быть фиксированной или динамической.
Фиксированная:
.y0(height)
Динамическая:
.y0(d => yScale(d.min))
Также возможно смещение относительно нуля:
.y0(d => yScale(0))
.y1(d => yScale(d.value))
В сложных визуализациях часто комбинируются разные области:
const areaA = d3.area()
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.a));
const areaB = d3.area()
.x(d => xScale(d.x))
.y0(height)
.y1(d => yScale(d.b));
Это позволяет строить многослойные графики без использования stack.
При больших объёмах данных важны следующие аспекты:
curveLinear для снижения вычислительной
нагрузкиСглаженные кривые требуют дополнительных расчетов контрольных точек, что увеличивает стоимость рендера.
Обычно d3.area() используется вместе с
d3.axisBottom() и d3.axisLeft():
svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
svg.append("g")
.call(d3.axisLeft(yScale));
Генератор площади визуально опирается на эти оси, но не зависит от них напрямую.
С точки зрения геометрии, d3.area() формирует
многоугольник, аппроксимирующий интеграл функции:
Площадь между ними может рассматриваться как интеграл разности функций на дискретных точках данных.
Изменение domain или range шкал приводит к автоматическому пересчёту всех координат:
xScale.domain([0, newMax]);
yScale.range([newHeight, 0]);
После этого достаточно заново применить генератор к данным:
path.attr("d", area);
Сформированный путь может быть использован в различных SVG-операциях:
fill)stroke)clipPath)mask)Площадная форма особенно чувствительна к стилям заливки, так как визуально занимает большую часть графика.
При добавлении интерактивности генератор остаётся неизменным, а обновляется только входной набор данных:
function update(newData) {
path.datum(newData).attr("d", area);
}
Это позволяет динамически перестраивать графики без пересоздания SVG-структуры.