From 7ec6a9f8e02cac92f0d2ce8c450ab49a648320f0 Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 31 Oct 2026 23:36:38 +0100 Subject: dashboard: make transports curved --- src/api/dashboard/dashboard.html | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index f544f51..784fdb6 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -794,12 +794,17 @@ function renderGraph() { stroke: "var(--bad)", "stroke-opacity": .5, "stroke-width": width + 4, "stroke-linecap": "round" })); } + // The one in use drawn last: on top of the others where they meet, at the nodes. + const drawnLines = []; lines.forEach((line, i) => { - // 0, then +1, -1, +2, -2 … steps of 6 px to the side. + // 0, then +1, -1, +2, -2 … steps of 6 px to the side, at the middle: from node to + // node, each bowing out that far (a quadratic curve, its control point twice as + // far out); `aside(t)`, how far out at `t` along. const side = i === 0 ? 0 : (i % 2 ? 1 : -1) * Math.ceil(i / 2) * 6; - const ox = nx * side, oy = ny * side; - const attrs = { x1: p.x + ox, y1: p.y + oy, x2: q.x + ox, y2: q.y + oy, - stroke: colourOf(line.transport), + const aside = t => 4 * t * (1 - t) * side; + const cx = (p.x + q.x) / 2 + nx * side * 2, cy = (p.y + q.y) / 2 + ny * side * 2; + const attrs = { d: "M " + p.x + " " + p.y + " Q " + cx + " " + cy + " " + q.x + " " + q.y, + fill: "none", stroke: colourOf(line.transport), // Narrow where dormant or down (over its underlay). "stroke-width": broken ? (line.used ? 1.5 : 0.8) : line.used ? 3 : 1.2 }; // Dotted where an end reports nothing, dashed where relayed, solid where direct. @@ -809,7 +814,7 @@ function renderGraph() { } else if (line.used ? link.relayed : line.relayed) { attrs["stroke-dasharray"] = "7 4"; } - const drawnLine = drawing("line " + key + " " + i, "line", attrs); + const drawnLine = drawing("path " + key + " " + i, "path", attrs); const description = name(a) + " – " + name(b) + (line.transport ? " via " + line.transport : "") + (line.used ? " (in use)" : "") + ((line.used ? link.relayed : line.relayed) ? ", relayed" : "") + (link.dormant ? ", dormant" : "") + @@ -819,7 +824,7 @@ function renderGraph() { ", measured " + age(secsAgo + elapsed()) + " ago"; tooltip(drawnLine, description); descriptions.push(description); - children.push(drawnLine); + drawnLines.push(drawnLine); if (typeof line.rttMs === "number") { // Near the end that measured it (`a`, whose report is drawn), clear of its // node and name, and short of the middle: the one in use larger, the others @@ -828,14 +833,15 @@ function renderGraph() { const t = (line.used ? along : Math.max(24, along * .6)) / length; const out = line.used ? -4 : Math.sign(side) * 9; const rtt = drawing("rtt " + key + " " + i, "text", upright({ - x: p.x + (q.x - p.x) * t + ox + nx * out, - y: p.y + (q.y - p.y) * t + oy + ny * out + (line.used ? 0 : 3), + x: p.x + (q.x - p.x) * t + nx * (aside(t) + out), + y: p.y + (q.y - p.y) * t + ny * (aside(t) + out) + (line.used ? 0 : 3), "text-anchor": "middle", "font-size": line.used ? 11 : 9, fill: line.used ? "var(--fg)" : "var(--muted)" })); label(rtt, ms(line.rttMs)); labels.push(rtt); } }); + children.push(...drawnLines.reverse()); tooltip(covering, descriptions.join("\n")); } // Above every line, so none crosses them. -- cgit v1.3.1