SVG предоставляет набор векторных примитивов для графики, и текстовые
элементы занимают в нём особое место. В отличие от HTML, где текст — это
потоковый контент, в SVG текст является графическим объектом с
координатной привязкой и набором атрибутов позиционирования. В D3.js
работа с текстом строится поверх стандартных SVG-элементов
<text>, <tspan> и
<textPath>, позволяя динамически формировать надписи,
сложные подписи и текст вдоль кривых.
Базовый текстовый элемент создаётся через SVG-тег
<text>, который в D3 обычно добавляется через
selection.append.
d3.select("svg")
.append("text")
.attr("x", 50)
.attr("y", 50)
.text("Простой текст");
SVG-координаты работают в пиксельной системе пользовательского
пространства. Атрибуты x и y задают начальную
точку текста, но визуальное положение зависит также от выравнивания и
метрик шрифта.
SVG-текст по умолчанию привязывается к базовой линии шрифта. Это
означает, что значение y не соответствует верхнему краю
символов.
Ключевые атрибуты:
x, y — координаты начальной точкиdx, dy — смещение относительно базовой
позицииtext-anchor — горизонтальное выравниваниеdominant-baseline — вертикальное выравниваниеПример центрирования текста:
d3.select("svg")
.append("text")
.attr("x", 200)
.attr("y", 100)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.text("Центр");
Значение text-anchor может принимать:
start — выравнивание по началу строкиmiddle — центрированиеend — выравнивание по правому краюКомбинация text-anchor и dominant-baseline
позволяет точно контролировать положение подписи относительно
геометрических объектов диаграммы.
D3.js связывает данные с DOM-элементами, включая текстовые узлы.
Метод .text() может принимать как строку, так и функцию,
возвращающую строку на основе данных.
const data = [
{ name: "A", value: 10 },
{ name: "B", value: 25 }
];
d3.select("svg")
.selectAll("text.label")
.data(data)
.enter()
.append("text")
.attr("class", "label")
.attr("x", d => d.value * 10)
.attr("y", (d, i) => 30 + i * 20)
.text(d => `${d.name}: ${d.value}`);
Текст в SVG не ограничен строкой фиксированной длины, однако отсутствие автоматического переноса требует явного управления разбиением.
<tspan>SVG не поддерживает автоматический перенос строк, поэтому
многострочные надписи реализуются через элемент
<tspan>. Он позволяет разбивать текст на части с
индивидуальным позиционированием.
const text = d3.select("svg")
.append("text")
.attr("x", 50)
.attr("y", 50);
text.append("tspan")
.attr("x", 50)
.attr("dy", "0em")
.text("Первая строка");
text.append("tspan")
.attr("x", 50)
.attr("dy", "1.2em")
.text("Вторая строка");
text.append("tspan")
.attr("x", 50)
.attr("dy", "1.2em")
.text("Третья строка");
Ключевая особенность:
dy задаёт смещение относительно предыдущей строкиx фиксирует горизонтальное выравниваниеx текст будет смещаться относительно
предыдущего tspanaПри работе с динамическими данными tspan часто создаются
через data join:
const lines = ["строка 1", "строка 2", "строка 3"];
const text = d3.select("svg")
.append("text")
.attr("x", 100)
.attr("y", 100);
text.selectAll("tspan")
.data(lines)
.enter()
.append("tspan")
.attr("x", 100)
.attr("dy", (d, i) => i === 0 ? "0em" : "1.2em")
.text(d => d);
SVG-текст поддерживает стандартные CSS-стили, включая:
font-sizefont-familyfont-weightfillletter-spacingd3.select("svg")
.append("text")
.attr("x", 50)
.attr("y", 50)
.style("font-size", "18px")
.style("font-family", "Arial")
.style("fill", "#333")
.text("Стилизованный текст");
При работе с визуализациями D3 важно учитывать, что текст часто является частью композиции графика, поэтому типографика должна быть согласована с визуальной иерархией элементов.
<textPath>SVG позволяет размещать текст вдоль произвольного пути. Для этого
используется элемент <textPath>, который привязывает
строку к геометрии <path>.
Сначала определяется путь:
const svg = d3.select("svg");
svg.append("defs")
.append("path")
.attr("id", "curvePath")
.attr("d", "M 50 200 C 150 50, 250 350, 350 200");
Затем создаётся текст, связанный с этим путём:
svg.append("text")
.append("textPath")
.attr("href", "#curvePath")
.attr("startOffset", "50%")
.attr("text-anchor", "middle")
.text("Текст вдоль кривой");
Параметр startOffset управляет положением текста вдоль
линии:
0% — начало пути50% — центр100% — конецВ современных SVG используется атрибут href, хотя в
некоторых окружениях встречается xlink:href.
D3 позволяет анимировать и изменять текст вдоль пути в зависимости от данных или состояния интерфейса.
svg.select("textPath")
.transition()
.duration(1000)
.attr("startOffset", "80%");
Также можно изменять сам путь, что автоматически перестраивает расположение текста:
svg.select("#curvePath")
.attr("d", "M 50 250 C 150 100, 250 400, 350 250");
Текст при этом следует новой геометрии без дополнительных вычислений.
<text>, <tspan> и
<textPath> в сложных визуализацияхВ сложных диаграммах эти элементы часто используются совместно.
<text> задаёт контейнер, <tspan>
формирует структурированные блоки, а <textPath>
применяется для привязки к геометрии.
Пример комбинированной структуры:
const label = svg.append("text");
label.append("textPath")
.attr("href", "#curvePath")
.attr("startOffset", "50%")
.append("tspan")
.text("Основной заголовок");
label.append("tspan")
.attr("x", 200)
.attr("dy", "1.5em")
.text("Дополнительная подпись");
Такой подход позволяет создавать многослойные подписи, где часть текста следует форме графика, а часть остаётся в стандартной координатной системе.
SVG-рендеринг текста зависит от метрик шрифта, поэтому точное позиционирование требует управления базовой линией.
Атрибут dominant-baseline может принимать значения:
hangingmiddlebaselinecentrald3.select("svg")
.append("text")
.attr("x", 100)
.attr("y", 100)
.attr("dominant-baseline", "middle")
.attr("text-anchor", "middle")
.text("Точная центровка");
При создании осевых подписей и меток шкал это критически важно, поскольку визуальная симметрия зависит от шрифтовых метрик, а не только от координат.
dx и dy для тонкой типографикиАтрибуты dx и dy позволяют смещать текст
без изменения основных координат.
d3.select("svg")
.append("text")
.attr("x", 100)
.attr("y", 100)
.text("Базовый")
.append("tspan")
.attr("dx", "10")
.attr("dy", "-5")
.text("смещённый фрагмент");
Это используется для:
В D3 текст часто выступает не просто подписью, а носителем данных. Значения могут кодироваться через содержимое строки, размер, цвет или позицию.
d3.select("svg")
.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("x", d => d.value * 5)
.attr("y", 50)
.style("fill", d => d.value > 20 ? "red" : "black")
.text(d => d.value);
Такая модель делает текст частью визуального канала представления информации, наравне с линиями и фигурами.
SVG-текст имеет ряд особенностей, влияющих на поведение в визуализациях:
При проектировании визуализаций эти ограничения компенсируются
использованием <tspan>, вычислением размеров текста и
динамическим перераспределением координат через D3.