Версия: 1.3
Перекрёстная фильтрация (выбор)
Можно включить перекрёстную фильтрацию других визуалов при щелчке по примитиву, объект datum которого удаётся сопоставить с исходными данными. Щелчок с удержанием Ctrl позволяет выбрать несколько точек.
В отличие от подсказок и контекстного меню, перекрёстная фильтрация требует особого подхода. По умолчанию она выключена, чтобы визуал не создавал проблем при взаимодействии, пока в нём не настроены эффекты для состояния выбора. Здесь рассмотрим, что нужно учесть при её включении и реализации спецификации.
Как работает перекрёстная фильтрация
Vega управляет интерактивностью через сигналы и события, а Vega-Lite — через параметры. Однако нужно также учитывать, как Power BI поддерживает состояние выбора между визуалами, и обеспечить универсальный способ взаимодействия. Deneb связывает эти механизмы следующим образом:
Настройка Cross-Filtering (Selection) of Data Points в разделе Vega → Power BI Interactivity панели Settings редактора визуала определяет, должен ли Deneb пытаться сопоставлять точки данных при щелчке по примитивам.
По умолчанию настройка выключена.
Для каждой строки
"dataset"Deneb создаёт специальное поле"__selected__". Его значение обновляется при щелчках и подходящих внешних событиях — например, восстановлении закладки с активным состоянием выбора.При выборе нескольких точек с удержанием Ctrl Deneb добавляет их в текущий список и обновляет значения
__selected__.Щелчок по полотну вне примитива либо по примитиву, который нельзя сопоставить с одной или несколькими точками данных, очищает текущий выбор. Deneb также просит Power BI сбросить соответствующий выбор в других визуалах страницы.
Автор должен использовать поле состояния для настройки визуальных эффектов, различающих выбранные и невыбранные примитивы. Простой вариант показан в практическом примере, а другие подходы рассмотрены ниже.
Определение точки данных
Если Cross-Filtering (Selection) of Data Points включена, Deneb отслеживает щелчки по примитивам. Если примитив представляет datum непреобразованной строки "dataset" или содержит достаточно информации для сопоставления, его точка данных добавляется в список выбранных. Затем Power BI получает запрос на обработку других визуалов страницы:

При удержании Ctrl щелчки по другим примитивам с сопоставимыми точками данных добавляют их в текущий список и обновляют остальные визуалы:

Простое сопоставление агрегированных данных
Для примитивов и слоёв с простым агрегированием Deneb может попытаться найти составляющие точки данных по уникальным значениям полей группировки. Это бывает полезно, но имеет несколько особенностей:
- В новом потоке данных столбцы и меры должны иметь те же имена, что и соответствующие исходные поля, из которых они получены.
- Фильтры и дополнительные преобразования, удаляющие составляющие строки, при сопоставлении не учитываются.
- Новый поток имеет другую детализацию и, следовательно, другой контекст строки относительно базового
"dataset". Поэтому в нём нет соответствующего поля__selected__для управления состоянием выбора. Однако можно создать впечатление выбора на более высоком уровне детализации; пример приведён ниже.
Ограничение числа точек данных
Большой выбор увеличивает объём работы Power BI по поддержанию состояния всех визуалов страницы и может снизить производительность. Vega и Vega-Lite позволяют создавать очень разные визуалы, поэтому количество точек, передаваемых Power BI, ограничено. Их число может быстро вырасти, если исходные данные имеют высокую детализацию, а выбранный примитив объединяет много строк.
При включённой перекрёстной фильтрации в панели настроек доступно свойство Data Point Limit:

По умолчанию предел равен 50. Его можно установить в диапазоне от 1 до 250.
Когда число выбранных точек достигает предела, в заголовке визуала появляется предупреждение:

Текущий выбор остаётся активным, но новые строки в него не добавляются.
Закрыть предупреждение можно одним из способов:
- Нажать значок закрытия, сохранив текущий выбор.
- Щёлкнуть по другому примитиву, начав новый выбор, если точку можно сопоставить.
- Щёлкнуть в другом месте полотна, очистив текущий выбор.
Поле __selected__
Deneb поддерживает следующие значения поля для каждой строки набора данных:
on— в визуале есть активный выбор, и строка входит в список выбранных точек.off— в визуале есть активный выбор, и строка не входит в список выбранных точек.neutral— активного выбора нет, и точку следует отображать обычным образом.
Дополнительные примеры использования состояний приведены ниже.
Отображение состояния выбора через кодирование
Чтобы перекрёстная фильтрация была понятна пользователям, используйте __selected__ каждой строки в кодировании примитивов. Визуал должен ясно различать выбранные и невыбранные точки. Начните с подхода, привычного по другим визуалам Power BI: например, меняйте непрозрачность затронутых примитивов. Языки Vega позволяют исследовать и другие варианты.
Раздел «Простые практические примеры» поможет начать. Примеры используют Vega-Lite, но обе версии шаблона Simple Bar Chart из диалога New Specification содержат простые правила перекрёстной фильтрации.
Ограничения и особенности
- Сопоставление данных с Power BI полностью зависит от правильного контекста строки. Подробнее о его сохранении см. выше и в обзоре.
- При агрегировании иногда можно имитировать эффект выбора, но для этого требуется нестандартный подход. Пример 3 показывает один из вариантов.
Простые практические примеры
Примеры используют Vega-Lite, но аналогичные принципы применимы и к Vega.
Во встроенном отчёте показаны три примера в Power BI. Модель основана на демонстрационных финансовых данных Power BI Desktop. Подсказки раскрывают все данные, чтобы вы могли наблюдать значение __selected__. Добавлены и примитивы, явно показывающие его изменение при взаимодействии. Базовые JSON-спецификации приведены под отчётом.
Пример 1. Условное кодирование непрозрачности
Как в практическом примере и встроенных шаблонах столбчатой диаграммы, можно задавать opacity в зависимости от того, равно ли __selected__ значению "off":
{
"data": { "name": "dataset" },
"mark": {
"type": "bar",
"tooltip": true
},
"encoding": {
"y": {
"field": "Country (Short)",
"type": "nominal"
},
"x": {
"field": "$ Sales",
"type": "quantitative"
},
"opacity": {
"condition": {
"test": {
"field": "__selected__",
"equal": "off"
},
"value": 0.3
},
"value": 1
}
}
}
Пример 2. Разное оформление выбранных и обычных примитивов
При необходимости предыдущий пример можно расширить: оформить явно выбранные примитивы с __selected__: "on" иначе, чем примитивы в обычном состоянии neutral. В следующем коде узорная заливка применяется к строкам со значением on, дополнительно выделяя их:
{
"data": { "name": "dataset" },
"mark": {
"type": "bar",
"tooltip": true
},
"encoding": {
"y": {
"field": "City",
"type": "nominal"
},
"x": {
"field": "Mean Temperature",
"type": "quantitative"
},
"opacity": {
"condition": {
"test": {
"field": "__selected__",
"equal": "off"
},
"value": 0.3
}
},
"fill": {
"condition": {
"test": {
"field": "__selected__",
"equal": "on"
},
"value": {
"expr": "pbiPatternSVG('diagonal-stripe-6', '#605E5C', '#ffffff')"
}
}
}
}
}
Пример 3. Оформление агрегированных примитивов
Этот случай сложнее: многие преобразования создают отдельные потоки данных, где сведения о контексте строки теряются. В примере строки группируются через агрегирование. Три ведущие категории сохраняют исходную детализацию, но идентификаторы строк в выходном потоке не сохраняются. Группа All Others («Все остальные») состоит из трёх исходных точек, объединённых в одну строку; связь с исходными строками отсутствует.
Как отмечено выше, Deneb пытается выполнить простое сопоставление с исходным "dataset", подобно обработке подсказок, но его возможности пока ограничены. С помощью слоёв можно создать впечатление эффекта выбора. Встроенный отчёт выше объясняет пример подробнее. Основной подход следующий:
- На верхнем уровне вычислить столбец через
calculate: если__selected__строки не равноoff, взять значение меры; иначе —0. - Использовать слои для двух дополнительных примитивов:
barс пониженной непрозрачностью, показывающий сумму основной меры.- Полностью непрозрачный
bar, показывающийsumвычисленного в первом шаге значения. Он рисуется после приглушённого столбца и поверх него. При нулевой сумме его ширина равна нулю; если выбраны все составляющие строки, он имеет ширину исходного столбца. При частичном выборе агрегированной группы ширина соответствует выбранной части суммы.
{
"data": { "name": "dataset" },
"transform": [
{
"calculate": "datum.__selected__ === 'off' ? 0 : datum['$ Sales']",
"as": "Sales_Selected"
}
],
"layer": [
{
"description": "Приглушённый столбец; ширина = сумма Sales",
"mark": {
"type": "bar",
"opacity": 0.3,
"tooltip": true
},
"encoding": {
"x": {
"aggregate": "sum",
"field": "$ Sales",
"tooltip": true
}
}
},
{
"description": "Непрозрачный столбец; ширина = сумма Sales_Selected",
"mark": { "type": "bar" },
"encoding": {
"x": {
"aggregate": "sum",
"field": "Sales_Selected"
}
}
}
],
"encoding": {
"y": {
"field": "Product Group",
"type": "nominal",
"sort": {
"field": "Product Group Sort"
}
}
}
}