Files
graph-mesamis/src/network0.ts
2025-10-19 09:08:49 +02:00

135 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import './style.css';
import Graph from "graphology";
import Sigma from "sigma";
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: Math.random(), y: Math.random(),
label: `${sex} ${i}`,
sex,
education,
size: 6 + education,
color,
});
}
let total = N * 1.5
// --- Calcul du layout ForceAtlas2 ---
/*
const positions = forceAtlas2(graph, { iterations: 50 });
// --- 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 });
// --- Fonctions dynamiques ---
function addLink() {
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: "#da1515ff", size: 1 });
}
if (total-- > 0) setTimeout(() => addLink(), 1000); else running = false;
}
function removeLink(source, target) {
if (graph.hasEdge(source, target)) {
graph.dropEdge(source, target);
renderer.refresh();
}
}
// --- Exemple dévolution dynamique ---
setTimeout(() => addLink(), 250);
setTimeout(() => removeLink("n1", "n2"), 8000);
// --- 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();
/*
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'
/*
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<div>
<a href="https://vite.dev" target="_blank">
<img src="${viteLogo}" class="logo" alt="Vite logo" />
</a>
<a href="https://www.typescriptlang.org/" target="_blank">
<img src="${typescriptLogo}" class="logo vanilla" alt="TypeScript logo" />
</a>
<h1>Vite + TypeScript</h1>
<div class="card">
<button id="counter" type="button"></button>
</div>
<p class="read-the-docs">
Click on the Vite and TypeScript logos to learn more
</p>
</div>
`
setupCounter(document.querySelector<HTMLButtonElement>('#counter')!)
*/