Docs / Build Workflow

Visualization — report_matrix

Cuándo usar report_matrix

report_matrix es la elección correcta cuando la audiencia necesita un reporte estructurado con filas agrupadas, secciones anidadas, subtotales y totales de grupo. Está diseñado para dashboards modo document y PDF export, mientras igual soporta click-to-filter dentro de dashboards interactivos.

Usá grid en su lugar cuando las filas no necesitan agrupamiento. Usá una viz tipo chart cuando la pregunta es sobre una métrica única entre categorías en vez de un reporte tabular estructurado.

Mapping

report_matrix toma su estructura de columnas del resultado de la query. No hay un bloque mapping requerido; la configuración de matrix vive bajo el bloque matrix en su lugar.

Columnas & presentación

Estas keys controlan qué columnas muestra el matrix y cómo renderiza cada columna:

  • matrix.key_columns — array de nombres de columna renderizados como key cells (bold, coloreo basado en polaridad). Usalo para la columna de métrica que los readers tienen que enfocar (ej. cumplimiento, conversion rate).
  • matrix.trend_columns — array de nombres de columna renderizados con un trend icon (up / down / dash) al lado del valor.
  • matrix.labels — objeto mapeando nombre de columna a display label (overridea el nombre raw de columna en el header).
  • matrix.column_formats — objeto mapeando nombre de columna a una format key.
  • matrix.formats — objeto mapeando format key a un pattern (indirección de dos pasos, como grid.formats).
  • matrix.column_widths — objeto mapeando nombre de columna a un ancho ("150px", "20%", o numérico).
  • matrix.uniform_column_widths — boolean o "auto". Cuando está seteado, todas las columnas comparten el mismo ancho auto-fit.
  • matrix.uniform_column_widths_min_px — entero. Default 80.
  • matrix.uniform_column_widths_max_px — entero. Default 520.

Tabla de summary

El matrix puede renderizar un summary comparativo arriba de las filas de detalle:

  • matrix.show_summary — boolean. Default true.
  • matrix.summary_title — título string arriba del summary.
  • matrix.summary_columns — array de nombres de columna incluidos en el summary.

Agrupamiento & secciones

Dos maneras de organizar las filas: agrupamiento automático por una columna, o secciones manuales.

Agrupamiento automático

  • matrix.group_by — nombre de columna. Agrupa las filas resultado por este field; cada grupo se vuelve una sección colapsable.
  • matrix.group_key_field — nombre de columna a renderizar como la primera columna dentro de cada sección de grupo.
  • matrix.group_columns — array de nombres de columna renderizados dentro de cada grupo.

Secciones manuales

matrix:
  sections:
    - id: revenue
      title: Revenue breakdown
      columns: [period, units, revenue]
    - id: cost
      title: Cost breakdown
      columns: [period, cogs, opex]

Totales

Los totales viven en dos hermanos bajo matrix: group_totals (una fila por sección de grupo) y overall_totals (una fila entre todos los grupos). Ambos comparten el mismo shape:

  • enabled — boolean.
  • label — string. Default "TOTAL".
  • columns — array de nombres de columna a sumar. Si está vacío, las columnas numéricas se suman automáticamente.
  • computed — array de objetos de field computado renderizados al lado de los sums. Cada item:
    • field — nombre del field output.
    • type"ratio" o "percent_delta".
    • numerator — nombre del field para el dividendo (ratio) o período actual (delta).
    • denominator — nombre del field para el divisor (ratio) o baseline (delta).
matrix:
  group_totals:
    enabled: true
    label: TOTAL ZONA
    columns: [unidades, ventas]
    computed:
      - field: cumplimiento
        type: percent_delta
        numerator: ventas
        denominator: presupuesto
  overall_totals:
    enabled: true
    label: TOTAL GENERAL
    columns: [unidades, ventas]

Behavior

matrix.behavior controla cómo se expanden las secciones y cómo renderiza el matrix para PDF export:

  • web_mode"all_open", "single_open", "expand_all", o vacío. Cómo se comportan las secciones en el browser cuando el usuario clickea un header.
  • default_open"all" o un id de sección específico. Qué secciones empiezan expandidas en first load.
  • pdf_expand_all — boolean. Default false. Crítico para PDF export: sin esto, los grupos colapsados desaparecen del documento impreso.

format

Usá matrix.column_formats + matrix.formats como el camino primario de formatting; el field format root se chequea solo como fallback.

Comportamiento de cross-filter

  • Clickear una celda del cuerpo cuya columna está declarada como parámetro en al menos un model del dashboard emite un pill { field: <nombre de columna>, value: <valor de celda> }.
  • Las celdas en filas de group totals y overall totals no son clickeables — agregan entre múltiples valores key, así que un click sería ambiguo.
  • Las celdas en trend columns (renderizadas con badges de dirección up/down) no son clickeables — muestran dirección sobre un valor numérico, no un pick categórico.
  • Los headers de sección (auto-agrupados vía matrix.group_by o hechos a mano vía matrix.sections) no son clickeables en esta versión. El click de <details> está reservado para expand/collapse.
  • Modo document (tableContext: document) suprime el cableo de cell-click enteramente — el render document/PDF no tiene target interactivo.
  • Deshabilitá por viz con chart.cross_filter: false.

Mirá Cross-filtering para el mecanismo completo.

Ejemplo trabajado

id: nv_visitador_resumen
title: Resumen por visitador
query: "models/nv_comercial.malloy::resumen_por_visitador"
type: report_matrix
matrix:
  group_by: zona
  group_key_field: visitador
  group_columns: [periodo, unidades, ventas, cumplimiento]
  key_columns: [cumplimiento]
  trend_columns: [cumplimiento]
  group_totals:
    enabled: true
    label: TOTAL ZONA
    columns: [unidades, ventas]
    computed:
      - field: cumplimiento
        type: percent_delta
        numerator: ventas
        denominator: presupuesto
  overall_totals:
    enabled: true
    label: TOTAL GENERAL
    columns: [unidades, ventas]
  column_formats:
    ventas: currency
    presupuesto: currency
    cumplimiento: percent
  formats:
    currency: "$#,##0"
    percent: "#,##0.0%"
  behavior:
    web_mode: single_open
    default_open: all
    pdf_expand_all: true
published: true

Errores comunes

  • El PDF export muestra menos filas que el browser. Seteá matrix.behavior.pdf_expand_all: true. Sin eso, los grupos colapsados se quedan colapsados en el documento impreso.
  • Los totales auto-sumados incluyen las columnas equivocadas. Listá las columnas que querés sumadas explícitamente en group_totals.columns / overall_totals.columns; dejarlas vacías auto-suma todas las columnas numéricas, lo que puede incluir cosas tipo números de ID.
  • El field de total computado muestra un número raro. Tanto numerator como denominator tienen que referenciar fields presentes en las filas que se suman. Chequeá la ortografía contra el resultado de query.
  • Las secciones no empiezan expandidas. Seteá matrix.behavior.default_open: "all", o el id de sección específico que querés abrir en first load.
  • El click en una celda no hace nada. Chequeá que (a) el nombre de columna esté declarado como parámetro en al menos un model del dashboard, (b) el valor no sea null, (c) la celda no esté en una fila de totals o trend (esas son no-clickeables por diseño), y (d) matrix.cross_filter no esté seteado a false.
  • Los formats de celda son inconsistentes entre columnas. Usá la indirección matrix.column_formats + matrix.formats así el mismo pattern de currency / percent aplica en todos lados donde debería.