Docs / Build Workflow

Visualization — kpi

Cuándo usar kpi

KPI es la elección correcta cuando la respuesta es un solo número — total de revenue, count de orders, tasa de conversión, error budget consumido. Agregá un delta o un valor secundario para mostrar dirección o comparación al lado del headline. KPI es el "headline" típico de un dashboard: no emite clicks (no hay dimension para clickear), pero reacciona a filtros de dashboard y pills de cross-filter como cualquier otra viz — su query subyacente re-corre con los params activos y el número headline se recomputa.

Si necesitás un número por categoría en vez de un solo número, usá bar. Si necesitás un trend en el tiempo, usá line. Si necesitás muchos números en un layout tabular, usá grid.

Los identifiers de tipo kpi y number mapean al mismo renderer; cualquiera de los dos se acepta.

Mapping

El KPI lee la primera fila del resultado de la query. Los campos de mapping nombran qué columnas de esa fila se vuelven qué elemento visual:

  • mapping.value — requerido. El field cuyo valor es el número headline.
  • mapping.subtitle — field string para una línea de contexto label / período debajo del valor.
  • mapping.delta — field numérico mostrado como indicador de cambio. El signo maneja la flecha up/down; la config de polaridad controla el color.
  • mapping.secondary_value — field numérico para un valor de comparación (ej. "período anterior") cuando no hay delta.
  • mapping.secondary_label — caption para secondary_value, escrito como string literal (ej. "Invoices", "Previous quarter"). También acepta un nombre de campo: si el valor coincide con una columna de la fila de resultado, se usa el valor de esa columna como caption. Default a "Previous" cuando se omite.
  • mapping.secondary_plain — field de texto plano mostrado al lado del headline cuando no hay delta ni valor secundario.
mapping:
  value: revenue
  subtitle: period_label
  delta: revenue_delta_pct

Bloque kpi

Las opciones específicas de KPI viven bajo el bloque top-level kpi. KPI no tiene un bloque chart.

  • kpi.comparison_label — caption mostrado debajo del delta (ej. "vs. last week"). Cuando se omite, el renderer compone un default tipo "Up vs previous period" desde el signo del delta.
  • kpi.delta_good_when"increase" (default) o "decrease". Setea la polaridad que colorea el delta en verde vs rojo. Usá "decrease" para métricas donde menos es mejor — refunds, error rate, time-to-resolution.

format

El format de número es field-keyed. Patterns por field ganan sobre el pattern root.

  • format.value — pattern para el número headline.
  • format.delta — pattern para el indicador delta.
  • format.secondary_value — pattern para el valor de comparación secundario.
  • format en root — fallback cuando falta una entry field-específica.
# headline como currency abreviada, delta como porcentaje
format:
  revenue: "$#,##0a"
  revenue_delta_pct: "#,##0.00%"

La gramática de patterns completa vive en el overview de viz-types.

Comportamiento de cross-filter

KPI participa en cross-filtering solo como consumer:

  • No emite. Clickear un KPI no agrega un pill — no hay dimension para clickear.
  • Sí reacciona. Los pills seteados en otra parte del dashboard, y cualquier filtro a nivel dashboard, se vuelven parámetros en el próximo run, y la query subyacente del KPI re-corre con ellos. El número headline se recomputa en consecuencia.

Si querés un "headline que siempre muestre el total dashboard-wide" sin importar los pills, escribí la query Malloy subyacente para que los defaults de su parámetro ignoren los valores de pill (ej. aceptar el parámetro pero no usarlo en el where-clause), o usá dos items KPI separados: uno atado a un model que ignora el parámetro de cross-filter, otro atado a un model que lo respeta.

Ejemplos trabajados

Headline con delta y polaridad de porcentaje favoreciendo decrease (menor error rate es mejor):

id: ec_error_rate_kpi
title: Error Rate
query: "models/ec_quality.malloy::error_rate_kpi"
type: kpi
mapping:
  value: error_rate
  delta: error_rate_delta_pct
  subtitle: period_label
format:
  error_rate: "#,##0.00%"
  error_rate_delta_pct: "#,##0.00%"
kpi:
  comparison_label: "vs previous period"
  delta_good_when: decrease
published: true

Headline con un valor de comparación secundario (sin delta):

id: ec_revenue_vs_prev_kpi
title: Revenue
query: "models/ec_revenue.malloy::current_vs_previous"
type: kpi
mapping:
  value: revenue_current
  secondary_value: revenue_previous
  secondary_label: "Previous quarter"
format:
  revenue_current: "$#,##0a"
  revenue_previous: "$#,##0a"
published: true

Headline con una anotación de texto plano cuando la métrica no tiene una comparación numérica:

id: ec_top_brand_kpi
title: Top Brand
query: "models/ec_revenue.malloy::top_brand"
type: kpi
mapping:
  value: brand_name
  secondary_plain: market_share_label
published: true

Errores comunes

  • El KPI muestra el número equivocado. Solo se lee la primera fila del resultado de query. Asegurate que la query subyacente agregue a una fila, o ordenala para que el valor headline sea la fila que querés.
  • La polaridad del delta está invertida. Seteá kpi.delta_good_when: decrease para métricas donde menos es mejor (refunds, errores, latency). El default "increase" asume que más es mejor.
  • El KPI está reaccionando a un pill cuando querías un headline global. KPI consume pills como cada otra viz. Para hacer un KPI "siempre-total", escribí el model subyacente así el parámetro se acepta pero no se usa en el where-clause de esa view.
  • El valor headline no se formatea. Seteá format.value (o la entry field-específica bajo format) — sin un pattern, el valor se renderiza con el default de la plataforma.
  • Mezclar delta y secondary_value en el mismo KPI. Elegí uno o el otro; mezclar hace el chart ocupado y el renderer prefiere delta.