Канал strokeDash

Канал strokeDash отвечает за управление пунктирной (штриховой) структурой линии в графических примитивах. Он определяет последовательность длин сегментов «линия–пробел», задавая визуальный ритм контура геометрических объектов. В терминах грамматики визуализации Vega и Vega-Lite этот канал относится к визуальным encoding channels и применяется для масштабируемого управления стилем линий в зависимости от данных.


Семантика strokeDash

strokeDash задаётся как массив чисел:

strokeDash: [dashLength, gapLength, dashLength, gapLength, ...]

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

Базовые свойства:

  • чётные элементы массива — длины штрихов
  • нечётные элементы — длины промежутков
  • пустой массив или отсутствие канала — сплошная линия
  • длины могут быть дробными значениями
  • поведение зависит от масштаба визуализации, но сохраняет пропорции

Модель применения в Vega

В Vega strokeDash используется внутри описания marks:

{
  "type": "line",
  "encode": {
    "update": {
      "stroke": { "value": "steelblue" },
      "strokeWidth": { "value": 2 },
      "strokeDash": { "value": [6, 3] }
    }
  }
}

Здесь линия рисуется с повторяющимся паттерном:

  • 6 пикселей линия
  • 3 пикселя пропуск

Динамическое управление через данные

strokeDash может быть связан с полями данных:

"strokeDash": {
  "field": "dashPattern"
}

Где dashPattern может содержать массивы:

[
  { "category": "A", "dashPattern": [1, 0] },
  { "category": "B", "dashPattern": [5, 2] },
  { "category": "C", "dashPattern": [10, 4] }
]

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


Использование в Vega-Lite

В Vega-Lite strokeDash применяется в секции encoding.

Базовый пример

{
  "mark": "line",
  "encoding": {
    "x": { "field": "x", "type": "quantitative" },
    "y": { "field": "y", "type": "quantitative" },
    "strokeDash": { "field": "category", "type": "nominal" }
  }
}

Однако прямое использование категориального поля требует трансформации через scale или condition, поскольку strokeDash ожидает числовой массив.


Преобразование категорий в паттерны

Типичный подход — явное сопоставление значений:

"strokeDash": {
  "condition": [
    { "test": "datum.category === 'A'", "value": [1, 0] },
    { "test": "datum.category === 'B'", "value": [6, 2] },
    { "test": "datum.category === 'C'", "value": [2, 2] }
  ],
  "value": [0]
}

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


Поведение в сочетании с strokeWidth и strokeOpacity

strokeDash часто используется вместе с другими каналами:

strokeWidth

Толщина линии усиливает или ослабляет восприятие паттерна:

"strokeWidth": { "value": 3 },
"strokeDash": { "value": [8, 4] }

Толстые линии с длинными штрихами читаются стабильнее на сложных графиках.

strokeOpacity

Прозрачность влияет на визуальную «плотность» паттерна:

"strokeOpacity": { "value": 0.6 },
"strokeDash": { "value": [4, 2] }

Геометрическая интерпретация

Механизм strokeDash реализуется как параметризация кривой по длине дуги:

  • линия разбивается на сегменты
  • текущая позиция t ∈ [0, L]
  • применяется циклический шаблон dashArray
  • рисуются только активные сегменты

Формально:

pattern(t) = dashArray[t mod sum(dashArray)]

Где чередование определяется суммой элементов массива.


Сигналы и реактивное управление

В Vega возможно управление через signals:

"signals": [
  {
    "name": "dash",
    "value": [4, 2]
  }
]

И применение:

"strokeDash": { "signal": "dash" }

Это позволяет динамически изменять стиль линии без перерасчёта данных.


Типовые паттерны strokeDash

Сплошная линия

[]

или отсутствие свойства.


Классический пунктир

[5, 5]

Длинный штрих

[12, 6]

Точка-тире (морзеподобный стиль)

[2, 2, 8, 2]

Плотный технический стиль

[1, 1]

Применение в многосерийных графиках

При визуализации нескольких линий strokeDash заменяет или дополняет цветовое кодирование:

"encoding": {
  "color": { "field": "series" },
  "strokeDash": { "field": "series" }
}

Такой подход особенно важен при:

  • печати в grayscale
  • дальтонических палитрах
  • ограниченной цветовой гамме

Ограничения и особенности рендеринга

  • слишком короткие паттерны визуально сливаются при масштабировании
  • длинные массивы увеличивают стоимость отрисовки
  • при анимации возможны фазовые сдвиги паттерна
  • SVG и Canvas могут по-разному интерпретировать субпиксельные значения

Масштабирование и трансформации

При применении scale, zoom и pan:

  • абсолютная длина dash пересчитывается в экранные пиксели
  • визуальная структура сохраняется, но может «сжиматься»
  • при сильном зуме мелкие паттерны становятся сплошными

Использование в сложных композициях

В сложных визуализациях strokeDash комбинируется с:

  • interpolate (тип линии)
  • curve (сглаживание)
  • defined (разрыв линии по условию)
  • fill (для замкнутых контуров)

Это позволяет формировать гибридные визуальные коды, где форма линии несёт дополнительную информационную нагрузку.


Информационная нагрузка канала

strokeDash относится к ретинальным каналам восприятия, влияющим на:

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

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