dark mode and improved network coloring

This commit is contained in:
2025-09-08 17:43:06 -05:00
parent e7469ac081
commit 9f7b05294c
6 changed files with 256 additions and 6 deletions
+1
View File
@@ -402,6 +402,7 @@ class CompleteNodeOnEdgeEngine {
ratio: init_ratio,
reversed: path[1],
fixed: true,
font: node.font,
};
var edge = this.network.body.edges[newDotNode.edge];
+1 -1
View File
@@ -12,7 +12,7 @@ You can:
When sending packets, the colors of each node will change to reflect the TTL of the packet. The more green a node is, the closer it was to the origin of the packet, the more red a node is, the further it is from the origin. Nodes that were unable to receive the packet will turn white (this is often due to low TTL on large networks).
I have also found that this simulation can vary wildly in performance depending on the machine it's running on. Make sure your browser supports GPU acceleration, or else this will run very poorly with large networks.
I have also found that this simulation can vary wildly in performance depending on the machine and browser it's running on. Make sure your browser supports GPU acceleration, or else this will run very poorly with large networks. I have personally found that Chrome works the best for this by a huge margin, as much as I love Firefox.
You should be able to run this simulation by opening the `index.html` file in your browser, there's no fancy stack or anything, just pure HTML, CSS, and JavaScript.
+8 -2
View File
@@ -7,13 +7,13 @@
<script type="text/javascript" src="vis-network.min.js"></script>
<script type="text/javascript" src="simhelper.js"></script>
<script type="text/javascript" src="CompleteMoveOnEdge.js"></script>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" id="styleSheet" href="style.css">
</head>
<body>
<div id="rowFlex" style="display: flex; flex-direction: row; align-items: start; justify-content: center; width: 100%; height: 100%;">
<div id="propertyViewer">
<div id="propertyViewerHeader">Simulation Properties</div>
<hr/>
<hr style="width: 100%;"/>
<details id="simpleSettings">
<summary>Simple Settings</summary>
<div id="simpleSettingsContent">
@@ -43,6 +43,12 @@
<input type="number" id="simSpeed" value="1" min="0.1" step="0.1" autocomplete="off">
</div>
</details>
<div style="display: flex; flex-grow: 1; height: auto;"></div>
<hr style="width: 100%;"/>
<div id="darkModeContainer">
<input type="checkbox" id="darkMode" class="simToggle">
<label for="darkMode">Dark Mode</label>
</div>
</div>
<div id="centerColumn" style="display: flex; flex-direction: column; align-items: center; justify-content: center; width: 70%; height: 100%; margin: 0 auto;">
<div id="simContainer"></div>
+33 -1
View File
@@ -100,13 +100,18 @@ var onEdgeEngine = new CompleteNodeOnEdgeEngine(network, nodes, dotNodes, edges,
onEdgeEngine.createEdgesTable();
onEdgeEngine.initMovement();
onEdgeEngine.setArrivalCallback(({ from, to, dot }) => {
var ttl = parseInt(dot.id.split('-')[2]);
if (document.getElementById('showTTL').checked) {
edges.update({id: `${from}->${to}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1)}});
} else {
edges.update({id: `${from}->${to}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
}
if (nodeTable[to].packetCache.includes(dot.id.split('-')[0])) {
return;
}
// update color of receiving node for visualization
nodeTable[to].packetCache.push(dot.id.split('-')[0]);
var packetId = dot.id.split('-')[0];
var ttl = parseInt(dot.id.split('-')[2]);
ttl--;
if (document.getElementById('showTTL').checked) {
nodes.update({id: to, color: {background: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
@@ -127,6 +132,9 @@ onEdgeEngine.setArrivalCallback(({ from, to, dot }) => {
shape: dot.shape,
size: dot.size,
color: dot.color,
font: {
color: document.getElementById('darkMode').checked ? '#e0e0e0' : '#000'
}
};
onEdgeEngine.createDotNode(movingNode, to, neighbor);
}
@@ -155,6 +163,7 @@ const markNeighborsAsFailed = (nodeId, from, packetId, visited = new Set()) => {
continue;
}
nodes.update({id: neighbor, color: {background: 'white'}});
edges.update({id: `${nodeId}->${neighbor}`, color: {color: 'white', highlight: '#97c2fc'}});
markNeighborsAsFailed(neighbor, nodeId, packetId, visited);
}
}
@@ -465,6 +474,9 @@ document.getElementById('sendPacket').addEventListener('click', function() {
background: 'white',
border: 'black'
},
font: {
color: document.getElementById('darkMode').checked ? '#e0e0e0' : '#000'
}
};
onEdgeEngine.createDotNode(movingNode, selectedNode, connection);
nodeTable[selectedNode].packetCache.push(packetId);
@@ -476,6 +488,10 @@ document.getElementById('resetTTLColors').addEventListener('click', function() {
for (let node of nodes.get()) {
nodes.update({id: node.id, color: {background: '#97c2fc'}});
}
for (let edge of edges.get()) {
edges.update({id: edge.id, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
}
});
document.getElementById('updateInterval').addEventListener('change', function() {
@@ -544,3 +560,19 @@ document.getElementById('createRandomGraphConfirm').addEventListener('click', fu
}, 10);
document.getElementById('randomGraphModal').style.display = 'none';
});
document.getElementById('darkMode').addEventListener('change', function() {
if (this.checked) {
document.getElementById('styleSheet').href = 'style-dark.css';
} else {
document.getElementById('styleSheet').href = 'style.css';
}
});
window.onload = function() {
if (document.getElementById('darkMode').checked) {
document.getElementById('styleSheet').href = 'style-dark.css';
} else {
document.getElementById('styleSheet').href = 'style.css';
}
}
+207
View File
@@ -0,0 +1,207 @@
#simContainer {
width: 100%;
height: 90%;
margin: 0 auto;
border: 1px solid #404040;
box-sizing: border-box;
position: relative;
padding: 0;
overflow: hidden;
background-color: #1a1a1a;
}
#controlContainer {
width: 100%;
height: 10%;
margin: 0 auto;
border: 1px solid #404040;
padding: 5px;
box-sizing: border-box;
display: flex;
gap: 5px;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #2d2d2d;
}
#connectionViewer, #propertyViewer {
width: 15%;
height: 90%;
margin: 0 auto;
border: 1px solid #404040;
padding: 5px;
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
background-color: #252525;
color: #e0e0e0;
}
.controlButton {
width: 100%;
height: 100%;
cursor: pointer;
background-color: #3a3a3a;
color: #e0e0e0;
border: 1px solid #555555;
border-radius: 4px;
transition: background-color 0.2s ease;
}
.controlButton:hover {
background-color: #4a4a4a;
}
.controlButton:active {
background-color: #2a2a2a;
}
html, body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: #1a1a1a;
color: #e0e0e0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.rangeVis {
position: absolute;
border: 1px solid #666666;
border-radius: 50%;
z-index: 1000;
opacity: 0.3;
background-color: #ff6b6b;
pointer-events: none;
}
#controlButtons {
display: flex;
flex-direction: row;
flex-grow: 1;
gap: 10px;
}
#simToggles {
display: flex;
flex-direction: row;
flex-shrink: 1;
gap: 10px;
}
#simpleSettingsContent, #engineSettingsContent, #hardwareConstraintsContent {
display: flex;
flex-direction: column;
gap: 10px;
padding-left: 20px;
padding-top: 10px;
}
#simpleSettings, #hardwareConstraints, #engineSettings {
margin-bottom: 10px;
}
#randomGraphModal, #warningModal {
display: none;
position: absolute;
top: 0%;
left: 0%;
transform: translate(0%, 0%);
background-color: rgba(0, 0, 0, 0.8);
padding: 20px;
border: none;
width: 100%;
height: 100%;
}
#warningModalContent {
padding: 20px;
background-color: #2d2d2d;
border: 2px solid #ffaa00;
border-radius: 8px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #e0e0e0;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}
#randomGraphModalContent {
padding: 20px;
background-color: #2d2d2d;
border: 1px solid #555555;
border-radius: 8px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #e0e0e0;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
}
#createRandomGraphConfirm {
margin-top: 10px;
background-color: #4a9eff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s ease;
}
#createRandomGraphConfirm:hover {
background-color: #3a8eef;
}
#createRandomGraphConfirm:active {
background-color: #2a7edf;
}
/* Input and form styling for dark mode */
input, select, textarea {
background-color: #3a3a3a;
color: #e0e0e0;
border: 1px solid #555555;
border-radius: 4px;
padding: 4px 8px;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #4a9eff;
box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2);
}
/* Label styling */
label {
color: #e0e0e0;
}
/* Button styling */
button {
background-color: #3a3a3a;
color: #e0e0e0;
border: 1px solid #555555;
border-radius: 4px;
padding: 6px 12px;
cursor: pointer;
transition: background-color 0.2s ease;
}
button:hover {
background-color: #4a4a4a;
}
button:active {
background-color: #2a2a2a;
}
/* Checkbox and radio button styling */
input[type="checkbox"], input[type="radio"] {
accent-color: #4a9eff;
}
+4
View File
@@ -29,6 +29,10 @@
margin: 0 auto;
border: 1px solid #000;
padding: 5px;
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
}
.controlButton {