--- 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**.