---
type: Resumen
title: "Estudio — Visualización de Datos con JS (15 librerías · Monterail)"
description: "Estudio de monterail-dataviz publicado como sitio: scripts minimalistas para implementarlo y cómo se conecta con el OKF."
resource: "https://gerardoesquivia.com/monterail-dataviz/"
status: publicado
tags: [estudio, monterail-dataviz, scripts-minimalistas, documentacion, okf]
timestamp: 2026-10-04
creator: "Gerardo Esquivia Zapata"
grafo: datos
---
# Estudio — Visualización de Datos con JS (15 librerías · Monterail)
> **Sitio publicado:** https://gerardoesquivia.com/monterail-dataviz/
> **Nota generada del sitio** para que el estudio regrese al OKF (REGLA del ciclo:
> la documentación no está completa hasta estar publicada **Y** registrada).
## Cómo usarla
Los **scripts minimalistas** de abajo se copian y funcionan. Esa es la parte que vale:
la prosa se lee y se olvida; un script se pega y arranca.
---
## 1 · Comparativa de las 15 a un vistazo
| Librería | Rendering | Licencia | Mejor ajuste |
| --- | --- | --- | --- |
| D3.js | SVG (+Canvas) | ISC (open) | El gráfico es el producto |
| Recharts | SVG | MIT | Dashboards en React |
| Victory | SVG | MIT | Web + React Native |
| Chartkick | Delegado | MIT | Una línea, stacks mixtos |
| Flexmonster | Pivot + charts | Comercial | Pivotes enterprise |
| WebDataRocks | Pivot + charts | Free | Pivotes pequeños |
| ApexCharts | SVG | MIT | Dashboards pulidos rápido |
| Chart.js | Canvas | MIT | El default estándar |
| Apache ECharts | Canvas/SVG/WebGL | Apache 2.0 | Datasets gigantes, enterprise |
| Nivo | Canvas/SVG/HTML | MIT | React + SSR |
| amCharts | Canvas (v5) | Free+backlink / $90–180 | Pulido + soporte |
| CanvasJS | Canvas | Comercial | Rendimiento bruto |
| Highcharts | SVG + boost | Comercial (free edu) | Enterprise/reguladas |
| ZoomCharts | Canvas | Comercial | Touch-first |
| Vega / Vega-Lite | Canvas o SVG | BSD-3 | Declarativa por spec |
🧠 Rendering = techo: SVG crea un nodo DOM por punto (flexible, accesible, pero lento
pasados ~10k). Canvas dibuja píxeles (rápido a escala, pero hay que reimplementar la
interacción). WebGL usa la GPU (scatter 3D, streams real-time).
## 2 · Las 15 librerías
### 🛠️ D3.js — el estándar para visualizaciones custom
```
// script minimalista (d3-scale — seleccionar escala)
import { scaleLinear } from 'd3-scale';
const x = scaleLinear().domain([0, 100]).range([0, 500]);
console.log(x(50)); // 250
```
Stars 112k · SVG · Open source (ISC) · Mantenido por Observable. "The JavaScript library for bespoke data visualization". Curva alta, máxima flexibilidad. En React: módulos no-DOM (d3-scale, d3-array) en JSX; módulos DOM (d3-selection) con ref + useEffect.
### ⚛️ Recharts — gráficos React declarativos
```
// npm i recharts
import { BarChart, Bar } from 'recharts';
```
Stars 26k · SVG · MIT · Encima de D3 con componentes nativos de React. Leyendas, tooltips y labels integrados. TypeScript sólido. >470 issues abiertos.
### 📱 Victory — React Native cross-platform
```
// npm i victory
import { VictoryBar } from 'victory';
```
Stars 11.2k · SVG · MIT · Componentes modulares para React y React Native (Nearform). ARIA fuerte out-of-the-box. API consistente web/móvil.
### 📈 Chart.js — el default (Canvas)
```
// npm i chart.js
import Chart from 'chart.js/auto';
new Chart(document.getElementById('g'), {
type: 'bar',
data: { labels: ['A','B'], datasets: [{ data: [10, 20] }] },
});
```
Stars 66.6k · Canvas · MIT · La más descargada (millones/semana). 8 tipos core (~16 con extensiones). v4+: tree-shaking, mejor TypeScript. Friendly para principiantes.
### 🚀 Apache ECharts — enterprise a escala
```
// npm i echarts
import * as echarts from 'echarts';
const chart = echarts.init(document.getElementById('g'));
chart.setOption({ xAxis: {}, yAxis: {}, series: [{ type: 'bar', data: [5,20] }] });
```
Stars 64.7k · Canvas/SVG/WebGL (GL) · Apache 2.0 · Antes Baidu, ahora Apache. >20 tipos, progressive rendering, TypedArray; documenta 10M puntos en real-time. v6 actual.
### 🧩 ApexCharts · Nivo · Chartkick
| Librería | Rendering | Stars | Detalle |
| --- | --- | --- | --- |
| ApexCharts | SVG · MIT | 14.9k | Zoom/pan/scroll/anotaciones, >12 tipos, mixed charts. Techo SVG ~miles de puntos. Dashboards atractivos rápido. |
| Nivo | Canvas/SVG/HTML · MIT | 13.8k | React sobre D3, SSR con react-spring, playground en nivo.rocks. Defaults fuertes. |
| Chartkick | Delegado · MIT | 1.2k | "One line of JavaScript" sobre Chart.js/Google/Highcharts. Multi-lenguaje (Vue, React, Python, Ruby…). |
### 🏢 Comerciales: Flexmonster · WebDataRocks · amCharts · CanvasJS · Highcharts · ZoomCharts
| Librería | Rendering | Licencia | Detalle |
| --- | --- | --- | --- |
| Flexmonster | Pivot+charts | $0 trial → $799+ | Hasta 1GB/1M registros; JSON, CSV, SQL, MongoDB, ES, MSAS. Pivotes enterprise. |
| WebDataRocks | Pivot+charts | Free | Del equipo de Flexmonster; 1MB, solo CSV/JSON. Pequeños y prototipos. |
| amCharts | Canvas (v5) | Free+backlink / $90–180 | Pulido visual (Apple, Amazon, NASA). ~400KB core, TS completo. Mapas, Sankey, treemap. |
| CanvasJS | Canvas | Comercial | "10x más rápido"; 100k+ puntos. >30 tipos. Faltan network/sparklines/gauges. |
| Highcharts | SVG + boost | Comercial (free edu) | 80 de las top 100 empresas. Stock, maps, Gantt. boost = millones de puntos. ~76% TS. |
| ZoomCharts | Canvas | Comercial | Multi-touch (Time/Net/Geo/Pie/Face). Exploración touch-first. |
⚠️ Licencias ANTES de construir: 4 de 15 son comerciales y 1 es free con backlink
(decisión de marca/legal). Los claims de vendor (10x/20x, máximos de puntos) hay que
benchmarkear con tus propios datos.
### 🧬 Vega / Vega-Lite — gramática declarativa
```
// Vega-Lite spec (declarativo)
{ "mark": "bar",
"data": { "values": [{a:"A",b:10},{a:"B",b:20}] },
"encoding": { "x": {"field":"a"}, "y": {"field":"b"} } }
```
Stars 11.7k · Canvas o SVG · BSD-3 · UW Interactive Data Lab. Spec JSON declarativa: describes QUÉ visualizar y Vega resuelve CÓMO. Vega-Lite es más conciso; ambos compilan al mismo engine. Python vía Altair.
## 3 · Cómo elegir (8 preguntas en orden)
- ¿Qué tipos de charts? (Sankey/Gantt elimina opciones rápidamente)
- ¿Tamaño del dataset? — responde con tu peor caso realista
- ¿Web, móvil o ambos? — Victory = React Native
- ¿Soporte de navegadores? — según tus analíticas
- ¿Qué framework? — React → Recharts/Nivo; agnóstico → Chart.js/D3/ECharts
- ¿Personalización visual? — D3 = máximo control/esfuerzo
- ¿TypeScript? — Recharts, Highcharts, amCharts fuertes
- ¿Activa? — GitHub, cadencia, issues, comunidad
💡 Librería vs desde cero: usa librería para charts estándar con tooltips/leyendas/ejes y
time-to-market. Construye desde cero solo si el gráfico es un diferenciador competitivo del producto.
## 4 · Grafo animado — el flujo de decisión
El token 🟠 recorre la decisión en orden. Clic en el gráfico reinicia.
Iniciando…
## 5 · Claves y referencia
| Decisión | Opción recomendada |
| --- | --- |
| Charts estándar | Chart.js |
| Escala (millones de puntos) | Apache ECharts |
| React | Recharts o Nivo |
| El gráfico es el producto | D3.js |
| React Native cross-platform | Victory |
| Enterprise con soporte | Highcharts / amCharts |
| Declarativa / análisis | Vega / Vega-Lite |
📦 Regla de librerías (local primero): revisar
C:\Users\TUF\Documents\librerías\local\ antes de descargar.
Fuente: https://www.monterail.com/blog/javascript-libraries-data-visualization.
Se enlaza con el catálogo de 66: D3.js, Chart.js y Highcharts están en ambos.
📱 Escanéalo para abrir la documentación
https://gerardoesquivia.com/monterail-dataviz/
Visualización de Datos con JS · 15 librerías (Monterail) · OKF de Gerardo Esquivia Zapata · 2026-08-30
(function () {
const nodes = [
{ id: "chart", label: "Tipos de chart", sub: "¿Sankey/Gantt?", x: 70, y: 200 },
{ id: "data", label: "Tamaño dataset", sub: "peor caso", x: 300, y: 80 },
{ id: "fw", label: "Framework", sub: "React? Vue?", x: 300, y: 320 },
{ id: "lic", label: "Licencia", sub: "comercial?", x: 640, y: 200 },
{ id: "pick", label: "Elegir", sub: "shortlist 2-3", x: 880, y: 200 },
];
const edges = [
{ from: "chart", to: "data", label: "tipo", loop: false },
{ from: "data", to: "fw", label: "plataforma", loop: false },
{ from: "fw", to: "lic", label: "stack", loop: false },
{ from: "lic", to: "pick", label: "acota", loop: false },
{ from: "pick", to: "chart", label: "revisa", loop: false },
];
const pos = Object.fromEntries(nodes.map(n => [n.id, { x: n.x, y: n.y }]));
const svg = document.getElementById("grafo");
const NS = "http://www.w3.org/2000/svg";
function el(tag, attrs) { const e = document.createElementNS(NS, tag); for (const k in attrs) e.setAttribute(k, attrs[k]); return e; }
const edgePaths = [], edgeArrows = [];
edges.forEach((ed) => {
const a = pos[ed.from], b = pos[ed.to];
let d, mid;
if (ed.from === "pick") {
d = `M ${a.x} ${a.y} C ${(a.x+b.x)/2} 460, ${(a.x+b.x)/2} 460, ${b.x} ${b.y}`;
mid = { x: (a.x + b.x) / 2, y: 400 };
} else {
const dx = Math.abs(b.x - a.x), dy = Math.abs(b.y - a.y);
if (dy > dx) { const my = (a.y+b.y)/2; d = `M ${a.x} ${a.y} C ${a.x} ${my}, ${b.x} ${my}, ${b.x} ${b.y}`; mid = { x: (a.x+b.x)/2, y: my }; }
else { const mx = (a.x+b.x)/2; d = `M ${a.x} ${a.y} C ${mx} ${a.y}, ${mx} ${b.y}, ${b.x} ${b.y}`; mid = { x: mx, y: (a.y+b.y)/2 }; }
}
const path = el("path", { class: "edge", d }); svg.appendChild(path); edgePaths.push(path);
const ang = Math.atan2(b.y - mid.y, b.x - mid.x);
const tx = b.x - 18 * Math.cos(ang), ty = b.y - 18 * Math.sin(ang);
const arrow = el("path", { class: "arrow", d: `M ${tx} ${ty} l 8 ${-4} l -8 ${-4} z`, transform: `rotate(${ang*180/Math.PI} ${tx} ${ty})` });
svg.appendChild(arrow); edgeArrows.push(arrow);
});
const nodeGroups = {};
nodes.forEach(n => {
const g = el("g", { class: "node" });
g.appendChild(el("rect", { x: n.x - 70, y: n.y - 29, width: 140, height: 58 }));
const t = el("text", { class: "t", x: n.x, y: n.y - 4, "text-anchor": "middle" }); t.textContent = n.label;
const s = el("text", { class: "s", x: n.x, y: n.y + 16, "text-anchor": "middle" }); s.textContent = n.sub;
g.appendChild(t); g.appendChild(s); svg.appendChild(g); nodeGroups[n.id] = g;
});
const travel = el("circle", { class: "travel", r: 6, opacity: 0 });
svg.appendChild(travel);
const caption = document.getElementById("caption");
const N = edges.length;
let i = 0, raf = null;
function clearActive() { nodes.forEach(n => nodeGroups[n.id].classList.remove("active")); edgePaths.forEach(p => p.classList.remove("active")); edgeArrows.forEach(a => a.classList.remove("active")); }
function animateEdge(idx) {
const ed = edges[idx];
clearActive();
edgePaths[idx].classList.add("active"); edgeArrows[idx].classList.add("active");
nodeGroups[ed.from].classList.add("active");
caption.innerHTML = `Paso ${idx+1}/${N}: ${ed.from} → ${ed.to} (${ed.label})`;
const path = edgePaths[idx], len = path.getTotalLength();
const t0 = performance.now(), dur = 900;
function step(now) { let p = (now-t0)/dur; if (p>1) p=1; const pt = path.getPointAtLength(p*len); travel.setAttribute("cx", pt.x); travel.setAttribute("cy", pt.y); travel.setAttribute("opacity", 1); if (p animateEdge(i), 320); } }
raf = requestAnimationFrame(step);
}
function start() { cancelAnimationFrame(raf); i = 0; animateEdge(0); }
svg.addEventListener("click", start);
start();
})();
---
type: Resumen
title: "🌐 Estudio: Visualización de Datos con JS — 15 Librerías (Monterail)"
description: "Nota OKF del artículo de Monterail: 15 librerías JS de visualización de datos comparadas por renderizado (SVG/Canvas/WebGL), framework y licencia, con guía de elección."
fuente: "https://www.monterail.com/blog/javascript-libraries-data-visualization"
sitio: "https://gerardoesquivia.com/monterail-dataviz/"
tags: [resumen, javascript, visualizacion, datos, charting, monterail, okf]
timestamp: 2026-08-30
creator: "Gerardo Esquivia Zapata"
---
# 🌐 Visualización de Datos con JS — 15 Librerías (Monterail)
> **Para qué:** elegir la librería de charts correcta según el renderizado (SVG/Canvas/WebGL), el framework y la licencia, evitando el error costoso de reescribir el dashboard.
> **Cómo:** comparar en 4 ejes en orden — techo del dataset, modelo de renderizado, encaje con framework y exposición de licencia. Sitio: https://gerardoesquivia.com/monterail-dataviz/
## 🎯 Para qué sirve
- Elegir librería de visualización según tipo de chart, tamaño de dataset, framework y licencia.
- Entender que el modelo de renderizado (SVG
function descargarMD() {
const md = document.getElementById('md-resumen').textContent.trim();
const blob = new Blob([md], { type: 'text/markdown;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'resumen-monterail-dataviz.md';
document.body.appendChild(a); a.click(); a.remove();
URL.revokeObjectURL(url);
}
---
## Cómo se conecta con el OKF
- **Sitio:** https://gerardoesquivia.com/monterail-dataviz/
- **Nota:** esta (bajada del sitio, para consulta del agente)
- **Fuente:** https://gerardoesquivia.com/monterail-dataviz/
## Aprendizajes
- Los scripts minimalistas son el activo: **el ejemplo más corto que demuestra el uso**.
- Este estudio forma parte del ciclo: **estudiar → publicar → registrar en el OKF**.