Установка текстового и HTML-содержимого

В библиотеке D3.js метод text() используется для установки или получения текстового содержимого элементов DOM. Метод работает аналогично свойству textContent в обычном JavaScript и применяется к выделенным элементам через механизм выборок D3.

Базовая форма вызова:

selection.text("Новый текст");

Пример:

d3.select("p")
  .text("Привет, D3.js!");

После выполнения содержимое первого найденного тега <p> будет полностью заменено указанной строкой.

HTML:

<p>Старый текст</p>

Результат:

<p>Привет, D3.js!</p>

Метод text() всегда заменяет существующее текстовое содержимое элемента.


Установка текста для нескольких элементов

При работе с выборками D3 изменения автоматически применяются ко всем найденным элементам.

Пример:

d3.selectAll("li")
  .text("Элемент списка");

HTML до выполнения:

<ul>
  <li>Первый</li>
  <li>Второй</li>
  <li>Третий</li>
</ul>

HTML после выполнения:

<ul>
  <li>Элемент списка</li>
  <li>Элемент списка</li>
  <li>Элемент списка</li>
</ul>

Использование функции в text()

Наиболее мощная возможность метода — генерация текста через функцию. Для каждого элемента функция вызывается отдельно.

Сигнатура:

selection.text(function(d, i) {
    return ...;
});

Параметры:

Параметр Описание
d Данные, привязанные к элементу
i Индекс элемента
this Текущий DOM-элемент

Пример:

const data = [10, 20, 30];

d3.select("body")
  .selectAll("p")
  .data(data)
  .enter()
  .append("p")
  .text(function(d, i) {
      return "Индекс: " + i + ", значение: " + d;
  });

Результат:

<p>Индекс: 0, значение: 10</p>
<p>Индекс: 1, значение: 20</p>
<p>Индекс: 2, значение: 30</p>

Краткая запись через стрелочную функцию:

.text((d, i) => `Элемент ${i}: ${d}`);

Получение текстового содержимого

Если метод text() вызывается без аргументов, он возвращает текст первого найденного элемента.

Пример:

const text = d3.select("h1").text();

console.log(text);

HTML:

<h1>Заголовок страницы</h1>

Результат в консоли:

Заголовок страницы

Особенности работы text()

Экранирование HTML

Метод text() не интерпретирует HTML-разметку. Все специальные символы автоматически экранируются.

Пример:

d3.select("div")
  .text("<strong>Жирный текст</strong>");

Результат:

<div>&lt;strong&gt;Жирный текст&lt;/strong&gt;</div>

В браузере пользователь увидит:

<strong>Жирный текст</strong>

как обычный текст, а не как HTML.

Это делает text() безопасным способом вывода пользовательских данных.


Метод html()

Метод html() устанавливает HTML-содержимое элемента. В отличие от text(), строка интерпретируется браузером как HTML-код.

Базовый синтаксис:

selection.html("<strong>Текст</strong>");

Пример:

d3.select("div")
  .html("<h2>Заголовок</h2><p>Абзац</p>");

Результат:

<div>
  <h2>Заголовок</h2>
  <p>Абзац</p>
</div>

Отличия text() и html()

Метод Интерпретация HTML Безопасность
text() Нет Высокая
html() Да Требует осторожности

Сравнение:

d3.select("#a")
  .text("<em>Текст</em>");

d3.select("#b")
  .html("<em>Текст</em>");

Результат:

<div id="a">&lt;em&gt;Текст&lt;/em&gt;</div>
<div id="b"><em>Текст</em></div>

Использование функции в html()

Метод html() также поддерживает динамическую генерацию содержимого.

Пример:

const users = [
  { name: "Анна", age: 24 },
  { name: "Игорь", age: 31 }
];

d3.select("body")
  .selectAll(".user")
  .data(users)
  .enter()
  .append("div")
  .html(d => `
      <strong>${d.name}</strong>
      <span>${d.age} лет</span>
  `);

Результат:

<div>
  <strong>Анна</strong>
  <span>24 лет</span>
</div>

<div>
  <strong>Игорь</strong>
  <span>31 лет</span>
</div>

Получение HTML-содержимого

Вызов без аргументов возвращает HTML первого элемента.

Пример:

const html = d3.select("article").html();

console.log(html);

HTML:

<article>
  <h2>Новость</h2>
  <p>Описание</p>
</article>

Результат:

<h2>Новость</h2>
<p>Описание</p>

Работа с SVG

Метод html() не поддерживается внутри SVG-элементов, поскольку SVG использует XML-структуру.

Пример ошибки:

d3.select("svg")
  .html("<circle></circle>");

Для SVG необходимо использовать методы создания элементов:

d3.select("svg")
  .append("circle")
  .attr("cx", 50)
  .attr("cy", 50)
  .attr("r", 20);

Текст внутри SVG создаётся через элемент <text>:

d3.select("svg")
  .append("text")
  .attr("x", 100)
  .attr("y", 100)
  .text("Подпись");

Комбинирование append(), text() и html()

Наиболее распространённый сценарий в D3 — создание элементов и заполнение их содержимым.

Пример:

d3.select("body")
  .append("h1")
  .text("Статистика продаж");

Создание карточки:

d3.select("body")
  .append("div")
  .attr("class", "card")
  .html(`
      <h3>Ноутбук</h3>
      <p>Цена: 1200$</p>
  `);

Динамическое обновление содержимого

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

Пример обновления счётчика:

let count = 0;

setInterval(() => {
    count++;

    d3.select("#counter")
      .text(count);
}, 1000);

Формирование сложного HTML

Метод html() позволяет генерировать шаблоны прямо внутри JavaScript.

Пример:

const products = [
  { name: "Телефон", price: 500 },
  { name: "Планшет", price: 800 }
];

d3.select("#catalog")
  .selectAll(".product")
  .data(products)
  .enter()
  .append("div")
  .attr("class", "product")
  .html(d => `
      <h3>${d.name}</h3>
      <p>Цена: ${d.price}$</p>
  `);

Потенциальные проблемы безопасности

Использование html() с пользовательскими данными может привести к XSS-атакам.

Опасный пример:

const userInput = "<script>alert('XSS')</script>";

d3.select("#content")
  .html(userInput);

Безопасный вариант:

d3.select("#content")
  .text(userInput);

Если HTML необходимо разрешить, данные предварительно очищаются через специальные библиотеки санитизации.


Производительность

При частом обновлении интерфейса важно учитывать различия между text() и html().

text() быстрее

Метод работает только с текстовым узлом:

selection.text("Новое значение");

html() медленнее

Браузеру требуется:

  1. Разобрать HTML-строку
  2. Построить DOM-дерево
  3. Выполнить перерасчёт структуры

Поэтому для простого текста предпочтителен text().


Очистка содержимого

Очистить текст:

d3.select("#block")
  .text("");

Очистить HTML:

d3.select("#block")
  .html("");

Использование вместе с событиями

Пример интерактивного изменения содержимого:

d3.select("button")
  .on("click", function() {

      d3.select("#message")
        .html("<strong>Кнопка нажата</strong>");

  });

Создание таблицы через html()

const data = [
  { name: "Анна", score: 90 },
  { name: "Игорь", score: 75 }
];

d3.select("#table")
  .html(`
      <table>
          <tr>
              <th>Имя</th>
              <th>Баллы</th>
          </tr>

          ${data.map(d => `
              <tr>
                  <td>${d.name}</td>
                  <td>${d.score}</td>
              </tr>
          `).join("")}
      </table>
  `);

Использование шаблонных строк

Современный JavaScript значительно упрощает генерацию HTML.

Пример:

const title = "Отчёт";
const year = 2026;

d3.select("#report")
  .html(`
      <h1>${title}</h1>
      <p>Год: ${year}</p>
  `);

Сравнение подходов

Через html()

d3.select("body")
  .html("<h1>Заголовок</h1>");

Через D3-методы

d3.select("body")
  .append("h1")
  .text("Заголовок");

Первый вариант компактнее, второй — лучше интегрируется с философией D3 и удобнее для сложных визуализаций.


Практические рекомендации

Когда использовать text()

Подходит для:

  • подписей графиков;
  • отображения чисел;
  • вывода пользовательских данных;
  • безопасного текста;
  • частых обновлений интерфейса.

Когда использовать html()

Подходит для:

  • генерации карточек;
  • вставки разметки;
  • создания таблиц;
  • форматированного контента;
  • динамических шаблонов.

Типичная структура обновления интерфейса

function render(user) {

    d3.select("#profile")
      .html(`
          <h2>${user.name}</h2>
          <p>${user.city}</p>
      `);

}

Вызов:

render({
    name: "Алексей",
    city: "Алматы"
});

Совместное использование с привязкой данных

const numbers = [5, 10, 15];

d3.select("body")
  .selectAll("div")
  .data(numbers)
  .enter()
  .append("div")
  .text(d => d * 2);

Результат:

<div>10</div>
<div>20</div>
<div>30</div>

Вложенная генерация HTML

const categories = [
  {
    title: "Фрукты",
    items: ["Яблоко", "Груша"]
  },
  {
    title: "Овощи",
    items: ["Морковь", "Огурец"]
  }
];

d3.select("#content")
  .selectAll(".category")
  .data(categories)
  .enter()
  .append("div")
  .html(d => `
      <h2>${d.title}</h2>
      <ul>
          ${d.items.map(item => `<li>${item}</li>`).join("")}
      </ul>
  `);

Основные различия методов

Возможность text() html()
Работа с HTML Нет Да
Безопасный вывод Да Нет
Поддержка SVG Да Ограниченно
Высокая производительность Да Ниже
Подходит для шаблонов Нет Да
Автоэкранирование Да Нет