В многовидовых визуализациях Vega-Lite выделения
(selection) могут использоваться одновременно в нескольких
графиках. По умолчанию механизм выделения пытается синхронизировать
состояние между всеми представлениями (views), однако при
сложной композиции — layer, concat,
repeat, facet — возникает необходимость явно
управлять тем, как именно выделение объединяется между графиками.
Поле resolve определяет стратегию согласования
(resolution strategy) выделений в многовидовых
представлениях.
Наиболее часто resolve применяется:
repeat;facet;concat и vconcat;Поле задаётся внутри определения выделения:
selection: {
brush: {
type: "interval",
resolve: "global"
}
}
Либо в новой системе параметров:
params: [
{
name: "brush",
select: {
type: "interval",
resolve: "global"
}
}
]
resolveДля многовидовых выделений доступны три стратегии:
| Значение | Назначение |
|---|---|
global |
Одно общее выделение для всех представлений |
union |
Объединение выделений из всех представлений |
intersect |
Пересечение выделений между представлениями |
globalglobal создаёт единое состояние выделения для всех
графиков.
Когда пользователь создаёт новое выделение в одном представлении:
repeat{
data: {
url: "data/cars.json"
},
repeat: ["Horsepower", "Acceleration", "Miles_per_Gallon"],
spec: {
width: 200,
height: 200,
mark: "point",
params: [
{
name: "brush",
select: {
type: "interval",
resolve: "global"
}
}
],
encoding: {
x: {
field: { repeat: "repeat" },
type: "quantitative"
},
y: {
field: "Weight_in_lbs",
type: "quantitative"
},
color: {
condition: {
param: "brush",
value: "steelblue"
},
value: "lightgray"
}
}
}
}
Если выделение создаётся:
global подходит для:
Все представления используют один объект выделения.
Это означает:
View A -> Selection State
View B -> Selection State
View C -> Selection State
Состояние физически одно.
Так как хранится только одно состояние выделения:
При большом количестве представлений возможны проблемы UX:
unionunion объединяет выделения из всех представлений.
Каждый график хранит собственное локальное выделение, а итоговый
результат вычисляется как логическое ИЛИ (OR).
Selection A
OR
Selection B
OR
Selection C
{
data: {
url: "data/cars.json"
},
repeat: {
column: ["Horsepower", "Acceleration", "Miles_per_Gallon"]
},
spec: {
width: 180,
height: 180,
mark: "point",
params: [
{
name: "brush",
select: {
type: "interval",
resolve: "union"
}
}
],
encoding: {
x: {
field: { repeat: "column" },
type: "quantitative"
},
y: {
field: "Weight_in_lbs",
type: "quantitative"
},
color: {
condition: {
param: "brush",
value: "firebrick"
},
value: "#ddd"
}
}
}
}
Пользователь может:
Все выделения сохраняются одновременно.
Точка считается выбранной, если она попадает хотя бы в одно выделение.
Пусть имеются три диапазона:
A = Horsepower ∈ [100, 150]
B = Acceleration ∈ [10, 15]
C = MPG ∈ [20, 30]
При union запись будет выбрана, если выполняется хотя бы
одно условие:
A OR B OR C
Позволяет накапливать несколько независимых выделений.
Можно выделять разные диапазоны на разных графиках и анализировать совокупный результат.
Подходит для интерфейсов, где пользователь постепенно расширяет область анализа.
Vega-Lite создаёт:
Условно:
brush_0 OR brush_1 OR brush_2
При большом числе представлений:
Пользователь может забыть о ранее созданных выделениях.
Иногда интерфейс визуально не показывает:
intersectintersect выбирает только те записи, которые
удовлетворяют всем выделениям одновременно.
Используется логическое И (AND).
Selection A
AND
Selection B
AND
Selection C
{
data: {
url: "data/cars.json"
},
repeat: {
column: [
"Horsepower",
"Acceleration",
"Miles_per_Gallon"
]
},
spec: {
width: 180,
height: 180,
mark: "point",
params: [
{
name: "brush",
select: {
type: "interval",
resolve: "intersect"
}
}
],
encoding: {
x: {
field: {
repeat: "column"
},
type: "quantitative"
},
y: {
field: "Weight_in_lbs",
type: "quantitative"
},
color: {
condition: {
param: "brush",
value: "green"
},
value: "#ddd"
}
}
}
}
Точка выделяется только если:
A AND B AND C
Допустим:
Horsepower ∈ [120, 180]
Acceleration ∈ [12, 14]
MPG ∈ [25, 35]
Тогда запись должна удовлетворять всем трём условиям одновременно.
Особенно полезен при exploratory data analysis.
Пользователь постепенно сужает выборку:
Шаг 1 -> широкий диапазон
Шаг 2 -> уточнение
Шаг 3 -> финальная фильтрация
intersect позволяет быстро уменьшать объём отображаемых
данных.
При слишком жёстких пересечениях пользователь может получить пустой результат.
Не все пользователи ожидают поведение AND.
Часто требуется:
| Режим | Логика | Количество выделений | Тип поведения |
|---|---|---|---|
global |
одно общее | 1 | замещение |
union |
OR | много | накопление |
intersect |
AND | много | пересечение |
Поле resolve напрямую влияет на predicate, который
Vega-Lite генерирует внутри фильтров.
globalpredicate(brush)
unionpredicate(brush_0)
OR
predicate(brush_1)
OR
predicate(brush_2)
intersectpredicate(brush_0)
AND
predicate(brush_1)
AND
predicate(brush_2)
transform.filtertransform: [
{
filter: {
param: "brush"
}
}
]
Поведение фильтра полностью зависит от resolve.
unionФильтр пропускает записи, попадающие хотя бы в одно выделение.
intersectФильтр пропускает только записи, удовлетворяющие всем selection одновременно.
facetПри использовании facet каждый facet становится
отдельным view.
Следовательно:
resolve начинает играть ключевую роль.{
facet: {
field: "Origin",
type: "nominal"
},
spec: {
params: [
{
name: "brush",
sel ect: {
type: "interval",
resolve: "union"
}
}
],
mark: "point",
encoding: {
x: {
field: "Horsepower",
type: "quantitative"
},
y: {
field: "Miles_per_Gallon",
type: "quantitative"
},
color: {
condition: {
param: "brush",
value: "orange"
},
value: "lightgray"
}
}
}
}
repeatrepeat — наиболее распространённый сценарий
использования resolve.
Причина:
Scatter Plot Matrix:
HP vs MPG
HP vs Weight
MPG vs Weight
Acceleration vs MPG
...
Здесь resolve определяет:
Поддерживается полностью.
Наиболее частый сценарий.
Также поддерживает resolve.
Пример:
params: [
{
name: "pts",
select: {
type: "point",
resolve: "union"
}
}
]
В старом API (selection) параметр также
поддерживался:
selection: {
pts: {
type: "multi",
resolve: "intersect"
}
}
globalНаиболее дешёвый режим.
Причины:
unionСредняя нагрузка.
Рост сложности линейно зависит от количества views.
intersectОбычно самый тяжёлый режим.
Особенно при:
При компиляции Vega-Lite создаёт:
brush_store
brush_tuple
brush_modify
Для multi-view layouts появляются дополнительные структуры:
brush_0
brush_1
brush_2
А resolve определяет механизм их композиции.
globalОчистка удаляет единственное состояние.
unionУдаляется только локальное выделение текущего view.
Остальные продолжают действовать.
intersectУдаление одного selection может резко расширить итоговую выборку,
поскольку исчезает одно из условий AND.
resolve: {
scale: {
x: "independent",
y: "independent"
}
}
Не следует путать:
resolve для scale;resolve для selection.Это разные механизмы.
При независимых шкалах interval selection может выглядеть одинаково визуально, но соответствовать разным диапазонам данных.
resolve.scale и selection.resolveЧастая ошибка:
resolve: "union"
на верхнем уровне spec.
Правильно:
select: {
type: "interval",
resolve: "union"
}
global при аналитикеglobal плохо подходит для:
intersectМожет приводить к:
globalПодходит для:
unionПодходит для:
intersectПодходит для:
Поле resolve существует потому, что Vega-Lite использует
декларативную модель.
Каждое view:
resolve выступает механизмом композиции этих
состояний.
В Vega:
В Vega-Lite:
resolve скрывает сложность;Для анализа selection-state удобно использовать:
brush
brush_tuple
brush_store
brush_store
Проверка скомпилированного Vega-кода помогает понять:
resolve.