En este módulo, aprenderemos a crear visualizaciones avanzadas utilizando diseños de fuerza en D3.js. Los diseños de fuerza son útiles para representar datos como grafos, redes y otros tipos de relaciones entre nodos. Este tipo de visualización es interactiva y puede ser muy efectiva para mostrar conexiones complejas.

Conceptos Clave

Antes de sumergirnos en el código, es importante entender algunos conceptos clave:

  • Nodos: Representan los elementos individuales en el gráfico.
  • Enlaces: Representan las conexiones entre los nodos.
  • Fuerzas: Reglas que determinan cómo los nodos y enlaces interactúan entre sí.

Configuración Básica

Paso 1: Configurar el Entorno

Asegúrate de tener un entorno de desarrollo configurado con D3.js. Puedes incluir D3.js en tu proyecto mediante un CDN:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Force Layout</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .node {
            fill: #69b3a2;
            stroke: #fff;
            stroke-width: 1.5px;
        }
        .link {
            stroke: #999;
            stroke-opacity: 0.6;
        }
    </style>
</head>
<body>
    <svg width="800" height="600"></svg>
    <script src="force-layout.js"></script>
</body>
</html>

Paso 2: Crear el Archivo JavaScript

Crea un archivo force-layout.js donde escribiremos el código para nuestro diseño de fuerza.

Implementación del Diseño de Fuerza

Paso 3: Definir los Datos

Primero, definimos los datos para los nodos y enlaces:

const nodes = [
    { id: 1, group: 1 },
    { id: 2, group: 1 },
    { id: 3, group: 2 },
    { id: 4, group: 2 },
    { id: 5, group: 3 }
];

const links = [
    { source: 1, target: 2 },
    { source: 1, target: 3 },
    { source: 2, target: 4 },
    { source: 3, target: 5 },
    { source: 4, target: 5 }
];

Paso 4: Crear el Simulador de Fuerza

Usamos d3.forceSimulation para crear el simulador de fuerza:

const simulation = d3.forceSimulation(nodes)
    .force("link", d3.forceLink(links).id(d => d.id))
    .force("charge", d3.forceManyBody().strength(-200))
    .force("center", d3.forceCenter(400, 300));

Paso 5: Dibujar los Enlaces

Usamos svg para dibujar los enlaces:

const svg = d3.select("svg");

const link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(links)
    .enter().append("line")
    .attr("class", "link");

Paso 6: Dibujar los Nodos

Usamos svg para dibujar los nodos:

const node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(nodes)
    .enter().append("circle")
    .attr("class", "node")
    .attr("r", 10)
    .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

Paso 7: Actualizar la Simulación

Actualizamos la simulación en cada "tick":

simulation.on("tick", () => {
    link
        .attr("x1", d => d.source.x)
        .attr("y1", d => d.source.y)
        .attr("x2", d => d.target.x)
        .attr("y2", d => d.target.y);

    node
        .attr("cx", d => d.x)
        .attr("cy", d => d.y);
});

Paso 8: Manejar el Arrastre de Nodos

Definimos las funciones para manejar el arrastre de nodos:

function dragstarted(event, d) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
}

function dragged(event, d) {
    d.fx = event.x;
    d.fy = event.y;
}

function dragended(event, d) {
    if (!event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
}

Ejercicio Práctico

Ejercicio 1: Añadir Etiquetas a los Nodos

Añade etiquetas a los nodos para mostrar sus identificadores.

Solución:

const label = svg.append("g")
    .attr("class", "labels")
    .selectAll("text")
    .data(nodes)
    .enter().append("text")
    .attr("class", "label")
    .text(d => d.id);

simulation.on("tick", () => {
    link
        .attr("x1", d => d.source.x)
        .attr("y1", d => d.source.y)
        .attr("x2", d => d.target.x)
        .attr("y2", d => d.target.y);

    node
        .attr("cx", d => d.x)
        .attr("cy", d => d.y);

    label
        .attr("x", d => d.x + 12)
        .attr("y", d => d.y + 3);
});

Conclusión

En esta sección, hemos aprendido a crear un diseño de fuerza básico utilizando D3.js. Hemos cubierto cómo definir nodos y enlaces, crear un simulador de fuerza, y dibujar y actualizar los elementos SVG. Además, hemos añadido interactividad mediante el arrastre de nodos. En el siguiente módulo, exploraremos cómo crear mapas geográficos utilizando D3.js.

D3.js: De Principiante a Avanzado

Módulo 1: Introducción a D3.js

Módulo 2: Trabajando con Selecciones

Módulo 3: Datos y Escalas

Módulo 4: Creando Visualizaciones Básicas

Módulo 5: Visualizaciones Avanzadas

Módulo 6: Interactividad y Animación

Módulo 7: Trabajando con Datos Reales

Módulo 8: Rendimiento y Optimización

Módulo 9: Mejores Prácticas y Técnicas Avanzadas

Módulo 10: Proyecto Final

© Copyright 2024. Todos los derechos reservados