Поле condition: условное кодирование

Условное кодирование в Vega-Lite используется для динамического изменения визуальных свойств элементов графика в зависимости от данных, выражений или состояния взаимодействия. Поле condition является частью декларативной системы encoding и позволяет задавать альтернативные значения для одного визуального канала.

Основная идея заключается в разделении отображения на две ветви:

  • значение по умолчанию
  • значение при выполнении условия

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


Базовая структура condition

Обобщённая форма условного кодирования выглядит следующим образом:

{
  "encoding": {
    "color": {
      "condition": {
        "test": "datum.value > 10",
        "value": "red"
      },
      "value": "blue"
    }
  }
}

Здесь:

  • condition описывает правило
  • test задаёт логическое выражение
  • value определяет результат при истинности условия
  • внешний value работает как значение по умолчанию

Такая конструкция применяется ко всем каналам: color, size, shape, opacity, tooltip, stroke, fill и другим.


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

Наиболее прямолинейный вариант — использование выражений Vega Expression Language. Эти выражения работают в контексте datum.

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

{
  "mark": "point",
  "encoding": {
    "x": { "field": "x", "type": "quantitative" },
    "y": { "field": "y", "type": "quantitative" },
    "color": {
      "condition": {
        "test": "datum.y > 50",
        "value": "red"
      },
      "value": "steelblue"
    }
  }
}

Здесь все точки, у которых y > 50, окрашиваются в красный цвет, остальные — в синий.


Несколько условий и приоритеты

condition может быть массивом условий. В этом случае применяется первое совпавшее правило.

{
  "color": {
    "condition": [
      {
        "test": "datum.value > 80",
        "value": "red"
      },
      {
        "test": "datum.value > 50",
        "value": "orange"
      }
    ],
    "value": "green"
  }
}

Логика выполнения:

  1. проверяется первое условие
  2. если оно ложно — второе
  3. если ни одно не сработало — используется value по умолчанию

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


Условное кодирование на основе полей данных

Вместо выражений можно использовать сравнение через встроенные механизмы трансформации Vega-Lite:

{
  "color": {
    "condition": {
      "field": "category",
      "equal": "A",
      "value": "red"
    },
    "value": "gray"
  }
}

Поддерживаются операторы:

  • equal
  • range
  • lt, lte
  • gt, gte
  • oneOf

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

{
  "color": {
    "condition": {
      "field": "score",
      "range": [70, 100],
      "value": "green"
    },
    "value": "red"
  }
}

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


Условие на основе взаимодействия (selection)

Одно из наиболее мощных применений condition связано с интерактивными выделениями (selection). В этом случае визуальное состояние зависит от пользовательского действия.

{
  "selection": {
    "brush": {
      "type": "interval"
    }
  },
  "mark": "point",
  "encoding": {
    "color": {
      "condition": {
        "selection": "brush",
        "value": "orange"
      },
      "value": "lightgray"
    }
  }
}

Здесь элементы, попадающие в область выделения brush, получают альтернативный цвет.

Механизм selection-кондиций лежит в основе:

  • фильтрации по области
  • интерактивных дашбордов
  • выделения групп данных
  • связанных представлений (linked views)

Комбинация condition с другими каналами

condition не ограничен цветом. Он одинаково работает с любыми визуальными каналами.

Изменение размера

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

Изменение формы

{
  "shape": {
    "condition": {
      "test": "datum.type === 'critical'",
      "value": "triangle"
    },
    "value": "circle"
  }
}

Изменение прозрачности

{
  "opacity": {
    "condition": {
      "test": "datum.hidden === true",
      "value": 0.2
    },
    "value": 1
  }
}

Вложенные условия и сложные логические выражения

Для более сложной логики используются выражения Vega Expression Language:

{
  "color": {
    "condition": {
      "test": "datum.a > 10 && datum.b < 5",
      "value": "purple"
    },
    "value": "steelblue"
  }
}

Допускается использование функций:

{
  "test": "isValid(datum.value) && datum.value > mean"
}

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


condition в контексте слоя (layered charts)

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

{
  "layer": [
    {
      "mark": "point",
      "encoding": {
        "color": {
          "condition": {
            "test": "datum.group === 'A'",
            "value": "red"
          },
          "value": "gray"
        }
      }
    }
  ]
}

В этом случае один слой визуально разделяет группы данных без необходимости создания отдельных наборов данных.


Поведение по умолчанию и приоритет вычислений

При интерпретации condition действует строгий порядок:

  1. Проверка условий (test, field, selection)
  2. Выбор первого истинного условия (если массив)
  3. Применение value условия
  4. Применение внешнего значения канала

Важно, что condition полностью перекрывает стандартное значение канала при срабатывании.


Отличие condition в Vega-Lite и Vega

В Vega-Lite condition является декларативной абстракцией, которая компилируется в более низкоуровневые конструкции Vega.

В Vega (низкоуровневом языке) аналогичное поведение реализуется через:

  • signal-выражения
  • if-then-else конструкции в encode
  • predicates (test)

Пример Vega-уровня:

{
  "encode": {
    "update": {
      "fill": {
        "signal": "datum.value > 10 ? 'red' : 'blue'"
      }
    }
  }
}

Vega-Lite скрывает эту сложность, предоставляя единый condition.


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

Распространённые проблемы связаны не с синтаксисом, а с логикой:

  • отсутствие fallback value, приводящее к неопределённому отображению
  • слишком сложные выражения в test, ухудшающие читаемость
  • конфликт нескольких каналов, где разные condition перекрывают друг друга
  • попытка использовать condition вместо агрегации или трансформаций

Особенно важно учитывать, что condition работает на уровне визуализации, а не на уровне структуры данных.


Практическая роль условного кодирования

Условное кодирование формирует основу адаптивных визуализаций, где один и тот же график может одновременно:

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

За счёт этого Vega-Lite позволяет строить выразительные визуализации без перехода к императивной логике или ручной отрисовке элементов.