Ir al contenido

Widgets y gráficos

Los dashboards están compuestos de widgets ubicados en una grilla responsive de 12 columnas. Cada widget tiene un tipo, un binding a una fuente de datos y una posición en la grilla (x, y, w, h).

TipoPropósito
kpiMétrica única con comparación opcional y sparkline
chartVisualización de datos (line, bar, pie, scatter, gauge, y más)
tableTabla de datos ordenable y paginada
textLabels y anotaciones en Markdown o HTML
filterControl de filtro interactivo (dropdown, date picker, etc.)
htmlHTML libre; scripts deshabilitados por defecto
imageImagen estática desde blobs
embedEmbed por iframe

Muestra una única métrica con contexto. Es el tipo de widget más usado.

┌──────────────────────────────┐
│ Label │
│ $1,234,567 ▲ 15.2% │
│ ▁▂▃▄▅▆▇ sparkline │
└──────────────────────────────┘
dashboard.widgets.add('kpi', {
value: 'total_revenue',
label: 'Ingresos Totales',
format: 'currency',
formatOptions: { notation: 'compact' },
comparison: {
value: 'prev_month_revenue',
type: 'percent',
invertColors: false, // true cuando menor es mejor
},
sparkline: { field: 'daily_revenue', type: 'area' },
size: 'lg', // 'sm' | 'md' | 'lg'
}, { x: 0, y: 0, w: 4, h: 3 });

Valores de format: 'number' | 'currency' | 'percent' | 'custom'

Tamaños recomendados:

TamañoGrilla (w×h)Muestra
Chico3×2Valor + label
Mediano3×2Valor + label + cambio
Grande4×3Valor + label + cambio + sparkline

Visualiza tendencias y comparaciones de datos.

Tipos de gráfico: line | bar | area | pie | donut | scatter | heatmap | gauge | funnel | treemap

PreguntaGráfico
¿Cómo cambia en el tiempo?line (continuo), bar (períodos discretos)
¿Cómo se comparan las categorías?bar (vertical ≤7 categorías, horizontal para más o labels largos)
¿Cuál es la composición?pie / donut (≤6 partes)
¿Existe correlación?scatter
¿Cuál es el avance hacia una meta?gauge
¿Cuál es el flujo de conversión?funnel
¿Patrones en dos dimensiones?heatmap
// Gráfico de líneas
dashboard.widgets.add('chart', {
chartType: 'line',
xAxis: { field: 'date', type: 'time', label: 'Fecha' },
yAxis: { field: 'revenue', label: 'Ingresos ($)', min: 0 },
series: [
{ field: 'revenue', name: 'Real', color: '#3b82f6' },
{ field: 'target', name: 'Objetivo', color: '#94a3b8' },
],
legend: { show: true, position: 'top' },
animation: true,
}, { x: 0, y: 2, w: 6, h: 4 });

Tamaños mínimos recomendados:

Tipo de gráficoMínimo (w×h)Ideal
Line / Area6×36×4
Bar (vertical)4×36×4
Bar (horizontal)6×48×5
Pie / Donut4×44×4
Scatter6×46×5
Gauge3×34×3

Tabla de datos ordenable, filtrable y paginada.

dashboard.widgets.add('table', {
columns: [
{ field: 'name', header: 'Cliente', sortable: true },
{ field: 'revenue', header: 'Ingresos', format: 'currency', align: 'right', sortable: true },
{ field: 'status', header: 'Estado', format: 'badge' },
],
pageSize: 10,
sortable: true,
filterable: true,
striped: true,
}, { x: 0, y: 6, w: 12, h: 5 });

Opciones de format para columnas: text | number | currency | percent | date | boolean | link | image | badge

Las tablas generalmente ocupan las 12 columnas completas. Mostrá 8–12 filas sin scroll (5–6 unidades de fila); paginá a 10–25 ítems.

Contenido estático en Markdown o HTML — encabezados de sección, anotaciones, instrucciones.

dashboard.widgets.add('text', {
content: '## Rendimiento de Ventas',
contentType: 'markdown', // 'markdown' | 'html'
align: 'left',
}, { x: 0, y: 0, w: 12, h: 1 });

Los controles de filtro interactivos se definen via dashboard.filters.addDefinition(), no via widgets.add(). Tipos de filtro: select | multiselect | daterange | numberrange | search.

dashboard.filters.addDefinition({
type: 'select',
label: 'Región',
options: [
{ value: 'na', label: 'Norteamérica' },
{ value: 'eu', label: 'Europa' },
{ value: 'apac', label: 'Asia Pacífico' },
],
affects: '*', // '*' = todos los widgets; o array de IDs
});
dashboard.filters.addDefinition({
type: 'daterange',
label: 'Período',
defaultValue: { from: '2026-01-01', to: '2026-12-31' },
affects: ['chart-revenue', 'table-details'],
});

HTML libre para visualizaciones personalizadas o contenido embebido.

dashboard.widgets.add('html', {
content: '<div class="custom-viz" style="height:100%"><canvas id="globe"></canvas></div>',
scripts: false, // habilitá solo para contenido de confianza
}, { x: 0, y: 0, w: 6, h: 6 });

Los scripts están en sandbox y deshabilitados por defecto. Sandboxeá los iframes embebidos.

Los dashboards usan una grilla de 12 columnas. Las posiciones de los widgets son coordenadas de columna y fila con índice cero.

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬──┬──┬──┐
│0│1│2│3│4│5│6│7│8│ 9│10│11│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴──┴──┴──┘

Altura de fila por defecto: 80 px por unidad de fila.

Tamaños estándar:

Widgetwh
KPI (chico)32
KPI (grande)43
Chart (mitad del ancho)64
Chart (ancho completo)124–5
Table125–6
Barra de filtros121
// Fila de KPIs
dashboard.widgets.add('kpi', kpiConfig1, { x: 0, y: 0, w: 3, h: 2 });
dashboard.widgets.add('kpi', kpiConfig2, { x: 3, y: 0, w: 3, h: 2 });
dashboard.widgets.add('kpi', kpiConfig3, { x: 6, y: 0, w: 3, h: 2 });
dashboard.widgets.add('kpi', kpiConfig4, { x: 9, y: 0, w: 3, h: 2 });
// Fila de gráficos
dashboard.widgets.add('chart', trendConfig, { x: 0, y: 2, w: 6, h: 4 });
dashboard.widgets.add('chart', breakdownConfig, { x: 6, y: 2, w: 6, h: 4 });
// Fila de tabla
dashboard.widgets.add('table', tableConfig, { x: 0, y: 6, w: 12, h: 5 });

El campo layout en DashboardMeta puede ser 'fixed' o 'responsive'. En modo responsive la grilla se reorganiza en los breakpoints estándar:

ViewportColumnasCambio típico
Desktop ≥1280 px12Layout completo
Tablet 768–1279 px8KPIs de a 2, gráficos apilados
Mobile ≤767 px4KPIs de a 1, gráficos a ancho completo
  • Más de 4–6 KPIs saturan la vista de un vistazo; agrupá métricas relacionadas.
  • Los KPIs deben estar siempre sobre el fold — los viewers no deberían tener que hacer scroll para ver los números clave.
  • Variá los tamaños de los widgets para señalar importancia; tamaños uniformes hacen que todo parezca igual de importante.
  • Usá splits de columnas consistentes (6+6, 8+4, 4+4+4); evitá proporciones incómodas.

Después de agregar un widget, podés moverlo o redimensionarlo vía el layout manager:

dashboard.layout.move('kpi-revenue', 3, 0); // mover a (3, 0)
dashboard.layout.resize('chart-trend', 8, 4); // redimensionar a 8 cols × 4 filas
dashboard.layout.update('table-deals', { x: 0, y: 9, w: 12, h: 5 });