La interactividad es una de las características más poderosas de D3.js, permitiendo a los usuarios interactuar con las visualizaciones de datos de manera dinámica. En esta sección, aprenderemos cómo añadir interactividad a nuestras visualizaciones utilizando D3.js.
Conceptos Clave
- Eventos del DOM: D3.js permite manejar eventos del DOM como
click
,mouseover
,mouseout
, etc. - Manejadores de Eventos: Funciones que se ejecutan en respuesta a eventos del DOM.
- Transiciones: Cambios animados en los atributos de los elementos del DOM.
Ejemplo Práctico: Añadiendo Interactividad a un Gráfico de Barras
Paso 1: Crear un Gráfico de Barras Básico
Primero, crearemos un gráfico de barras básico. Si no estás familiarizado con la creación de gráficos de barras en D3.js, revisa la sección "Creando Gráficos de Barras" del Módulo 4.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Gráfico de Barras Interactivo</title> <script src="https://d3js.org/d3.v6.min.js"></script> <style> .bar { fill: steelblue; } .bar:hover { fill: orange; } </style> </head> <body> <svg width="600" height="400"></svg> <script> const data = [30, 86, 168, 281, 303, 365]; const svg = d3.select("svg"); const width = +svg.attr("width"); const height = +svg.attr("height"); const x = d3.scaleBand() .domain(d3.range(data.length)) .range([0, width]) .padding(0.1); const y = d3.scaleLinear() .domain([0, d3.max(data)]) .nice() .range([height, 0]); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", (d, i) => x(i)) .attr("y", d => y(d)) .attr("width", x.bandwidth()) .attr("height", d => height - y(d)); </script> </body> </html>
Paso 2: Añadir Interactividad
Ahora, añadiremos interactividad al gráfico de barras. Queremos que las barras cambien de color cuando el usuario pase el ratón sobre ellas y que muestren un tooltip con el valor de la barra.
Añadir Manejadores de Eventos
Utilizaremos los eventos mouseover
y mouseout
para cambiar el color de las barras y mostrar/ocultar el tooltip.
// Añadir manejadores de eventos svg.selectAll(".bar") .on("mouseover", function(event, d) { d3.select(this).attr("fill", "orange"); tooltip.style("display", null); }) .on("mouseout", function(event, d) { d3.select(this).attr("fill", "steelblue"); tooltip.style("display", "none"); }) .on("mousemove", function(event, d) { const [x, y] = d3.pointer(event); tooltip.attr("transform", `translate(${x},${y})`); tooltip.select("text").text(d); });
Crear el Tooltip
Añadiremos un grupo g
al SVG para el tooltip, que contendrá un rectángulo y un texto.
// Crear el tooltip const tooltip = svg.append("g") .attr("class", "tooltip") .style("display", "none"); tooltip.append("rect") .attr("width", 30) .attr("height", 20) .attr("fill", "white") .style("opacity", 0.5); tooltip.append("text") .attr("x", 15) .attr("dy", "1.2em") .style("text-anchor", "middle") .attr("font-size", "12px") .attr("font-family", "sans-serif");
Código Completo
Aquí está el código completo con la interactividad añadida:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Gráfico de Barras Interactivo</title> <script src="https://d3js.org/d3.v6.min.js"></script> <style> .bar { fill: steelblue; } .bar:hover { fill: orange; } </style> </head> <body> <svg width="600" height="400"></svg> <script> const data = [30, 86, 168, 281, 303, 365]; const svg = d3.select("svg"); const width = +svg.attr("width"); const height = +svg.attr("height"); const x = d3.scaleBand() .domain(d3.range(data.length)) .range([0, width]) .padding(0.1); const y = d3.scaleLinear() .domain([0, d3.max(data)]) .nice() .range([height, 0]); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", (d, i) => x(i)) .attr("y", d => y(d)) .attr("width", x.bandwidth()) .attr("height", d => height - y(d)) .on("mouseover", function(event, d) { d3.select(this).attr("fill", "orange"); tooltip.style("display", null); }) .on("mouseout", function(event, d) { d3.select(this).attr("fill", "steelblue"); tooltip.style("display", "none"); }) .on("mousemove", function(event, d) { const [x, y] = d3.pointer(event); tooltip.attr("transform", `translate(${x},${y})`); tooltip.select("text").text(d); }); // Crear el tooltip const tooltip = svg.append("g") .attr("class", "tooltip") .style("display", "none"); tooltip.append("rect") .attr("width", 30) .attr("height", 20) .attr("fill", "white") .style("opacity", 0.5); tooltip.append("text") .attr("x", 15) .attr("dy", "1.2em") .style("text-anchor", "middle") .attr("font-size", "12px") .attr("font-family", "sans-serif"); </script> </body> </html>
Ejercicio Práctico
Ejercicio 1: Añadir Interactividad a un Gráfico de Líneas
- Crea un gráfico de líneas básico.
- Añade interactividad para que la línea cambie de color cuando el usuario pase el ratón sobre ella.
- Muestra un tooltip con el valor de
y
en el punto donde el usuario pasa el ratón.
Solución
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Gráfico de Líneas Interactivo</title> <script src="https://d3js.org/d3.v6.min.js"></script> <style> .line { fill: none; stroke: steelblue; stroke-width: 2px; } .line:hover { stroke: orange; } </style> </head> <body> <svg width="600" height="400"></svg> <script> const data = [30, 86, 168, 281, 303, 365]; const svg = d3.select("svg"); const width = +svg.attr("width"); const height = +svg.attr("height"); const x = d3.scaleLinear() .domain([0, data.length - 1]) .range([0, width]); const y = d3.scaleLinear() .domain([0, d3.max(data)]) .nice() .range([height, 0]); const line = d3.line() .x((d, i) => x(i)) .y(d => y(d)); svg.append("path") .datum(data) .attr("class", "line") .attr("d", line) .on("mouseover", function(event, d) { d3.select(this).attr("stroke", "orange"); tooltip.style("display", null); }) .on("mouseout", function(event, d) { d3.select(this).attr("stroke", "steelblue"); tooltip.style("display", "none"); }) .on("mousemove", function(event, d) { const [xPos, yPos] = d3.pointer(event); const index = Math.round(x.invert(xPos)); const value = data[index]; tooltip.attr("transform", `translate(${xPos},${yPos})`); tooltip.select("text").text(value); }); // Crear el tooltip const tooltip = svg.append("g") .attr("class", "tooltip") .style("display", "none"); tooltip.append("rect") .attr("width", 30) .attr("height", 20) .attr("fill", "white") .style("opacity", 0.5); tooltip.append("text") .attr("x", 15) .attr("dy", "1.2em") .style("text-anchor", "middle") .attr("font-size", "12px") .attr("font-family", "sans-serif"); </script> </body> </html>
Conclusión
En esta sección, hemos aprendido cómo añadir interactividad a nuestras visualizaciones de D3.js utilizando eventos del DOM y manejadores de eventos. Hemos visto cómo cambiar el color de los elementos y mostrar tooltips en respuesta a eventos del usuario. La interactividad mejora significativamente la experiencia del usuario y hace que las visualizaciones sean más atractivas y útiles.
En la siguiente sección, profundizaremos en cómo manejar eventos de manera más avanzada y cómo crear transiciones y animaciones para nuestras visualizaciones.
D3.js: De Principiante a Avanzado
Módulo 1: Introducción a D3.js
Módulo 2: Trabajando con Selecciones
- Entendiendo las Selecciones
- Seleccionando Elementos del DOM
- Modificando Elementos
- Vinculando Datos a Elementos
Módulo 3: Datos y Escalas
- Cargando y Analizando Datos
- Usando Escalas de D3
- Escalas Lineales y Ordinales
- Escalas de Tiempo y Logarítmicas
Módulo 4: Creando Visualizaciones Básicas
- Creando Gráficos de Barras
- Creando Gráficos de Líneas
- Creando Gráficos de Pastel
- Creando Diagramas de Dispersión
Módulo 5: Visualizaciones Avanzadas
- Creando Diseños Jerárquicos
- Creando Diseños de Fuerza
- Creando Mapas Geográficos
- Creando Visualizaciones Personalizadas
Módulo 6: Interactividad y Animación
Módulo 7: Trabajando con Datos Reales
- Obteniendo Datos de APIs
- Limpieza y Transformación de Datos
- Integración con Otras Bibliotecas
- Estudios de Caso y Ejemplos
Módulo 8: Rendimiento y Optimización
- Optimizando el Rendimiento de D3.js
- Manejando Grandes Conjuntos de Datos
- Vinculación de Datos Eficiente
- Depuración y Solución de Problemas
Módulo 9: Mejores Prácticas y Técnicas Avanzadas
- Organización del Código y Modularidad
- Componentes Reutilizables
- Patrones Avanzados de D3.js
- Contribuyendo a la Comunidad de D3.js