diff --git a/src/main.ts b/src/main.ts index 09bb2a1..753ecf6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,20 +1,22 @@ import './style.css' import Graph from "https://esm.sh/graphology"; import Sigma from "https://esm.sh/sigma"; -import forceAtlas2 from "https://esm.sh/graphology-layout-forceatlas2"; +import forceAtlas2 from "graphology-layout-forceatlas2"; // --- Génération de données de base --- const graph = new Graph(); const N = 30; const colors = ["#ec635e", "#61afef", "#2c3029ff", "#e5c07b"]; + for (let i = 0; i < N; i++) { const sex = Math.random() < 0.5 ? "F" : "M"; const education = Math.floor(Math.random() * 4); const color = colors[education]; + graph.addNode(`n${i}`, { - x: i, y: i, - label: `${sex}${i}`, + x: Math.random(), y: Math.random(), + label: `${sex} ${i}`, sex, education, size: 6 + education, @@ -27,22 +29,20 @@ for (let i = 0; i < N * 1.5; i++) { const a = `n${Math.floor(Math.random() * N)}`; const b = `n${Math.floor(Math.random() * N)}`; if (a !== b && !graph.hasEdge(a, b)) { - graph.addEdge(a, b, { color: "#aaa", size: 1 }); + graph.addEdge(a, b, { color: "#da1515ff", size: 1 }); } } +// --- Calcul du layout ForceAtlas2 --- +/* +const positions = forceAtlas2(graph, { iterations: 50 }); -// With settings: -const positions = forceAtlas2(graph, { - iterations: 50, - settings: { - gravity: 10 - } -}); - -// --- Placement automatique avec ForceAtlas2 --- -//forceAtlas2.assign(graph); - +// --- Application des positions calculées --- +for (const [node, pos] of Object.entries(positions)) { + graph.setNodeAttribute(node, "x", pos.x); + graph.setNodeAttribute(node, "y", pos.y); +} +*/ // --- Rendu Sigma --- const container = document.getElementById("app"); const renderer = new Sigma(graph, container, { renderLabels: true }); @@ -63,11 +63,63 @@ function removeLink(source, target) { } // --- Exemple d’évolution dynamique --- -setTimeout(() => addLink("n0", "n5"), 3000); -setTimeout(() => removeLink("n1", "n2"), 6000); +//setTimeout(() => addLink("n0", "n5"), 3000); +//setTimeout(() => removeLink("n1", "n2"), 6000); -console.log("Graph loaded:", graph.order, "nodes,", graph.size, "edges"); +//console.log("Graph loaded:", graph.order, "nodes,", graph.size, "edges"); + +// --- Animation du layout --- +// On crée une "simulation" ForceAtlas2 en incrémentant les positions à chaque frame. +let running = true; + +function stepLayout() { + if (!running) return; + + // Effectue une itération de ForceAtlas2 (ne recrée pas tout) + forceAtlas2.assign(graph, { iterations: 1, settings: { gravity: 0.1, scalingRatio: 10 } }); + + // Sigma détecte les changements automatiquement → inutile de refresh manuellement + requestAnimationFrame(stepLayout); +} + +// Lancement +stepLayout(); + +// Arrêt automatique après 8 secondes +setTimeout(() => { + running = false; + console.log("Layout stabilisé"); +}, 8000); + +/* +const layout = new ForceAtlas2Layout(graph, { + settings: { + gravity: 0.1, + slowDown: 10, + linLogMode: false, + outboundAttractionDistribution: false, + adjustSizes: true, + }, +}); + +// --- Animation : on démarre le layout --- +layout.start(); + +// --- Optionnel : arrêt automatique après quelques secondes --- +setTimeout(() => { + layout.stop(); + console.log("Layout stabilisé"); +}, 5000); + +// --- Animation continue du rendu --- +function animate() { + // On redessine continuellement le graphe tant que le layout tourne + renderer.refresh(); + requestAnimationFrame(animate); +} +animate(); +*/ //import typescriptLogo from './typescript.svg' //import viteLogo from '/vite.svg' //import { setupCounter } from './counter.ts'