From 63ef2b3a9beaa24e77b578e505910342e5e4de06 Mon Sep 17 00:00:00 2001 From: wisplite Date: Mon, 8 Sep 2025 16:15:30 -0500 Subject: [PATCH] Simulation speed settings for large network simulations --- CompleteMoveOnEdge.js | 41 ++++++++++++++++++++++++++++++++++------- index.html | 2 ++ script.js | 35 ++++++++++++++++++++++++----------- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/CompleteMoveOnEdge.js b/CompleteMoveOnEdge.js index 7420a8f..cce286f 100644 --- a/CompleteMoveOnEdge.js +++ b/CompleteMoveOnEdge.js @@ -29,6 +29,8 @@ class CompleteNodeOnEdgeEngine { this.timer = null; this.lastTime = 0; this.targetInterval = this.time_delay; + this.speedMultiplier = 1; + this.timeAccumulator = 0; this._movementInitialized = false; // Keep linksByEdges up-to-date for dynamic graph changes @@ -87,6 +89,20 @@ class CompleteNodeOnEdgeEngine { this.onArrival = callback; } + /** + * Adjust the simulation speed multiplier. + * A value > 1 speeds up the simulation, 0 < value < 1 slows it down. + * @param {number} multiplier + */ + setSimulationSpeed(multiplier) { + if (!isFinite(multiplier) || multiplier <= 0) { + return; + } + this.speedMultiplier = multiplier; + const minInterval = 1; // ms + this.targetInterval = Math.max(minInterval, this.time_delay / this.speedMultiplier); + } + /** * Initializes the movement of the nodes on edges. */ @@ -178,11 +194,22 @@ class CompleteNodeOnEdgeEngine { } loop = (timestamp) => { - const elapsed = timestamp - this.lastTime; - if (elapsed >= this.targetInterval) { - this.lastTime = timestamp; - this.eventProcess(); + if (this.lastTime === 0) { + this.lastTime = timestamp; } + const delta = timestamp - this.lastTime; + this.lastTime = timestamp; + + this.timeAccumulator += delta * this.speedMultiplier; + + let steps = 0; + const maxStepsPerFrame = 50; + while (this.timeAccumulator >= this.time_delay && steps < maxStepsPerFrame) { + this.eventProcess(); + this.timeAccumulator -= this.time_delay; + steps++; + } + this.timer = requestAnimationFrame(this.loop); }; @@ -190,18 +217,18 @@ class CompleteNodeOnEdgeEngine { * Processes the movement events and updates the nodes on edges accordingly. */ eventProcess() { - var ratio = this.ratio_inc; + var ratio = this.ratio_inc * this.speedMultiplier; if (ratio < 0) { this.moveDot(ratio, this.currentTime); - this.currentTime = this.currentTime + this.time_delay * Math.sign(ratio); + this.currentTime = this.currentTime + this.time_delay * Math.sign(this.ratio_inc) * this.speedMultiplier; this.replayManager(this.currentTime, true); this.maxTime = Math.max(this.maxTime, this.currentTime); } else { this.moveDot(ratio, this.currentTime); - this.currentTime = this.currentTime + this.time_delay * Math.sign(ratio); + this.currentTime = this.currentTime + this.time_delay * Math.sign(this.ratio_inc) * this.speedMultiplier; this.replayManager(this.currentTime, false); this.maxTime = Math.max(this.maxTime, this.currentTime); diff --git a/index.html b/index.html index db8f8c6..b06fe92 100644 --- a/index.html +++ b/index.html @@ -39,6 +39,8 @@
+ +
diff --git a/script.js b/script.js index 8d87d87..306d0fa 100644 --- a/script.js +++ b/script.js @@ -461,6 +461,14 @@ document.getElementById('updateInterval').addEventListener('change', function() UPDATE_INTERVAL = parseInt(this.value); }); +document.getElementById('simSpeed').addEventListener('change', function() { + const speed = parseFloat(this.value); + if (!isFinite(speed) || speed <= 0) { + return; + } + onEdgeEngine.setSimulationSpeed(speed); +}); + document.getElementById('connectionDistance').addEventListener('change', function() { CONNECTION_DISTANCE = parseInt(this.value); }); @@ -493,19 +501,24 @@ document.getElementById('createRandomGraphConfirm').addEventListener('click', fu physics: true, }, }); - for (let i = 0; i < nodeCount; i++) { + let nodeCounter = 0; + const interval = setInterval(() => { const nodeId = generateRealisticLabel(); nodes.add({id: nodeId, label: nodeId, x: Math.random() * 100, y: Math.random() * 100}); nodeTable[nodeId] = {'incoming': [], 'outgoing': [], 'packetCache': []}; - } - - setTimeout(() => { - network.setOptions({ - nodes: { - shape: 'box', - physics: false, - } - }); - }, 2000); + nodeCounter++; + if (nodeCounter >= nodeCount) { + console.log('Node count reached'); + clearInterval(interval); + setTimeout(() => { + network.setOptions({ + nodes: { + shape: 'box', + physics: false, + } + }); + }, 2000); + } + }, 10); document.getElementById('randomGraphModal').style.display = 'none'; }); \ No newline at end of file