Обсудить
бизнес-задачи
блог о bi, №1 в рунете

Использование гиперссылки для проброса значений фильтров из одного дашборда в другой

в Apache Superset

Создание интерактивных решений для аналитики широко востребовано в области исследования данных. Формирование дашбордов с последовательным углублением в разрезы данных известная и логичная механика для построения аналитической системы. Чтобы решение было интуитивно понятным и удобным для пользователя, необходимо реализовать переход между дашбордами разных уровней анализа с передачей значений фильтров.

В текущей реализации Apache Superset такого функционала нет, но существует возможность выбирать значения для фильтров по URL-адресу. Об этом мы узнали в источнике по ссылке: https://www.blef.fr/superset-filters-in-url/

Для решения задачи нам необходимо:

- Создать URL-адрес для выбора фильтров;
- Обернуть URL-адрес в гиперссылку;
- Добавить значения фильтров из исходного дашборда в URL-адрес;


Окружение:


- Apache Superset 2.0
- Apache Kylin 4.0

Пример реализации описанной выше методики:

  1. Создание ссылки для выбора фильтров
Для проверки решения создадим тестовый дашборд, для которого будем выбирать фильтры, и назовем его «test_url_input». Добавим в него два фильтра (YEAR и MONTH) и таблицу, которая отображает выбранные значения фильтры, чтобы проверить влияние ссылки на чарт.
В общем виде URL-адрес для выбора фильтров для нашей версии SuperSet выглядит следующим образом:

http://<ip>:<port>/superset/dashboard/<DashbordNumber>/?native_filters=(<NATIVE_FILTER-id>:(__cache:(label:<value>,validateStatus:!f,value:!(<value>)),extraFormData:(filters:!((col:<column>,op:IN,val:!(<value>)))),filterState:(label:<value>,validateStatus:!f,value:!(<value>)),id: <NATIVE_FILTER-id>,ownState:()))

В указанный адрес необходимо вставить параметры:

- <ip>:<port> - ip-адрес и порт SuperSet;
- <DashbordNumber> - номер дашборда, в котором необходимо выбрать фильтры;
- <NATIVE_FILTER-id> - собственный идентификатор фильтра;
- <value> - значение для фильтра;
- <column> - название колонки, которая выбрана для фильтра.

Чтобы ссылка заработала необходимо предварительно установить следующие флаги в файле конфигурации config.py:

FEATURE_FLAGS = {"DASHBOARD_FILTERS_EXPERIMENTAL": True,
"DASHBOARD_NATIVE_FILTERS_SET": True,
"DASHBOARD_NATIVE_FILTERS": True,
"DASHBOARD_CROSS_FILTERS": True,
"ENABLE_TEMPLATE_PROCESSING": True}

Номер дашборда можно узнать в текущем URL вашего дашборда, для нашего он равен 16:

Идентификатор фильтра можно получить при редактировании свойств дашборда в расширенной части, просмотрев метаданные JSON (см. рисунок ниже). Для наших фильтров:
- YEAR - NATIVE_FILTER-aHg1b2y66
- MONTH - NATIVE_FILTER-LIGOzuVHD.
Значения для фильтров выберем отличные от указанных в примере выше:
- YEAR - 2021
- MONTH - November.
Название колонки мы указывали при создании фильтров:
Соберем все в итоговую ссылку (чтобы выбрать несколько фильтров их нужно указать через запятую), получается вот такая конструкция:

http://<ip>:<port>/superset/dashboard/16/?native_filters=(NATIVE_FILTER-aHg1b2y66:(__cache:(label:2021,validateStatus:!f,value:!(2021)),extraFormData:(filters:!((col:YEAR_NAME,op:IN,val:!(2021)))),filterState:(label:2021,validateStatus:!f,value:!(2021)),id:NATIVE_FILTER-aHg1b2y66,ownState:()),NATIVE_FILTER-LIGOzuVHD:(__cache:(label:November,validateStatus:!f,value:!(November)),extraFormData:(filters:!((col:MONTH_NAME,op:IN,val:!(November)))),filterState:(label:November,validateStatus:!f,value:!(November)),id:NATIVE_FILTER-LIGOzuVHD,ownState:()))

Результат работы ссылки:
2. Обернуть получившийся URL-адрес в гиперссылку

Создадим второй дашборд, из которого будем переходить по ссылке, назовем его «test_url_output». Он будет содержать два аналогичных фильтра (YEAR и MONTH) и таблицу с гиперссылкой на дашборд «test_url_input»
Подробно останавливаться на создании гиперссылки мы не будем, так как описывали эту механику в одной из предыдущих статей. Возьмем итоговый URL-адрес из п.1 и вставим в ячейку таблицы, запрос для реализации выглядит следующим образом:

select '<p>Cсылка на <a href =
"http://<ip>:<port>/superset/dashboard/16/?native_filters=(NATIVE_FILTER-aHg1b2y66:(__cache:(label:2021,validateStatus:!f,value:!(2021)),extraFormData:(filters:!((col:YEAR_NAME,op:IN,val:!(2021)))),filterState:(label:2021,validateStatus:!f,value:!(2021)),id:NATIVE_FILTER-aHg1b2y66,ownState:()),NATIVE_FILTER-LIGOzuVHD:(__cache:(label:November,validateStatus:!f,value:!(November)),extraFormData:(filters:!((col:MONTH_NAME,op:IN,val:!(November)))),filterState:(label:November,validateStatus:!f,value:!(November)),id:NATIVE_FILTER-LIGOzuVHD,ownState:()))
" >input</a>.</p>' as t

При нажатии на слово «input» в таблице дашборда «test_url_output» мы должны переместиться в дашборд «test_url_input» с пока статичными фильтрами 2021/November.

3. Добавим в запрос таблицы дашборда «test_url_input» шаблоны Jinja (описание можно найти в предыдущих статьях по ссылке указанной выше) вместо выбранных ранее значений (2021/November) для передачи выбранных фильтров.
В Apache Kylin для конкатирования строк можно использовать «||» или «+». В нашем примере использован «+», но при работе с числами лучше использовать «||». Итоговый запрос имеет следующий вид:

select
'<p> Cсылка на <a href = "http:// <ip>:<port>/superset/dashboard/16/?native_filters=(NATIVE_FILTER-aHg1b2y66:(__cache:(label:' + '{{ filter_values('YEAR_NAME', )[0] }}' + ',validateStatus:!f,value:!(' + '{{ filter_values('YEAR_NAME', )[0] }}' + ')),extraFormData:(filters:!((col:YEAR_NAME,op:IN,val:!(' + '{{ filter_values('YEAR_NAME', )[0] }}' + ')))),filterState:(label:' + '{{ filter_values('YEAR_NAME', )[0] }}' + ',validateStatus:!f,value:!(' + '{{ filter_values('YEAR_NAME', )[0] }}' + ')),id:NATIVE_FILTER-aHg1b2y66,ownState:()),NATIVE_FILTER-LIGOzuVHD:(__cache:(label:' + '{{ filter_values('MONTH_NAME', )[0] }}' + ',validateStatus:!f,value:!(' + '{{ filter_values('MONTH_NAME', )[0] }}' + ')),extraFormData:(filters:!((col:MONTH_NAME,op:IN,val:!(' + '{{ filter_values('MONTH_NAME', )[0] }}' + ')))),filterState:(label:' + '{{ filter_values('MONTH_NAME', )[0] }}' + ',validateStatus:!f,value:!(' + '{{ filter_values('MONTH_NAME', )[0] }}' + ')),id:NATIVE_FILTER-LIGOzuVHD,ownState:()))">input</a>.</p>' as t

Результат: