Арифметические и логические операторы

Vega и Vega-Lite используют встроенный язык выражений (expression language), который является ключевым механизмом для вычисления производных значений, фильтрации данных, управления визуальными параметрами и построения условной логики внутри спецификаций визуализаций.

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


Выражения применяются в нескольких ключевых местах:

  • трансформации данных (calculate, filter, joinaggregate, window)
  • условная логика в каналах кодирования (encoding.condition)
  • вычисляемые поля (calculate в Vega-Lite)
  • параметры масштабирования и визуальных атрибутов
  • сигналы (signals) в Vega

Базовая сущность выражения — это строка, интерпретируемая как формула:

{
  "type": "formula",
  "expr": "datum.value * 2 + 10"
}

или в Vega-Lite:

{
  "calculate": "datum.value * 2 + 10",
  "as": "computedValue"
}

Арифметические операторы

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

Основные операторы

Оператор Назначение
+ сложение
- вычитание
* умножение
/ деление
% остаток от деления
** возведение в степень

Примеры арифметических выражений

datum.price * datum.quantity
datum.value / 100
datum.x ** 2 + datum.y ** 2

Приоритет операций

Приоритет совпадает с математической моделью:

  1. **
  2. * / %
  3. + -

Пример:

datum.a + datum.b * datum.c

эквивалентно:

datum.a + (datum.b * datum.c)

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

{
  "calculate": "datum.price * datum.quantity",
  "as": "total"
}
{
  "calculate": "(datum.x - datum.mean) / datum.std",
  "as": "zscore"
}

Логические операторы

Логические операции используются для построения условий фильтрации и ветвления.

Основные операторы

Оператор Назначение
&& логическое И
| | логическое ИЛИ
! отрицание

Примеры логических выражений

datum.value > 10 && datum.value < 100
datum.category == "A" || datum.category == "B"
!(datum.hidden)

Приоритет логических операций

  1. !
  2. &&
  3. ||

Пример:

datum.a || datum.b && datum.c

эквивалентно:

datum.a || (datum.b && datum.c)

Операторы сравнения

Сравнения возвращают булевы значения и активно используются в фильтрации и условной логике.

Оператор Значение
== равенство
!= неравенство
< меньше
> больше
<= меньше или равно
>= больше или равно

Примеры

datum.value >= 0
datum.category != "unknown"
datum.score > datum.threshold

Условные выражения

В выражениях Vega отсутствует классический JavaScript if, но используется тернарный оператор и встроенная функция if.

Тернарный оператор

datum.value > 0 ? "positive" : "negative"

Вложенные условия

datum.value > 100 ? "high"
: datum.value > 50 ? "medium"
: "low"

Функция if

if(datum.value > 0, datum.value, 0)

Работа с null и неопределёнными значениями

coalesce

Функция coalesce выбирает первое ненулевое значение:

coalesce(datum.value, 0)

Проверка на null

datum.value != null

или

!isNaN(datum.value)

Использование в фильтрации

Фильтрация данных является одним из основных сценариев применения логических операторов.

Vega transform filter

{
  "type": "filter",
  "expr": "datum.value > 10 && datum.category == 'A'"
}

Vega-Lite filter transform

{
  "filter": "datum.value > 10 && datum.category == 'A'"
}

Сложные фильтры

{
  "filter": "(datum.value > 10 && datum.value < 50) || datum.priority == 'high'"
}

Условная логика в encoding

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

Условный цвет

{
  "mark": "circle",
  "encoding": {
    "color": {
      "condition": {
        "test": "datum.value > 0",
        "value": "green"
      },
      "value": "red"
    }
  }
}

Условный размер

{
  "size": {
    "condition": {
      "test": "datum.value > 100",
      "value": 200
    },
    "value": 50
  }
}

Комбинирование арифметики и логики

Одним из ключевых аспектов является объединение арифметических и логических выражений в единые формулы.

Пример нормализации с условием

datum.value > 0 ? datum.value / datum.max : 0

Пример пороговой функции

datum.value * (datum.value > threshold)

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


Расширенные выражения

Масштабирование и ограничение значений

min(max(datum.value, 0), 100)

Логика категорий

datum.score > 80 ? "A"
: datum.score > 50 ? "B"
: datum.score > 30 ? "C"
: "D"

Комбинирование нескольких условий

(datum.a > 10 && datum.b < 5) || (datum.c == "active" && datum.d >= 100)

Особенности интерпретации выражений

  • выражения выполняются в sandbox-окружении
  • доступ к данным осуществляется через datum
  • глобальные функции ограничены набором Vega expression API
  • строки должны использовать корректные кавычки
  • отсутствует прямой доступ к DOM или внешним API

Типичные ошибки использования операторов

Смешение типов

datum.value + "10"

результат — конкатенация строки вместо арифметики


Неправильная проверка null

datum.value == null

может не учитывать undefined в некоторых контекстах


Ошибки при приоритете

datum.a || datum.b && datum.c

без скобок поведение может быть неожиданным


Композиция выражений в сложных визуализациях

В сложных спецификациях выражения часто комбинируются:

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

Пример комбинированного вычисляемого поля:

{
  "calculate": "datum.value > 0 ? datum.value * 1.2 : datum.value * 0.8",
  "as": "adjusted"
}

Роль операторов в декларативной модели

Арифметические и логические операторы формируют основу выразительной системы Vega и Vega-Lite, позволяя описывать поведение визуализаций без императивного кода. В результате визуализация становится функцией данных, где трансформации и условия встроены непосредственно в спецификацию графика.