En aquest tema, aprendrem a crear visualitzacions utilitzant disposicions de força amb D3.js. Les disposicions de força són útils per crear gràfics de xarxa, on els nodes i els enllaços es distribueixen de manera dinàmica segons forces simulades, com la gravetat, la repulsió i l'atracció.
Conceptes Clau
Abans de començar amb els exemples pràctics, és important entendre alguns conceptes clau:
- Nodes: Representen els elements individuals de la xarxa.
- Enllaços: Representen les connexions entre els nodes.
- Força: Simulació física que determina com es distribueixen els nodes i els enllaços.
Configuració Bàsica
HTML
Comencem amb una estructura HTML bàsica:
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<title>Disposició de Força amb D3.js</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>JavaScript
Creem un fitxer force-layout.js per a la nostra lògica D3.js:
// Dimensions del SVG
const width = 800;
const height = 600;
// Dades de nodes i enllaços
const nodes = [
{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }
];
const links = [
{ source: 1, target: 2 },
{ source: 1, target: 3 },
{ source: 2, target: 4 },
{ source: 3, target: 5 }
];
// Crear SVG
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height);
// Crear simulació de força
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody().strength(-200))
.force("center", d3.forceCenter(width / 2, height / 2));
// Crear enllaços
const link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("class", "link");
// Crear nodes
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));
// Actualitzar posicions 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);
});
// Funcions de drag
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;
}Explicació del Codi
- Configuració del SVG: Definim les dimensions del nostre SVG i el seleccionem amb D3.js.
- Dades de Nodes i Enllaços: Definim els nodes i els enllaços que formaran la nostra xarxa.
- Simulació de Força: Creem una simulació de força amb
d3.forceSimulation(), afegint forces de link, charge i center. - Creació d'Enllaços: Afegim els enllaços al SVG com a elements
line. - Creació de Nodes: Afegim els nodes al SVG com a elements
circlei configurem el comportament de drag. - Actualització de Posicions: Utilitzem la funció
tickper actualitzar les posicions dels nodes i enllaços en cada tick de la simulació. - Funcions de Drag: Definim les funcions per gestionar el drag dels nodes.
Exercici Pràctic
Exercici
Modifica el codi per afegir etiquetes de text als nodes que mostrin el seu id.
Solució
Afegim el següent codi al fitxer force-layout.js:
// Crear etiquetes de text
const label = svg.append("g")
.attr("class", "labels")
.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.text(d => d.id);
// Actualitzar posicions de les etiquetes 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);
label
.attr("x", d => d.x + 12)
.attr("y", d => d.y + 3);
});Resum
En aquesta secció, hem après a crear una disposició de força amb D3.js, utilitzant nodes i enllaços per formar una xarxa dinàmica. Hem explorat com configurar la simulació de força, crear elements SVG per als nodes i enllaços, i afegir interactivitat amb funcions de drag. A més, hem practicat afegint etiquetes de text als nodes.
En el següent tema, explorarem com crear mapes geo utilitzant D3.js.
D3.js: De Principiant a Avançat
Mòdul 1: Introducció a D3.js
Mòdul 2: Treballant amb Seleccions
Mòdul 3: Dades i Escales
- Carregant i Analitzant Dades
- Utilitzant Escales de D3
- Escales Lineals i Ordinals
- Escales de Temps i Logarítmiques
Mòdul 4: Creant Visualitzacions Bàsiques
- Creant Gràfics de Barres
- Creant Gràfics de Línies
- Creant Gràfics de Pastís
- Creant Gràfics de Dispersió
Mòdul 5: Visualitzacions Avançades
- Creant Disposicions Jeràrquiques
- Creant Disposicions de Força
- Creant Mapes Geo
- Creant Visualitzacions Personalitzades
Mòdul 6: Interactivitat i Animació
Mòdul 7: Treballant amb Dades Reals
- Recuperant Dades d'APIs
- Neteja i Transformació de Dades
- Integració amb Altres Llibreries
- Estudis de Cas i Exemples
Mòdul 8: Rendiment i Optimització
- Optimitzant el Rendiment de D3.js
- Gestionant Grans Conjunts de Dades
- Enllaç de Dades Eficient
- Depuració i Resolució de Problemes
Mòdul 9: Millors Pràctiques i Tècniques Avançades
- Organització del Codi i Modularitat
- Components Reutilitzables
- Patrons Avançats de D3.js
- Contribuint a la Comunitat de D3.js
