Docs / Build Workflow

Visualization — grid (alias: table)

Cuándo usar grid

Grid es la elección correcta cuando la audiencia necesita leer records individuales, exportar data, o verificar el detalle detrás de un summary. Los identifiers de tipo grid y table mapean al mismo renderer; cualquiera de los dos se acepta.

Usá una viz tipo chart (bar, line) cuando la pregunta es sobre una comparación o un trend en vez de las filas raw. Usá report_matrix cuando los records necesitan agrupamiento con subtotales o están diseñados para PDF export.

Mapping

El mapping para grid es mínimo — las columnas vienen del resultado de la query.

  • mapping.columns — opcional. Array de nombres de columna. El subset a mostrar, en el orden dado. Usalo para dropear columnas ruidosas o forzar un orden de columna específico sin cambiar la query. Cuando se omite, cada columna en el resultado de la query se renderiza, en orden de query.
mapping:
  columns:
    - order_date
    - category
    - brand
    - country
    - status
    - revenue

Bloque grid

Las opciones de grid viven bajo el bloque top-level grid (el alias table también se acepta). Grid no tiene un bloque chart.

Display de columna

  • grid.column_widths — objeto mapeando nombre de columna a un ancho fijo ("120px"), proporcional ("25%"), o valor numérico (pixels).
  • grid.frozen_columns — número de columnas leftmost a congelar, o un array de nombres de columna. Útil cuando el grid scrollea horizontal y la audiencia necesita el identifier de fila siempre visible.
  • grid.nowrap_columns — array de nombres de columna que nunca tienen que hacer wrap; el overflow muestra elipsis.
  • grid.labels — objeto mapeando nombre de columna a display label (overridea el nombre raw de columna en el header).

Celdas compuestas

grid.composite_columns renderiza una celda como múltiples líneas tomadas de otros fields:

grid:
  composite_columns:
    customer:
      lines:
        - field: name
          class: font-semibold
        - field: city
          prefix: "📍 "
          show_empty: false

Celdas de comparación

  • grid.comparison_columns — array de nombres de columna a renderizar como indicador de trend up / down / dash al lado del valor. Útil para columnas de delta donde la audiencia necesita la dirección a primera vista.

Formats

  • grid.column_formats — objeto mapeando nombre de columna a una format key.
  • grid.formats — objeto mapeando format key a un pattern. La indirección de dos pasos te deja reusar el mismo pattern en muchas columnas.

Cross-filter

  • grid.cross_filter — boolean, default true. Seteá a false para suprimir click-to-filter en este grid.

Paginación

Las opciones de paginación viven bajo el bloque top-level pagination:

  • pagination.page_size — entero. Filas por página. Default 25. Elegí más grande cuando la audiencia hace data-export; más chico cuando el escaneo es el uso típico.
  • pagination.column_page_size — entero. Cuando las columnas visibles exceden esto, se activa un column-pager horizontal. Default 8. Aliases: columns_per_page, columns_page_size.

La paginación es server-side: cambiar de página re-corre la query subyacente con los nuevos parámetros de página. Las características de costo difieren por adapter — mirá Diferencias entre adapters de source.

format

El par grid.column_formats + grid.formats es la forma primaria de formatear columnas. El field format root actúa como fallback para cualquier columna no cubierta. Usá el patrón de indirección cuando el mismo estilo de número aplica a muchas columnas:

grid:
  column_formats:
    revenue: currency
    avg_order_value: currency
    refunds: currency
    item_count: integer
  formats:
    currency: "$#,##0.00"
    integer: "#,##0"

Comportamiento de cross-filter

  • Clickear una celda (cuando la columna está configurada como clickeable) cross-filtra el resto del dashboard por el nombre de columna y el valor clickeado.
  • El field clickeado tiene que estar declarado como parámetro en al menos un model usado por el dashboard, o el click se ignora silenciosamente.
  • El bloque top-level emphasis puede declarativamente resaltar una fila matcheando un valor de cross-filter relacionado.
  • Deshabilitá por viz con chart.cross_filter: false.

Mirá Cross-filtering para el mecanismo completo.

Ejemplos trabajados

Detalle de orden con primera columna congelada, formats de currency y una columna de comparación:

id: ec_orders_detail_grid
title: Order Detail
query: "models/ec_fulfillment.malloy::detail"
type: grid
mapping:
  columns:
    - order_date
    - category
    - brand
    - country
    - status
    - item_count
    - revenue
    - avg_order_value
grid:
  frozen_columns: 1
  column_widths:
    order_date: "120px"
    revenue: "140px"
  column_formats:
    revenue: currency
    avg_order_value: currency
    item_count: integer
  formats:
    currency: "$#,##0.00"
    integer: "#,##0"
  comparison_columns:
    - revenue
pagination:
  page_size: 50
published: true

Roster de customers con celdas compuestas:

id: customers_grid
title: Customers
query: "models/customers.malloy::roster"
type: grid
grid:
  composite_columns:
    customer:
      lines:
        - field: name
          class: font-semibold
        - field: email
          prefix: "✉ "
        - field: city
          prefix: "📍 "
          show_empty: false
  column_widths:
    customer: "260px"
    lifetime_value: "140px"
  column_formats:
    lifetime_value: currency
  formats:
    currency: "$#,##0.00"
pagination:
  page_size: 25
published: true

Errores comunes

  • El grid ocupa demasiado espacio horizontal. Dropeá columnas de mapping.columns o seteá anchos más estrechos explícitos en grid.column_widths.
  • Los anchos de columna no quedan. Asegurate que los nombres de columna en grid.column_widths matcheen los nombres de field en el resultado de query exacto.
  • El sorteo es solo por-página. La paginación server-side significa que los sorts client-side solo ven una página. Para ordenar entre todas las filas, ordená en la query Malloy.
  • El label del header está mal. Seteá grid.labels para overridear el nombre raw de columna (o renombrá en la query Malloy).
  • El indicador de comparación apunta en la dirección equivocada. El renderer deriva dirección del signo del valor. Codificá deltas "buenos" con signo positivo y "malos" con negativo.
  • Los clicks de cross-filter no tienen efecto. La columna clickeada tiene que estar declarada como parámetro en al menos un model usado por el dashboard.
  • Grid esperado para agrupar filas con subtotales. Grid es plano; usá report_matrix para agrupamiento.