Версия: 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 щелчки по другим примитивам с сопоставимыми точками данных добавляют их в текущий список и обновляют остальные визуалы:

Выбор нескольких точек с удержанием Ctrl

Простое сопоставление агрегированных данных

Для примитивов и слоёв с простым агрегированием Deneb может попытаться найти составляющие точки данных по уникальным значениям полей группировки. Это бывает полезно, но имеет несколько особенностей:

  • В новом потоке данных столбцы и меры должны иметь те же имена, что и соответствующие исходные поля, из которых они получены.
  • Фильтры и дополнительные преобразования, удаляющие составляющие строки, при сопоставлении не учитываются.
  • Новый поток имеет другую детализацию и, следовательно, другой контекст строки относительно базового "dataset". Поэтому в нём нет соответствующего поля __selected__ для управления состоянием выбора. Однако можно создать впечатление выбора на более высоком уровне детализации; пример приведён ниже.

Ограничение числа точек данных

Большой выбор увеличивает объём работы Power BI по поддержанию состояния всех визуалов страницы и может снизить производительность. Vega и Vega-Lite позволяют создавать очень разные визуалы, поэтому количество точек, передаваемых Power BI, ограничено. Их число может быстро вырасти, если исходные данные имеют высокую детализацию, а выбранный примитив объединяет много строк.

При включённой перекрёстной фильтрации в панели настроек доступно свойство Data Point Limit:

Настройка 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-спецификации приведены под отчётом.

Скачать файл отчёта PBIX

Пример 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", подобно обработке подсказок, но его возможности пока ограничены. С помощью слоёв можно создать впечатление эффекта выбора. Встроенный отчёт выше объясняет пример подробнее. Основной подход следующий:

  1. На верхнем уровне вычислить столбец через calculate: если __selected__ строки не равно off, взять значение меры; иначе — 0.
  2. Использовать слои для двух дополнительных примитивов:
    • 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"
      }
    }
  }
}