|
31 | 31 | </head> |
32 | 32 |
|
33 | 33 | <body> |
34 | | - <strong>Map of mesh node connections.</strong> Updated: <span id="whenupdated"></span> |
| 34 | + <strong>Map of mesh node connections.</strong> Updated: <span id="whenupdated"></span> | <A href="https://github.com/filipsPL/meshtastic-network-visualization/">GitHub</A> |
35 | 35 | <div class="controls"> |
36 | 36 | <select id="fileSelect"> |
37 | 37 | <option value="data/cytoscape_traceroutes_1h.json">🚇 Traceroutes :: 1 hour</option> |
|
50 | 50 | <option value="data/cytoscape_neighbors_3h.json">🔗 Neighbors :: 3 hours</option> |
51 | 51 | <option value="data/cytoscape_neighbors_24h.json">🔗 Neighbors :: 24 hours</option> |
52 | 52 | </select> |
| 53 | + |
| 54 | + <select id="layoutSelect"> |
| 55 | + <option value="cose-bilkent">Cose-Bilkent Layout</option> |
| 56 | + <option value="circle">Circle Layout</option> |
| 57 | + <option value="concentric">Concentric Layout</option> |
| 58 | + </select> |
53 | 59 | </div> |
54 | 60 | <div id="cy"></div> |
55 | 61 | <script> |
56 | 62 | let cy; // Define cy in global scope |
| 63 | + let currentFilename; // Store the current filename |
57 | 64 |
|
58 | 65 | function loadData(filename) { |
| 66 | + currentFilename = filename; // Store the current filename |
59 | 67 | fetch(filename) |
60 | 68 | .then(response => { |
61 | 69 | if (!response.ok) { |
|
95 | 103 | cy.destroy(); |
96 | 104 | } |
97 | 105 |
|
| 106 | + // Determine layout based on dropdown selection |
| 107 | + const layoutType = document.getElementById('layoutSelect').value; |
| 108 | + let layoutConfig; |
| 109 | + switch(layoutType) { |
| 110 | + case 'cose-bilkent': |
| 111 | + layoutConfig = { |
| 112 | + name: "cose-bilkent", |
| 113 | + animate: false, |
| 114 | + idealEdgeLength: 100, |
| 115 | + randomize: true, |
| 116 | + nodeRepulsion: 7000, |
| 117 | + edgeElasticity: 0.45, |
| 118 | + nestingFactor: 10.1, |
| 119 | + numIter: 30000, |
| 120 | + gravity: 0.25, |
| 121 | + tile: true |
| 122 | + }; |
| 123 | + break; |
| 124 | + case 'concentric': |
| 125 | + layoutConfig = { |
| 126 | + name: 'concentric', |
| 127 | + minNodeSpacing: 50, |
| 128 | + concentric: function(node) { |
| 129 | + return node.data('connections'); |
| 130 | + }, |
| 131 | + levelWidth: function() { |
| 132 | + return 2; |
| 133 | + } |
| 134 | + }; |
| 135 | + break; |
| 136 | + default: |
| 137 | + layoutConfig = { |
| 138 | + name: 'circle' |
| 139 | + }; |
| 140 | + } |
| 141 | + |
98 | 142 | // Initialize Cytoscape.js |
99 | 143 | cy = cytoscape({ |
100 | 144 | container: document.getElementById('cy'), |
|
114 | 158 | 'background-color': 'mapData(connections, 1, 10, #d2dbfa, #003aff)', |
115 | 159 | 'shape': 'round-rectangle' |
116 | 160 | } |
117 | | - |
118 | 161 | }, |
119 | | - |
120 | 162 | { |
121 | 163 | selector: 'node[role=2]', |
122 | 164 | style: { |
|
144 | 186 | 'content': (ele) => `[RPT] ${ele.data('label')}` |
145 | 187 | } |
146 | 188 | }, |
147 | | - |
148 | 189 | { |
149 | 190 | selector: 'edge', |
150 | 191 | style: { |
|
159 | 200 | } |
160 | 201 | } |
161 | 202 | ], |
162 | | - layout: { |
163 | | - name: "cose-bilkent", |
164 | | - animate: false, |
165 | | - idealEdgeLength: 100, |
166 | | - randomize: true, |
167 | | - nodeRepulsion: 7000, |
168 | | - edgeElasticity: 0.45, |
169 | | - nestingFactor: 10.1, |
170 | | - numIter: 30000, |
171 | | - gravity: 0.25, |
172 | | - tile: true |
173 | | - } |
| 203 | + layout: layoutConfig |
174 | 204 | }); |
175 | 205 | }) |
176 | 206 | .catch(error => { |
|
193 | 223 | }); |
194 | 224 | } |
195 | 225 |
|
196 | | - // Add event listener for dropdown changes |
| 226 | + // Add event listener for data file dropdown changes |
197 | 227 | document.getElementById('fileSelect').addEventListener('change', function () { |
198 | 228 | loadData(this.value); |
199 | 229 | }); |
200 | 230 |
|
| 231 | + // Add event listener for layout dropdown changes |
| 232 | + document.getElementById('layoutSelect').addEventListener('change', function () { |
| 233 | + // Reload the current data with the new layout |
| 234 | + if (currentFilename) { |
| 235 | + loadData(currentFilename); |
| 236 | + } |
| 237 | + }); |
| 238 | + |
201 | 239 | // Load initial data |
202 | 240 | loadData(document.getElementById('fileSelect').value); |
203 | 241 | </script> |
|
0 commit comments