Qué es cross-filtering en Looky
Dentro de un dashboard, clickear un data point en una visualization estrecha cada otra visualization de la página. El par campo/valor clickeado se convierte en un "pill" removible que el usuario ve arriba del dashboard, y Looky aplica ese campo/valor a cada otra viz como parámetro en su próximo run.
Cross-filtering es un comportamiento de runtime, no un feature de YAML. No hay bloque cross_filter en el YAML del dashboard — el cableo es automático, manejado por qué campos los models subyacentes declaran como parámetros.
Dónde funciona el cross-filtering
- En dashboards. Cualquier click en un chart en cualquier parte de un dashboard agrega (o saca) un pill.
- No en la página standalone de visualization. Clickear un chart que está abierto como su propia página no produce un pill.
Si querés comportamiento cross-filter, el usuario tiene que estar mirando el chart a través de un dashboard.
Qué viz types emiten clicks
- bar — clickear una barra emite la categoría del eje x.
- line — clickear un punto emite el valor x (single / dual-axis) o el nombre de la serie (multi-series).
- pie — clickear un slice emite el label del slice.
- scatter — clickear un punto emite su label / serie / valor x.
- funnel — clickear un stage emite el label del stage.
- heatmap — emite solo cuando la viz tiene
chart.cross_filter_emitseteado a"x"o"y". - grid — clickear una celda en una columna configurada como clickeable emite el nombre de la columna y el valor de la celda.
- report_matrix — clickear una celda del cuerpo emite el nombre de la columna y el valor de la celda, mismo shape que grid. Las filas de totales, las celdas de trend y los headers de sección no son clickeables; el render en modo document suprime todo el cableo de click.
- kpi — no emite clicks (no tiene target categórico de click por estructura), pero consume pills: su query re-corre con los params activos igual que cada otra viz.
Pills
Los pills son la representación visual de los cross-filters activos arriba de un dashboard. El ciclo de vida:
- El usuario clickea un chart — el par campo/valor se convierte en un pill.
- Los pills son aditivos — clickear en un segundo chart agrega otro pill, y los dos aplican a cada viz en el próximo run.
- Clickear el botón de remove de un pill dropea ese filtro y re-corre el dashboard sin él.
- Los pills duran la sesión del dashboard — recargar la página los borra.
Un click solo se mantiene como pill si el campo clickeado también es un parámetro declarado por al menos un model en el dashboard. Los clicks en campos que ningún model acepta se ignoran silenciosamente — no hay error, simplemente no hay pill. Para hacer una columna cross-filterable, declará un parámetro para ella en el model que potencia los charts afectados (mirá Malloy support).
Cómo llegan los valores de cross-filter a las queries subyacentes
Los valores de pill activos se mergean con cualquier valor de filtro a nivel dashboard y se pasan como parámetros a la query de cada viz en el próximo run. Desde el punto de vista del model, un pill de cross-filter es indistinguible de un valor que el usuario tipeó en un control de filtro — aplica el mismo parameter binding.
Los pills overridean los valores de filtro declarados cuando ambos setean el mismo parámetro. Así, un click en un chart que emite {country: "MX"} gana sobre el select "country" del dashboard que estaba seteado en "all". Sacar el pill restaura el valor declarado.
Consecuencia práctica: cada model usado por un dashboard debería declarar un parámetro de Malloy para cualquier campo que querés que los usuarios puedan cross-filtrar. Usá un default razonable (típicamente un sentinel como "all", un string vacío, o el valor válido más amplio) así la query igual corre cuando el parámetro no está seteado.
# en un model de Malloy
##! experimental.parameters
source: orders(
p_country::string is "all",
p_brand::string is "all"
) is bigquery.table('...') extend {
view: by_category is {
where:
(p_country = "all" or country = p_country)
and (p_brand = "all" or brand = p_brand)
group_by: category
aggregate:
revenue is sum(sale_price)
}
}
Con los parámetros de arriba, clickear una barra de country agrega un pill {country: "MX"}, el dashboard re-corre con p_country = "MX", y cada chart usando esta view se estrecha correspondientemente.
Opt-out por viz
Suprimí la emisión de clicks para una viz específica seteando el flag de cross-filter a false en su YAML. El flag vive en el bloque de config primario de la viz — chart para vizs basadas en ECharts, el bloque con nombre del tipo para vizs basadas en DOM (porque no son "charts" en el sentido ECharts).
- bar, line, pie, scatter, heatmap, funnel →
chart.cross_filter: false - grid →
grid.cross_filter: false - report_matrix →
matrix.cross_filter: false - kpi → sin flag; KPI no emite por estructura (no tiene target categórico de click).
Usá opt-out para charts "headline" que siempre deberían mostrar el total sin filtrar — un chart top-line de revenue que no debería cambiar cuando el usuario clickea en otro lado, por ejemplo.
Diferencias entre adapters
El routing del cross-filter en sí es el mismo en los tres adapters. Los valores de pill se vuelven parámetros de query; desde ahí aplican las mismas caveats de adapter que para valores de filtro — mirá Diferencias entre adapters de source. Los pills numéricos y de string no se afectan; los pills de date/timestamp siguen el patrón de Postgres / MySQL.
Patrones
Un drill path por dashboard
Decidí qué campos los usuarios deberían poder drillear (típicamente las dimensions en tus cláusulas group-by) y declará parámetros para esos en cada model usado por el dashboard. Salteá parámetros para campos que no deberían manejar cross-filter — los clicks en ellos caen silenciosamente.
Headline + drill grid
Usá un KPI arriba mostrando el total (el KPI no reacciona a pills, por diseño). Debajo, un bar chart que emite clicks. Debajo del bar, un grid que consume el cross-filter y muestra las filas subyacentes. Cada click en la barra estrecha el grid al subset matcheante.
Cross-filter + filtros declarados juntos
Mezclá un filtro de fecha arriba del dashboard (ej. date_range_preset) con cross-filtering implícito en el layout de charts. Ambos terminan como parámetros en las mismas queries.
Errores comunes
- El click no hace nada. El campo clickeado tiene que estar declarado como parámetro en al menos un model en el dashboard. Si ningún model lo declara, el click se ignora silenciosamente.
- Los pills desaparecen después de reload. Los pills no persisten entre recargas de página. Si necesitás estado de filtro shareable, usá un filtro declarado (Filters) — esos se reflejan en la URL.
- Una viz reacciona al pill, otra no. Las dos vizs tienen que usar models que declaren el mismo parámetro. Auditá el model subyacente de cada viz.
- El KPI "headline" cambia cuando no debería. El KPI reacciona a pills como cada otra viz. Si querés un KPI que los ignore, escribí el model subyacente para que el parámetro no influya el where-clause; o usá una viz no-KPI con
chart.cross_filter: falsecomo headline. - Clickear un kpi no agrega un pill. KPI es una viz consumer-only (no tiene target categórico de click por estructura). Su query re-corre con params activos pero no puede emitir. report_matrix y grid emiten en clicks de body-cell.
- Los clicks de funnel SON pills. Funnel emite como bar / line / pie / scatter. Si querés un funnel que no emita, seteá
chart.cross_filter: falseen él. - Dos pills deberían combinarse como OR pero combinan como AND. El comportamiento actual es AND entre todos los pills. Para soportar semántica OR, codificalo en el parámetro del model subyacente (ej. aceptar una lista, default
"all").