Поле direction

В спецификациях Vega и Vega-Lite поле direction отвечает за направление письма текста в текстовых примитивах (text marks), включая подписи, метки осей и произвольные текстовые аннотации. Оно критически важно для корректного отображения языков с письмом справа налево и для смешанных многоязычных визуализаций.


Семантика поля direction

direction задаёт порядок визуального чтения текста и влияет на то, как браузер и SVG-рендерер интерпретируют строку символов внутри текстового объекта.

Основные значения:

  • “ltr” — left-to-right, слева направо (по умолчанию для латиницы)
  • “rtl” — right-to-left, справа налево (арабский, иврит)
  • “inherit” — наследование направления из окружения или конфигурации

Ключевой момент: direction не меняет сами символы, он управляет только их визуальной компоновкой.


Место direction в модели Vega

В Vega поле direction применяется в блоке mark, когда используется тип text.

Пример базовой структуры:

{
  "type": "text",
  "encode": {
    "enter": {
      "x": { "value": 100 },
      "y": { "value": 50 },
      "text": { "value": "שלום" },
      "direction": { "value": "rtl" }
    }
  }
}

В этом случае текст будет отрисован справа налево, что соответствует семантике ивритского слова.


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

В Vega-Lite поле direction чаще всего применяется через:

  • mark
  • encoding
  • config

Прямое задание встречается реже, поскольку Vega-Lite абстрагирует низкоуровневые свойства Vega.

Пример:

{
  "data": { "values": [
    { "x": 1, "y": 10, "label": "مرحبا" }
  ]},
  "mark": {
    "type": "text",
    "direction": "rtl"
  },
  "encoding": {
    "x": { "field": "x", "type": "quantitative" },
    "y": { "field": "y", "type": "quantitative" },
    "text": { "field": "label" }
  }
}

Здесь direction применяется ко всем текстовым элементам mark, если не переопределено на уровне encode.


Поведение при смешанных языках

При смешанном содержимом (например, латиница + арабский текст) направление играет роль только на уровне строки:

  • Vega не выполняет интеллектуальную сегментацию текста
  • direction задаёт общий режим для всего текстового узла
  • сложные случаи с bidirectional text обрабатываются браузером (Unicode BiDi алгоритм)

Ключевая особенность: direction влияет на базовую ориентацию, но не заменяет Unicode-алгоритм двунаправленного текста.


Взаимодействие с align и baseline

Поле direction тесно связано с параметрами позиционирования текста:

  • align — горизонтальное выравнивание (left, right, center)
  • baseline — вертикальное выравнивание (top, middle, bottom, alphabetic)
  • direction — логика направления строки

Комбинации дают разные визуальные эффекты:

LTR + align: “left”

Текст начинается слева и выравнивается по левому краю.

RTL + align: “left”

Логически текст идёт справа налево, но якорная точка остаётся слева, что может создавать визуально неожиданные смещения.

RTL + align: “right”

Наиболее естественная комбинация для арабских и ивритских подписей.


Наследование и конфигурация

В Vega-Lite и Vega можно задавать направление глобально через конфигурацию:

{
  "config": {
    "text": {
      "direction": "rtl"
    }
  }
}

Механика наследования:

  1. config.text.direction
  2. mark.direction
  3. encode.enter.direction
  4. значение по умолчанию (ltr)

Важно: локальные значения всегда переопределяют глобальные настройки.


Применение в осях и подписях

В Vega-Lite направление текста часто критично для:

  • подписей осей (axis labels)
  • заголовков
  • легенд

Пример:

{
  "mark": "bar",
  "encoding": {
    "x": {
      "field": "category",
      "type": "nominal",
      "axis": {
        "labelAngle": 0,
        "labelExpr": "datum.label",
        "labelDir": "rtl"
      }
    },
    "y": { "field": "value", "type": "quantitative" }
  }
}

Хотя Vega-Lite не всегда экспонирует прямое поле direction в axis, оно транслируется в Vega через текстовые элементы.


Рендеринг и техническая реализация

На уровне Vega runtime:

  • direction передаётся в SVG text element
  • интерпретируется браузером через direction CSS/SVG свойство
  • влияет на text-anchor в связке с align

В Canvas-рендерере поведение может отличаться:

  • direction частично эмулируется
  • BiDi алгоритмы зависят от реализации движка

Типичные сценарии использования

Арабские и ивритские диаграммы

{
  "mark": "text",
  "encoding": {
    "text": { "field": "label" }
  },
  "config": {
    "text": {
      "direction": "rtl",
      "align": "right"
    }
  }
}

Смешанные подписи (английский + арабский)

{
  "mark": {
    "type": "text",
    "direction": "inherit"
  }
}

Использование inherit позволяет браузеру применять Unicode BiDi-алгоритм без принудительного переопределения логики.


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

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

Взаимодействие с другими свойствами text mark

Поле direction часто рассматривается в связке с:

  • angle — поворот текста
  • limit — обрезка текста
  • dx / dy — смещение
  • fontSize — плотность текста

Комбинация direction + angle особенно чувствительна:

  • rotation применяется после определения направления
  • визуальная логика может меняться в зависимости от порядка трансформаций

Отличия Vega и Vega-Lite в обработке direction

Аспект Vega Vega-Lite
Уровень контроля низкоуровневый абстрагированный
Прямое задание всегда доступно частично делегировано
Наследование явное через config через config + трансляцию
axis labels ручная настройка автоматическая генерация

Vega предоставляет полный контроль над direction на уровне каждого text mark, тогда как Vega-Lite чаще использует его как конфигурационный параметр.


Поведение при отсутствии direction

Если поле direction не задано:

  • используется значение “ltr”
  • применяется браузерное направление по умолчанию
  • BiDi алгоритм работает без вмешательства Vega

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