resumen_mensual.json
Patrón mensual con series temporales y tabla consolidada
Esta página documenta la estructura completa del schema JSON. Úsala para construir payloads válidos de dashboard y guiar transformaciones de datos a partir de orígenes arbitrarios.
$schema, meta, kpis, charts y tables.vendor/dashboard-renderer.js.
El payload válido más pequeño necesita solo $schema y meta.title.
Esto es suficiente para que el renderer muestre el encabezado del dashboard.
minimum.json
{
"$schema": "dashboard-v1",
"meta": {
"title": "My First Dashboard"
}
}
Sirve tu proyecto con cualquier servidor estático y carga el JSON con
DashboardRenderer.init().
index.html
<script src="vendor/chart.umd.min.js"></script>
<script src="vendor/dashboard-renderer.js"></script>
<script>
DashboardRenderer.init('data/examples/minimum.json', '#dashboard');
</script>
Resultado esperado: la página renderiza un encabezado con tu
meta.title. Las tarjetas KPI, gráficos y tablas aparecen solo cuando se
incluyen sus arreglos.
Este schema define un objeto JSON con cinco propiedades de nivel superior. El renderer es agnóstico al dominio: lee la configuración y renderiza la UI sin aplicar transformaciones de lógica de negocio.
{root} object$schema requeridometa requeridokpis opcionalcharts opcionaltables opcionalModelo de render: los cálculos y umbrales deben precomputarse en tu pipeline de datos. Este esquema es para configuración de visualización y valores precomputados.
El campo $schema identifica la versión del contrato del payload y debe declararse
con su literal técnico correspondiente.
| Propiedad | Tipo | Requerido | Valor permitido | Descripción |
|---|---|---|---|---|
$schema |
string |
si | "dashboard-v1" |
Identificador de esquema consumido por documentación y herramientas de validación. |
schema-id.json
{
"$schema": "dashboard-v1",
"meta": {
"title": "Operations Dashboard"
}
}
El objeto meta controla la identidad del dashboard y el contexto de formato.
meta.title es obligatorio; el resto de propiedades son opcionales.
| Propiedad | Tipo | Requerido | Valores permitidos | Descripción |
|---|---|---|---|---|
title |
string |
si | Cualquier texto no vacío | Título principal del dashboard mostrado en la parte superior del render. |
description |
string |
no | Cualquier texto | Subtítulo o frase de contexto debajo del título. |
updated |
string |
no | Se recomienda fecha ISO 8601 | Marca de vigencia legible para usuarios finales. |
locale |
string |
no | BCP 47 locale (ex: es-EC, en-US) |
Usado por funciones formatter para renderizar número y moneda. |
meta-example.json
{
"meta": {
"title": "Claims Monitoring - Q1",
"description": "Monthly view for claims volume and spend patterns.",
"updated": "2026-03-18",
"locale": "es-EC"
}
}
Comportamiento de locale: las funciones formatter llaman a
Intl.NumberFormat con este valor. Si se omite, el fallback del renderer
es es-EC.
kpis es un arreglo de tarjetas mostrado cerca de la parte superior del dashboard. Los valores deben
venir agregados desde tu pipeline de datos.
| Propiedad | Tipo | Requerido | Valores permitidos | Descripción |
|---|---|---|---|---|
id |
string |
si | Identificador único | Clave estable para la entrada KPI. |
label |
string |
si | Cualquier etiqueta visible | Nombre corto del KPI mostrado en la tarjeta. |
value |
number | string |
si | Valor de métrica precomputado | Valor numérico principal o preformateado. |
format |
string |
no | currency | number | integer | percent | compact |
Formatter nombrado aplicado por el renderer. |
color |
string |
no | a | g | o | r | #hex |
Token de color/acento de tarjeta o color personalizado. |
delta |
string |
no | Texto con signo o flecha al inicio | Indicador de cambio; el renderer colorea según prefijo. |
a azul acento (#6c8cff)
g verde (#43a047)
o naranja (#fb8c00)
r rojo (#ef5350)
Reglas de color para delta: + o ^ se interpreta
como positivo; - como negativo; cualquier otro texto se renderiza en tono
neutro.
kpis-example.json
{
"kpis": [
{
"id": "claims_total",
"label": "Total Claims",
"value": 12840,
"format": "integer",
"color": "a",
"delta": "+4.8%"
},
{
"id": "spend_total",
"label": "Total Spend",
"value": 3289012.44,
"format": "currency",
"color": "g",
"delta": "-1.2%"
},
{
"id": "reject_rate",
"label": "Reject Rate",
"value": 5.33,
"format": "percent",
"color": "#7c3aed"
}
]
}
charts contiene bloques de configuración de Chart.js. Los datasets se pasan
directamente, por lo que se puede usar cualquier propiedad válida de dataset de Chart.js.
| Propiedad | Tipo | Requerido | Valores permitidos | Descripción |
|---|---|---|---|---|
id |
string |
si | Identificador único | ID de canvas en el resultado renderizado. |
type |
string |
si | Tipo de Chart.js (ver lista superior) | Define el modo de render del gráfico. |
datasets |
array |
si | Objetos dataset nativos de Chart.js | Payload de datos y opciones de estilo por serie. |
title |
string |
no | Cualquier texto | Título del gráfico sobre el canvas. |
subtitle |
string |
no | Cualquier texto | Subtítulo de apoyo debajo del título. |
width |
string |
no | full | half | third |
Sugerencia de layout para el ancho del contenedor del gráfico. |
labels |
array |
conditional | Arreglo de string/number | Requerido para gráficos no scatter; omitido para scatter. |
options |
object |
no | Opciones nativas de Chart.js | Soporta callbacks string "fmt:...". |
| Valor | Ancho aproximado | Caso de uso |
|---|---|---|
full |
100% | Gráficos principales de tendencia y series de tiempo amplias. |
half |
~50% | Dos gráficos lado a lado en layouts desktop. |
third |
~33% | Tarjetas compactas de comparación en grupos de tres. |
charts-example.json
{
"charts": [
{
"id": "monthly_spend",
"type": "bar",
"title": "Monthly Spend",
"subtitle": "Last 6 months",
"width": "half",
"labels": ["Oct", "Nov", "Dec", "Jan", "Feb", "Mar"],
"datasets": [
{
"label": "Spend",
"data": [240000, 260000, 280000, 310000, 295000, 325000],
"backgroundColor": "#6c8cff"
}
],
"options": {
"plugins": {
"tooltip": {
"callbacks": {
"label": "fmt:currency"
}
}
},
"scales": {
"y": {
"ticks": {
"callback": "fmt:compact"
}
}
}
}
}
]
}
Nota para scatter: los gráficos scatter usan puntos
{"x":...,"y":...} en datasets y normalmente omiten
labels de nivel superior.
tables define vistas tabulares ordenables y paginadas. Los metadatos de columnas controlan
etiquetas visibles, formato de celdas y alineación.
| Propiedad | Tipo | Requerido | Valores permitidos | Descripción |
|---|---|---|---|---|
id |
string |
si | Identificador único | Clave estable para la instancia del componente de tabla. |
title |
string |
no | Cualquier texto | Título de tabla mostrado sobre la fila de encabezado. |
columns |
array |
si | Objetos de definición de columna | Define el mapeo de campos y el comportamiento de visualización. |
data |
array |
si | Arreglo de objetos de fila | Registros crudos de tabla, un objeto por fila. |
pageSize |
integer |
no | Entero positivo | Filas por página; actualmente el fallback del renderer se comporta como 20. |
defaultSort |
object |
no | {field, direction} |
Configuración de orden inicial aplicada antes del primer render. |
| Propiedad | Tipo | Requerido | Valores permitidos | Descripción |
|---|---|---|---|---|
field |
string |
si | Clave del objeto de fila | Clave de datos a leer en cada fila de la tabla. |
label |
string |
si | Cualquier texto | Nombre visible de encabezado en la UI de tabla. |
format |
string |
no | currency | number | integer | percent | compact |
Formatter nombrado aplicado a cada celda de esa columna. |
align |
string |
no | left | center | right |
Alineación horizontal para celdas de encabezado y cuerpo. |
Nota de compatibilidad: los metadatos del esquema documentan
defaultSort.dir, mientras la lógica actual del renderer lee
defaultSort.direction. Para máxima compatibilidad, incluye ambas keys con
el mismo valor.
tables-example.json
{
"tables": [
{
"id": "patients_table",
"title": "Patient Detail",
"columns": [
{
"field": "patientId",
"label": "Patient",
"align": "left"
},
{
"field": "claims",
"label": "Claims",
"format": "integer",
"align": "right"
},
{
"field": "spend",
"label": "Spend",
"format": "currency",
"align": "right"
}
],
"data": [
{
"patientId": "P-1001",
"claims": 14,
"spend": 3200.5
},
{
"patientId": "P-1002",
"claims": 8,
"spend": 1780.0
}
],
"pageSize": 25,
"defaultSort": {
"field": "spend",
"direction": "desc",
"dir": "desc"
}
}
]
}
Este bloque muestra el archivo real de definición del schema. Se carga en runtime para evitar desalineación entre la documentación y el contrato fuente.
Se eligió esta estructura JSON porque define un contrato claro, único y autocontenido para representar un dashboard completo: meta para contexto, kpis para métricas resumen, charts para visualizaciones y tables para detalle tabular. Eso permite transformar fuentes de datos muy distintas a una misma forma de salida, sin mezclar lógica de negocio con lógica de render. En lugar de que el frontend tenga que interpretar casos especiales, el JSON ya llega precomputado y listo para mostrarse.
Es conveniente porque hace el sistema más portable, predecible y fácil de mantener. Al tener una estructura estable, el mismo renderer puede reutilizarse en distintos casos, se puede validar y documentar mejor, y también se vuelve más simple generar ejemplos, vistas previas y salidas desde procesos automáticos. Además, reduce acoplamientos innecesarios, facilita compartir una carpeta standalone y deja las opciones visuales en un formato declarativo que escala mejor con el tiempo.
El renderer incluye cinco formatters nombrados. En opciones de gráficos, los callbacks de formato se
representan como strings ("fmt:...") y se resuelven de forma segura en runtime.
| Formateador | Token de string | Ejemplo de entrada | Ejemplo de salida | Dónde se puede usar |
|---|---|---|---|---|
currency |
fmt:currency |
1234.5 |
$1,234.50 (según locale) |
KPI format, columna de tabla format, callbacks de gráficos |
number |
fmt:number |
1234.5 |
1,234.50 |
KPI format, columna de tabla format, callbacks de gráficos |
integer |
fmt:integer |
1234.5 |
1,235 |
KPI format, columna de tabla format, callbacks de gráficos |
percent |
fmt:percent |
5.2 |
5.20% |
KPI format, columna de tabla format, callbacks de gráficos |
compact |
fmt:compact |
1200000 |
1.2M (según locale) |
KPI format, columna de tabla format, callbacks de gráficos |
Cómo funciona la resolución: resolveFmtStrings() recorre
recursivamente options del gráfico, reemplaza cualquier string
"fmt:name" por una función formatter permitida y luego pasa el objeto
final a Chart.js.
formatter-callbacks.json
{
"charts": [
{
"id": "spend_trend",
"type": "line",
"labels": ["Jan", "Feb", "Mar"],
"datasets": [
{
"label": "Spend",
"data": [210000, 245000, 238000],
"borderColor": "#6c8cff",
"backgroundColor": "#6c8cff",
"tension": 0.25
}
],
"options": {
"plugins": {
"tooltip": {
"callbacks": {
"label": "fmt:currency"
}
}
},
"scales": {
"y": {
"ticks": {
"callback": "fmt:compact"
}
}
}
}
}
]
}
Estos patrones cubren configuraciones frecuentes y se mapean directamente con las capacidades del renderer.
Los colores se precomputan en tu generador de datos. El renderer solo pasa los arreglos a Chart.js tal como vienen.
pattern-conditional-colors.json
{
"charts": [
{
"id": "reject_rate_by_month",
"type": "bar",
"labels": ["Jan", "Feb", "Mar", "Apr"],
"datasets": [
{
"label": "Reject Rate",
"data": [2.3, 6.1, 3.9, 7.2],
"backgroundColor": ["#6c8cff", "#ef5350", "#6c8cff", "#ef5350"]
}
]
}
]
}
Usa yAxisID en cada dataset y define ambos ejes en
options.scales.
pattern-dual-axis.json
{
"charts": [
{
"id": "claims_vs_patients",
"type": "bar",
"labels": ["Jan", "Feb", "Mar"],
"datasets": [
{
"type": "line",
"label": "Claims",
"data": [1200, 1320, 1250],
"yAxisID": "y",
"borderColor": "#6c8cff",
"backgroundColor": "#6c8cff",
"tension": 0.25
},
{
"type": "bar",
"label": "Unique Patients",
"data": [820, 860, 845],
"yAxisID": "y1",
"backgroundColor": "#43a047"
}
],
"options": {
"scales": {
"y": {
"position": "left"
},
"y1": {
"position": "right",
"grid": {
"drawOnChartArea": false
}
}
}
}
}
]
}
Las barras horizontales son gráficos de barras estándar con
indexAxis: "y" en options.
pattern-horizontal-bar.json
{
"charts": [
{
"id": "top_patients_spend",
"type": "bar",
"title": "Top 10 Patients by Spend",
"labels": ["P-1001", "P-1204", "P-1008", "P-1122"],
"datasets": [
{
"label": "Spend",
"data": [6300, 5880, 5420, 5195],
"backgroundColor": "#6c8cff"
}
],
"options": {
"indexAxis": "y",
"scales": {
"x": {
"ticks": {
"callback": "fmt:currency"
}
}
}
}
}
]
}
Los datasets scatter usan objetos de puntos con valores x y y.
El campo labels de nivel superior normalmente se omite.
pattern-scatter.json
{
"charts": [
{
"id": "frequency_vs_controls",
"type": "scatter",
"datasets": [
{
"label": "Patient points",
"data": [
{ "x": 30, "y": 4 },
{ "x": 45, "y": 6 },
{ "x": 21, "y": 3 },
{ "x": 60, "y": 8 }
],
"backgroundColor": ["#6c8cff", "#ef5350", "#6c8cff", "#ef5350"],
"pointRadius": 5
}
],
"options": {
"scales": {
"x": {
"title": { "display": true, "text": "Frequency (days)" }
},
"y": {
"title": { "display": true, "text": "Controls" }
}
}
}
}
]
}
Usa un dataset con valores por categoría. Funciona para rangos de edad, división por estado o cualquier resumen de distribución.
pattern-doughnut.json
{
"charts": [
{
"id": "age_distribution",
"type": "doughnut",
"title": "Age Distribution",
"labels": ["18-24", "25-34", "35-44", "45+"],
"datasets": [
{
"label": "Patients",
"data": [34, 78, 65, 21],
"backgroundColor": ["#6c8cff", "#43a047", "#fb8c00", "#ef5350"]
}
]
}
]
}
Mantiene callbacks como tokens string en JSON. El renderer los resuelve antes de inicializar el gráfico.
pattern-fmt-callbacks.json
{
"charts": [
{
"id": "monthly_cost",
"type": "line",
"labels": ["Jan", "Feb", "Mar"],
"datasets": [
{
"label": "Cost",
"data": [80000, 93000, 91000],
"borderColor": "#6c8cff",
"backgroundColor": "#6c8cff"
}
],
"options": {
"plugins": {
"tooltip": {
"callbacks": {
"label": "fmt:currency"
}
}
},
"scales": {
"y": {
"ticks": {
"callback": "fmt:compact"
}
}
}
}
}
]
}
Este ejemplo completo combina meta, kpis,
charts y tables en un solo payload.
meta: identidad del dashboard y contexto de locale.kpis: métricas resumen precomputadas con tokens de formato/color.charts: visualizaciones de tendencia + distribución + scatter.tables: registros de detalle paginados y ordenables.
schema-full-example.json
{
"$schema": "dashboard-v1",
"meta": {
"title": "Healthcare Claims Dashboard",
"description": "Quarterly overview of volume, spend, and patient-level distribution.",
"updated": "2026-03-18",
"locale": "es-EC"
},
"kpis": [
{
"id": "claims_total",
"label": "Total Claims",
"value": 12840,
"format": "integer",
"color": "a",
"delta": "+4.8%"
},
{
"id": "spend_total",
"label": "Total Spend",
"value": 3289012.44,
"format": "currency",
"color": "g",
"delta": "-1.2%"
},
{
"id": "reject_rate",
"label": "Reject Rate",
"value": 5.33,
"format": "percent",
"color": "o"
}
],
"charts": [
{
"id": "monthly_spend",
"type": "line",
"title": "Monthly Spend",
"width": "half",
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
"datasets": [
{
"label": "Spend",
"data": [245000, 261500, 258000, 277200, 294000, 310500],
"borderColor": "#6c8cff",
"backgroundColor": "#6c8cff",
"tension": 0.25
}
],
"options": {
"plugins": {
"tooltip": {
"callbacks": {
"label": "fmt:currency"
}
}
},
"scales": {
"y": {
"ticks": {
"callback": "fmt:compact"
}
}
}
}
},
{
"id": "reject_rate_by_month",
"type": "bar",
"title": "Reject Rate by Month",
"width": "half",
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
"datasets": [
{
"label": "Reject Rate",
"data": [3.4, 5.1, 4.0, 6.3, 4.6, 5.8],
"backgroundColor": ["#6c8cff", "#ef5350", "#6c8cff", "#ef5350", "#6c8cff", "#ef5350"]
}
],
"options": {
"scales": {
"y": {
"ticks": {
"callback": "fmt:percent"
}
}
}
}
},
{
"id": "frequency_vs_controls",
"type": "scatter",
"title": "Frequency vs Controls",
"width": "full",
"datasets": [
{
"label": "Patients",
"data": [
{ "x": 21, "y": 3 },
{ "x": 35, "y": 4 },
{ "x": 42, "y": 6 },
{ "x": 57, "y": 8 }
],
"backgroundColor": ["#6c8cff", "#6c8cff", "#ef5350", "#ef5350"],
"pointRadius": 5
}
]
}
],
"tables": [
{
"id": "patients_detail",
"title": "Patient Detail",
"columns": [
{
"field": "patientId",
"label": "Patient",
"align": "left"
},
{
"field": "claims",
"label": "Claims",
"format": "integer",
"align": "right"
},
{
"field": "spend",
"label": "Spend",
"format": "currency",
"align": "right"
}
],
"data": [
{
"patientId": "P-1001",
"claims": 14,
"spend": 3200.5
},
{
"patientId": "P-1002",
"claims": 8,
"spend": 1780.0
},
{
"patientId": "P-1003",
"claims": 17,
"spend": 4120.3
}
],
"pageSize": 25,
"defaultSort": {
"field": "spend",
"direction": "desc",
"dir": "desc"
}
}
]
}
defaultSort.dir, pero el renderer lee defaultSort.direction.{x,y} y generalmente omitir labels de nivel superior.id únicos y estables por arreglo de componentes para mantenibilidad y depuración.pageSize.meta.locale cambia separadores numéricos y visualización de moneda mediante Intl.NumberFormat.Recomendación: si generas JSON desde código, agrega un paso de validación que verifique campos requeridos y aplique convenciones de formatter/token antes de publicar.
Esta sección permite revisar los archivos reales en formato legible y abrir una vista previa renderizada sin salir de la documentación.
Patrón mensual con series temporales y tabla consolidada
Patrón de detalle por paciente con dispersión
Patrón de alto volumen con tabla extensa