Skip to content

Commit 38bad6f

Browse files
committed
accuracy: add mouseover graph previews
1 parent c8ba7a3 commit 38bad6f

File tree

5 files changed

+116
-32
lines changed

5 files changed

+116
-32
lines changed

htdocs/accuracy.html

Lines changed: 94 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,22 @@
5353
<h1>GNSS Timing Performance</h1>
5454
<p class="small center" style="margin-top: -14px;">by: <a href="https://byo-ntp.github.io">Build Your Own NTP server</a></p>
5555

56-
<div class="legend">
57-
<p class="color-ms">ms = millisecond = 1e-3 = 0.001</p>
58-
<p class="color-us">µs = microsecond = 1e-6 = 0.000001</p>
59-
<p class="color-ns">ns = nanosecond = 1e-9 = 0.000000001</p>
60-
<p class="color-ps">ps = picosecond = 1e-12 = 0.000000000001</p>
56+
<div style="display: flex; width: 80%; text-align: center; max-width: 1200px; align-items: center; justify-content: center; gap: 1em; margin: auto;">
57+
<div style="flex: 1; text-align: left;" class="legend">
58+
<p class="color-ms">ms = millisecond = 1e-3 = 0.001</p>
59+
<p class="color-us">µs = microsecond = 1e-6 = 0.000001</p>
60+
<p class="color-ns">ns = nanosecond = 1e-9 = 0.000000001</p>
61+
<p class="color-ps">ps = picosecond = 1e-12 = 0.000000000001</p>
62+
</div>
63+
<div style="flex: 1; align-items: center; justify-content: right; max-width: 300px;">
64+
<img id="gnss_performance_graph" src="" alt="Hover over a cell to preview a graph of GNSS accuracy." height="85px; width: auto;">
65+
</div>
6166
</div>
67+
6268
<p class="center">This table shows the timing performance of various GNSS receivers on varying hardware,
6369
operating systems, and NTP daemons. Each numeric value is the most inaccurate reading measured during a 12
64-
hour measuring interval. The values are clickable links to the build recipe with instructions for
65-
replicating that build.
70+
hour measuring interval. The 3 left header columns are clickable links to the build recipe for that row.
71+
The numeric values are clickable and will open an image of the GNSS performance graph for that row.
6672
</p>
6773
<table id="timing-table">
6874
<thead>
@@ -120,7 +126,7 @@ <h1>GNSS Timing Performance</h1>
120126
<tr><th class="grey">LarkBox</th><th class="grey">BSD</th><th>ntp</th>
121127
<td>0.021700000</td><td>0.010400</td><td>0.0000510</td><td>0.000061000</td><td>0.000047000</td><td></td></tr>
122128
<tr><th class="grey">LarkBox</th><th class="grey">BSD</th><th>ntp + gpsd</th>
123-
<td> </td><td> </td><td>0.0001430</td><td>0.0000570000</td><td>0.000025000</td><td></td></tr>
129+
<td> </td><td> </td><td>0.0001430</td><td>0.000057000</td><td>0.000025000</td><td></td></tr>
124130
<tr><th class="grey">LarkBox</th><th>Win</th><th>ntp</th>
125131
<td> </td><td>0.013600</td><td></td><td></td><td></td><td></td></tr>
126132
<tr><th>&nbsp;</th><th></th><th></th><td></td><td></td><td></td><td></td><td></td><td></td></tr>
@@ -136,7 +142,7 @@ <h1>GNSS Timing Performance</h1>
136142
<tr><th>M3 MBA</th><th>Mac</th><th>chrony</th>
137143
<td>0.00172 </td><td> </td><td>0.001580 </td><td> </td><td> </td><td></td></tr>
138144
<tr><th class="grey">M3 MBA </th><th class="grey">Mac</th><th>mac-pps</th>
139-
<td> </td><td> </td><td>0.000358 </td><td> </td><td>0.000372000</td><td></td></tr>
145+
<td> </td><td> </td><td>0.000358 </td><td> </td><td>0.000372 </td><td></td></tr>
140146
<tr><th class="grey">M3 MBA </th><th class="grey">Mac</th><th>sec</th>
141147
<td> </td><td> </td><td>0.008000 </td><td> </td><td> </td><td></td></tr>
142148
<tr><th class="grey">M3 MBA </th><th class="grey">Mac</th><th>sec + gpsd</th>
@@ -152,6 +158,11 @@ <h1>GNSS Timing Performance</h1>
152158
<p>Win = Windows 11</p>
153159
</div>
154160

161+
<div id="lightbox-overlay" style="display: none;">
162+
<span id="close-btn">&times;</span>
163+
<img id="lightbox-img" src="" alt="Enlarged">
164+
</div>
165+
155166
<footer>
156167
<p>BYO-NTP is a community project. Please contribute on <a href="https://github.com/BYO-NTP/recipes/wiki">GitHub</a>.</p>
157168
</footer>
@@ -160,17 +171,17 @@ <h1>GNSS Timing Performance</h1>
160171
const isNumeric = (val) => /^\d*\.?\d+$/.test(val);
161172
function styleCell (td) {
162173
const val = parseFloat(td.textContent);
163-
if (td.textContent.trim() === "0" || val === 0) {
164-
td.classList.add("color-white");
174+
if (td.textContent.trim() === '0' || val === 0) {
175+
td.classList.add('color-white');
165176
} else if (!isNaN(val)) {
166177
if (val >= 0.001 && val < 1) {
167-
td.classList.add("color-ms");
178+
td.classList.add('color-ms');
168179
} else if (val >= 0.000001 && val < 0.001) {
169-
td.classList.add("color-us");
180+
td.classList.add('color-us');
170181
} else if (val >= 0.000000001 && val < 0.000001) {
171-
td.classList.add("color-ns");
182+
td.classList.add('color-ns');
172183
} else if (val >= 0.000000000001 && val < 0.000000001) {
173-
td.classList.add("color-ps");
184+
td.classList.add('color-ps');
174185
}
175186
}
176187
}
@@ -179,35 +190,86 @@ <h1>GNSS Timing Performance</h1>
179190
if (th.length < 1) return;
180191

181192
switch (th[1].textContent.trim()) {
182-
case "Pi OS": return "Pi-OS-12-GPIO";
183-
case "BSD":
193+
case 'Pi OS': return 'Pi-OS-12-GPIO';
194+
case 'BSD':
184195
switch (th[0].textContent.trim()) {
185-
case "Pi 4": return "FreeBSD-14-GPIO";
186-
case "Pi 5":
187-
case "LarkBox": return "FreeBSD-14-USB";
188-
case "Xeon E5": return "FreeBSD-14-UART";
196+
case 'Pi 4': return 'FreeBSD-14-GPIO';
197+
case 'Pi 5':
198+
case 'LarkBox': return 'FreeBSD-14-USB';
199+
case 'Xeon E5': return 'FreeBSD-14-UART';
189200
}
190-
case "Mac": return "macOS";
191-
case "Win": return "Windows-11-USB";
201+
case 'Mac': return 'macOS';
202+
case 'Win': return 'Windows-11-USB';
203+
}
204+
}
205+
206+
function getCellImage (th, tdIndex) {
207+
const gnss = ['6M', 'U7', '7M', 'M8Q', 'M8T', 'M10'];
208+
209+
if (th.length < 1) return;
210+
211+
let imgHW = th[0].textContent.trim().replace(/\s/g, '').toLowerCase()
212+
switch (th[0].textContent.trim()) {
213+
case 'Xeon E5': imgHW = 'xeonE5'; break
214+
case 'M3 MBA': imgHW = 'm3'; break
215+
}
216+
217+
let imgOS = th[1].textContent.trim().toLowerCase().replace(/\s/g, '')
218+
switch (th[1].textContent.trim()) {
219+
case 'Linux': imgOS = 'deb'; break
220+
}
221+
222+
let imgDaemon = th[2].textContent.trim().toLowerCase().replace(/\s/g, '').replace(/\+/g, '-')
223+
switch (th[2].textContent.trim()) {
224+
case 'mac-pps': imgDaemon = 'chrony'; break
225+
}
226+
227+
let imgGNSS = gnss[tdIndex];
228+
229+
if (imgHW && imgOS && imgDaemon && imgGNSS) {
230+
return `https://byo-ntp.github.io/img/ublox/${imgGNSS}/${imgHW}-${imgOS}-${imgGNSS.toLowerCase()}-${imgDaemon}.png`
192231
}
193232
}
194233

195-
document.addEventListener("DOMContentLoaded", () => {
196-
const table = document.getElementById("timing-table");
197-
const rows = table.querySelectorAll("tbody tr");
234+
document.addEventListener('DOMContentLoaded', () => {
235+
const graph = document.getElementById('gnss_performance_graph')
236+
const overlay = document.getElementById('lightbox-overlay')
237+
const lbImg = document.getElementById('lightbox-img')
238+
const table = document.getElementById('timing-table')
239+
const rows = table.querySelectorAll('tbody tr')
198240
for (const row of rows) {
199-
const th = row.querySelectorAll("th");
200-
const recipe = getRowRecipe(th);
241+
const th = row.querySelectorAll('th')
242+
const recipe = getRowRecipe(th)
243+
if (recipe) {
244+
for (const td of th) {
245+
td.onclick = () => window.open(`https://github.com/BYO-NTP/recipes/wiki/${recipe}`)
246+
}
247+
}
201248

202-
const cells = row.querySelectorAll("td");
249+
const cells = row.querySelectorAll('td')
250+
let cellIndex = 0
203251
for (const td of cells) {
204-
if (td.textContent.trim() !== "") {
205-
styleCell(td);
206-
if (recipe) td.onclick = () => window.open(`https://github.com/BYO-NTP/recipes/wiki/${recipe}`);
252+
if (td.textContent.trim() !== '') {
253+
styleCell(td)
254+
const imgURI = getCellImage(th, cellIndex)
255+
if (graph * imgURI) {
256+
td.onclick = () => {
257+
td.classList.add('lightbox-link')
258+
overlay.style.display = 'flex'
259+
lbImg.src = imgURI
260+
}
261+
td.onmouseover = () => { graph.src = imgURI; }
262+
td.onmouseout = () => { graph.src = ''; }
263+
}
207264
}
265+
cellIndex++
208266
}
209267
}
210268
})
269+
270+
document.getElementById('close-btn').addEventListener('click', () => {
271+
document.getElementById('lightbox-overlay').style.display = 'none'
272+
})
211273
</script>
212274
</body>
213275
</html>
File renamed without changes.
File renamed without changes.
File renamed without changes.

htdocs/style.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,34 @@ body {
2828
background-color: #fff;
2929
border: 1px solid #ccc;
3030
box-shadow: 0 0 5px rgba(0,0,0,0.1);
31+
font-size: 0.9em;
3132
}
3233
.legend p {
3334
font-family: monospace, monospace;
3435
white-space: pre;
3536
margin: 0.3em;
3637
}
38+
39+
#lightbox-overlay {
40+
position: fixed;
41+
display: none;
42+
top: 0; left: 0; width: 100%; height: 100%;
43+
background: rgba(0, 0, 0, 0.8);
44+
justify-content: center; align-items: center;
45+
z-index: 1000;
46+
}
47+
#lightbox-img {
48+
max-width: 90%;
49+
max-height: 90%;
50+
}
51+
#close-btn {
52+
position: absolute;
53+
top: 20px; right: 30px;
54+
color: white;
55+
font-size: 40px;
56+
cursor: pointer;
57+
}
58+
3759
footer {
3860
margin-top: 20px;
3961
padding: 5px;

0 commit comments

Comments
 (0)