Интеграция с D3.js для визуализации данных

Stimulus — это легковесный JavaScript-фреймворк, ориентированный на организацию поведения интерфейсов через декларативные контроллеры. D3.js обеспечивает мощные возможности для визуализации данных, предоставляя инструменты для работы с DOM и SVG на основе данных. Объединение этих двух технологий позволяет создавать интерактивные, динамически обновляемые визуализации, управляемые через Stimulus-контроллеры.

Подключение библиотек

Для работы необходимы следующие зависимости:

<script src="https://unpkg.com/stimulus/dist/stimulus.umd.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>

Stimulus регистрируется через Application.start():

const application = Stimulus.Application.start();

Создание контроллера Stimulus

Контроллер отвечает за инициализацию визуализации и обновление данных:

application.register("chart", class extends Stimulus.Controller {
  static values = { data: Array };

  connect() {
    this.createChart();
  }

  createChart() {
    const width = 500;
    const height = 300;

    this.svg = d3.select(this.element)
      .append("svg")
      .attr("width", width)
      .attr("height", height);

    this.updateChart();
  }

  updateChart() {
    if (!this.dataValue) return;

    const xScale = d3.scaleBand()
      .domain(this.dataValue.map((d, i) => i))
      .range([0, 500])
      .padding(0.1);

    const yScale = d3.scaleLinear()
      .domain([0, d3.max(this.dataValue)])
      .range([300, 0]);

    const bars = this.svg.selectAll("rect")
      .data(this.dataValue);

    bars.enter()
      .append("rect")
      .merge(bars)
      .attr("x", (d, i) => xScale(i))
      .attr("y", d => yScale(d))
      .attr("width", xScale.bandwidth())
      .attr("height", d => 300 - yScale(d))
      .attr("fill", "steelblue");

    bars.exit().remove();
  }

  dataValueChanged() {
    this.updateChart();
  }
});

Работа с динамическими данными

Stimulus обеспечивает реактивное обновление визуализации через dataValueChanged и связывание значений:

<div data-controller="chart" data-chart-data-value="[10, 20, 30, 40]"></div>

Изменение атрибута data-chart-data-value автоматически вызовет обновление графика.

Добавление интерактивности

D3.js позволяет добавлять события, а Stimulus упрощает их организацию через методы контроллера:

this.svg.selectAll("rect")
  .on("mouseover", (event, d) => {
    d3.select(event.currentTarget)
      .attr("fill", "orange");
  })
  .on("mouseout", (event, d) => {
    d3.select(event.currentTarget)
      .attr("fill", "steelblue");
  });

Stimulus помогает централизованно управлять поведением элементов, обеспечивая чистоту кода и повторное использование.

Анимация и переходы

D3.js поддерживает плавные переходы для обновления визуализаций:

this.svg.selectAll("rect")
  .data(this.dataValue)
  .join("rect")
  .transition()
  .duration(750)
  .attr("y", d => yScale(d))
  .attr("height", d => 300 - yScale(d));

Stimulus позволяет запускать анимации при изменении данных или событиях DOM, сохраняя реактивность интерфейса.

Многоуровневые визуализации

Для сложных графиков, например, линейных диаграмм с несколькими сериями, можно создавать несколько svg или группировать элементы через g:

const group = this.svg.append("g")
  .attr("transform", "translate(50,50)");

group.selectAll("line")
  .data(this.dataValue)
  .enter()
  .append("line")
  .attr("x1", (d,i) => i * 50)
  .attr("y1", 300)
  .attr("x2", (d,i) => i * 50)
  .attr("y2", d => 300 - d)
  .attr("stroke", "black");

Stimulus обеспечивает централизованное управление, позволяя обновлять сложные графики через единый контроллер.

Резюме

Использование Stimulus с D3.js дает преимущества:

  • Структурированное управление поведением DOM.
  • Реактивное обновление визуализаций при изменении данных.
  • Удобное разделение логики визуализации и логики взаимодействия.
  • Поддержка анимаций и интерактивности без дублирования кода.

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