v0.36.3
This commit is contained in:
1 parent
5cb63f542c
commit
17e314e159
27 files changed
+1017
-291
No files matched your search
@@ -282,6 +282,15 @@ function svgNode(tag, attrs = {}) {
|
||||
|
||||
function setChartText(node, value) {
|
||||
const text = String(value);
|
||||
// Controls decorated by the optional SVG icons hold [svg.ui-icon, text]; keep the icon
|
||||
// and update only the text node so periodic refreshes do not rebuild the button.
|
||||
const icon = node.querySelector(":scope > svg.ui-icon");
|
||||
if (icon) {
|
||||
const last = node.lastChild;
|
||||
if (last?.nodeType === 3) { if (last.data !== text) last.data = text; }
|
||||
else node.append(text);
|
||||
return;
|
||||
}
|
||||
if (node.firstChild?.nodeType === 3 && node.firstChild === node.lastChild) {
|
||||
if (node.firstChild.data !== text) node.firstChild.data = text;
|
||||
} else if (node.textContent !== text) {
|
||||
@@ -346,9 +355,12 @@ function renderNetworkInterfaceCharts(interfaces, appendSample) {
|
||||
setChartText(row.querySelector(".network-interface-hide"), t("hideMetric"));
|
||||
row.querySelector(".network-rx-line").setAttribute("points", sparklinePoints(history.rx, 300, 60, 5, peak) || "0,55 300,55");
|
||||
row.querySelector(".network-tx-line").setAttribute("points", sparklinePoints(history.tx, 300, 60, 5, peak) || "0,55 300,55");
|
||||
window.rustProxyChartScale.axes(row.querySelector("svg"), peak, "bytes/s", history.rx.length,
|
||||
// The Hide button precedes the chart and may carry an injected svg.ui-icon:
|
||||
// address the chart explicitly so axes/labels never attach to the icon.
|
||||
const chart = row.querySelector("svg:not(.ui-icon)");
|
||||
window.rustProxyChartScale.axes(chart, peak, "bytes/s", history.rx.length,
|
||||
{ top: 5 / 60, bottom: 55 / 60 });
|
||||
row.querySelector("svg").setAttribute("aria-label", `${name} ${t("networkInterfacesHistory")}`);
|
||||
chart.setAttribute("aria-label", `${name} ${t("networkInterfacesHistory")}`);
|
||||
children.push(row);
|
||||
}
|
||||
const hidden = current.filter(item => item?.name && hiddenNetworkInterfaces.has(item.name));
|
||||
@@ -395,15 +407,32 @@ function cacheOutcomeMix(totals) {
|
||||
const counts = [hits, misses, bypasses, requests - cacheTotal];
|
||||
return { counts, percentages: counts.map(value => value / requests * 100), requests };
|
||||
}
|
||||
// Percent labels live inside the bar segments; a label that does not fit is hidden
|
||||
// (the legend below always carries the exact value).
|
||||
function fitCacheMixLabels() {
|
||||
const bar = $("cache-mix-bar");
|
||||
if (!bar) return;
|
||||
bar.querySelectorAll(":scope > span").forEach(segment => {
|
||||
segment.classList.remove("is-tight");
|
||||
segment.classList.toggle("is-tight", segment.textContent !== "" && segment.scrollWidth > segment.clientWidth);
|
||||
});
|
||||
if (!bar.dataset.fitObserved && typeof ResizeObserver === "function") {
|
||||
bar.dataset.fitObserved = "1";
|
||||
new ResizeObserver(() => fitCacheMixLabels()).observe(bar);
|
||||
}
|
||||
}
|
||||
function renderCacheMix(mix, totalRequests) {
|
||||
const names = ["hit", "miss", "bypass", "other"];
|
||||
const unavailable = t(totalRequests === 0 ? "cacheMixWaiting" : "cacheMixInvalid");
|
||||
names.forEach((name, i) => {
|
||||
const pct = mix ? mix.percentages[i] : 0;
|
||||
$(`cache-mix-${name}`).style.width = `${pct}%`;
|
||||
const segment = $(`cache-mix-${name}`);
|
||||
segment.style.width = `${pct}%`;
|
||||
segment.textContent = mix && pct > 0 ? `${fmt(pct, pct < 10 ? 1 : 0)}%` : "";
|
||||
$(`cache-mix-${name}-count`).textContent = mix ? fmt(mix.counts[i]) : "-";
|
||||
$(`cache-mix-${name}-percent`).textContent = mix ? `${fmt(pct, 1)}%` : "-";
|
||||
});
|
||||
fitCacheMixLabels();
|
||||
$("cache-mix-headline").textContent = mix ? `${fmt(mix.percentages[0], 1)}% HIT` : "-";
|
||||
const caption = $("cache-mix-caption");
|
||||
const validTotal = Number.isSafeInteger(totalRequests) && totalRequests >= 0;
|
||||
@@ -424,6 +453,7 @@ function renderCacheMix(mix, totalRequests) {
|
||||
function renderDiagnostics(status, appendSample = true, systemSample = appendSample) {
|
||||
const d = status.system || {}, live = status.live_system || d, c = status.cache || {}, m = status.metrics || {};
|
||||
$("metric-h3").textContent = fmt(m.http3_requests);
|
||||
$("metric-h3-active").textContent = fmt(m.http3_active_connections || 0);
|
||||
const cacheHits = c.hits == null ? null : Number(c.hits), cacheMisses = c.misses == null ? null : Number(c.misses);
|
||||
const cacheEvents = cacheHits !== null && cacheMisses !== null ? cacheHits + cacheMisses : 0;
|
||||
$("metric-cache-ratio").textContent = cacheEvents > 0 ? `${fmt(cacheHits / cacheEvents * 100, 1)}%` : "-";
|
||||
|
||||
Reference in new issue
Block a user