Атрибуты заливки, обводки и прозрачности

Атрибут fill в SVG определяет внутреннюю окраску геометрических примитивов: окружностей, прямоугольников, путей и полигонов. В D3.js управление этим атрибутом осуществляется через метод .attr() или через стили .style(), однако семантически fill относится к SVG-атрибутам.

Базовое назначение:

d3.select("circle")
  .attr("fill", "steelblue");

Значение fill принимает любые допустимые CSS-цвета: именованные цвета, HEX, RGB, HSL:

.attr("fill", "#ffcc00")
.attr("fill", "rgb(255, 0, 0)")
.attr("fill", "hsl(120, 50%, 50%)")

В контексте работы с данными fill часто становится динамическим атрибутом:

d3.selectAll("rect")
  .attr("fill", d => d.value > 10 ? "green" : "red");

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

Приоритет между fill как атрибутом и CSS-правилами зависит от способа задания. Если цвет задаётся через .style("fill", ...), он становится CSS-стилем и может переопределять атрибут в зависимости от специфичности.


stroke (обводка)

Атрибут stroke определяет цвет контура SVG-элемента. Визуально он задаёт границу фигуры, которая может быть как тонкой линией, так и сложной стилизованной обводкой.

d3.select("circle")
  .attr("stroke", "black");

В отличие от fill, обводка существует независимо от внутреннего заполнения. Часто используется комбинация:

.attr("fill", "lightblue")
.attr("stroke", "darkblue");

Толщина обводки

Параметр stroke-width определяет толщину линии:

.attr("stroke-width", 3);

При работе с масштабируемой визуализацией значение часто вычисляется динамически:

.attr("stroke-width", d => d.weight * 2);

Стилизация концов и соединений

stroke-linecap управляет формой концов линий:

  • butt — обрезанный край
  • round — округлый край
  • square — выступающий квадрат
.attr("stroke-linecap", "round");

stroke-linejoin задаёт поведение в местах соединения сегментов:

  • miter — острый угол
  • round — скругление
  • bevel — срез
.attr("stroke-linejoin", "round");

Пунктирные линии

stroke-dasharray позволяет создавать пунктирную обводку:

.attr("stroke-dasharray", "5,5");

Чередование чисел задаёт длину штриха и пробела. Более сложные паттерны:

.attr("stroke-dasharray", "10,2,2,2");

opacity (прозрачность)

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

d3.select("circle")
  .attr("opacity", 0.5);

Значения находятся в диапазоне от 0 (полная прозрачность) до 1 (полная непрозрачность).

Раздельная прозрачность

SVG поддерживает независимую настройку прозрачности заливки и обводки:

  • fill-opacity
  • stroke-opacity
.attr("fill-opacity", 0.3)
.attr("stroke-opacity", 0.8);

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


Комбинирование заливки, обводки и прозрачности

При совместном использовании параметров формируется многослойная визуальная модель:

d3.selectAll("rect")
  .attr("fill", "orange")
  .attr("stroke", "black")
  .attr("stroke-width", 2)
  .attr("opacity", 0.9)
  .attr("fill-opacity", 0.6);

В этой модели различаются уровни воздействия:

  • fill отвечает за внутренний цвет
  • stroke задаёт контур
  • opacity влияет на весь элемент
  • fill-opacity и stroke-opacity разделяют прозрачность слоёв

Функциональное задание стилей на основе данных

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

d3.selectAll("circle")
  .attr("fill", d => d.active ? "green" : "gray")
  .attr("stroke", d => d.value > 50 ? "black" : "none")
  .attr("opacity", d => Math.max(0.2, d.score / 100));

Такой подход обеспечивает прямую трансформацию данных в визуальные характеристики без промежуточных вычислительных слоёв.


Взаимодействие с переходами (transitions)

Атрибуты заливки и обводки активно участвуют в анимациях:

d3.select("circle")
  .transition()
  .duration(800)
  .attr("fill", "tomato")
  .attr("stroke-width", 6)
  .attr("opacity", 0.7);

Изменение визуальных характеристик через переходы позволяет формировать плавные трансформации состояния объектов.


Особенности интерпретации значений

SVG-рендеринг интерпретирует отсутствие атрибутов по умолчанию:

  • отсутствие fill часто трактуется как black (в зависимости от браузера и контекста)
  • stroke по умолчанию отсутствует (none)
  • opacity по умолчанию равен 1

Удаление атрибута через D3:

d3.select("circle")
  .attr("fill", null);

Такой вызов может привести к возврату к стилям по умолчанию или CSS-наследованию.


Работа с градиентами и заливками сложной природы

Атрибут fill может ссылаться на SVG-градиенты и паттерны:

.attr("fill", "url(#gradient)")

Градиенты определяются в <defs> и становятся частью визуальной системы, где fill выступает как ссылка на ресурс, а не как цветовое значение.


Приоритеты и конфликт стилей

В случае одновременного использования CSS и атрибутов SVG возникает конкуренция:

  • .attr("fill", ...) задаёт SVG-атрибут
  • .style("fill", ...) задаёт CSS-правило

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


Наследование и группировка элементов

SVG-группы <g> позволяют задавать общие стили:

d3.select("g")
  .attr("fill", "steelblue")
  .attr("stroke", "black");

Все вложенные элементы наследуют параметры, если они не переопределены локально. Это уменьшает дублирование и позволяет управлять визуальной структурой на уровне контейнеров.


Влияние opacity на взаимодействие слоёв

opacity изменяет не только визуальное восприятие, но и композитинг слоёв. Полупрозрачные элементы начинают смешиваться с фоном и другими объектами, что влияет на читаемость плотных диаграмм:

.attr("opacity", 0.2)

При построении графиков с большим количеством перекрытий часто используется разделение:

  • слабая прозрачность для фоновых элементов
  • высокая прозрачность для активных или выделенных объектов

Практика комбинирования визуальных параметров

Сложные визуализации используют согласованную систему:

d3.selectAll("path")
  .attr("fill", "none")
  .attr("stroke", d => d.color)
  .attr("stroke-width", d => d.width)
  .attr("stroke-opacity", 0.8);

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