From 52441b7b1bdae7a20174d0feb00c500bb0fa99ab Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 15 Sep 2025 22:11:44 -0300 Subject: [PATCH 1/6] Remove unnecessary code The outer `if` (line 92) already guarantees only 2 possible values. If `isQueryTypeChart` is false, `isForwardDestinationChart` must be true. Signed-off-by: RD WebDesign --- scripts/js/charts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/js/charts.js b/scripts/js/charts.js index ecb99b61..224abda7 100644 --- a/scripts/js/charts.js +++ b/scripts/js/charts.js @@ -96,7 +96,7 @@ globalThis.htmlLegendPlugin = { if (isQueryTypeChart) { link.href = `queries?type=${item.text}`; - } else if (isForwardDestinationChart) { + } else { // Encode the forward destination as it may contain an "#" character link.href = `queries?upstream=${encodeURIComponent(upstreams[item.text])}`; } From 48666e1ffdf1d69081c624a0bada265a3c160061 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 15 Sep 2025 22:19:09 -0300 Subject: [PATCH 2/6] Use an array to store upstream server IPs This will avoid overwritting the IP when more than one upstream DNS server uses the same name Signed-off-by: RD WebDesign --- scripts/js/charts.js | 4 ++-- scripts/js/index.js | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/js/charts.js b/scripts/js/charts.js index 224abda7..860637c9 100644 --- a/scripts/js/charts.js +++ b/scripts/js/charts.js @@ -5,7 +5,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -/* global upstreams:false */ +/* global upstreamIPs:false */ "use strict"; @@ -98,7 +98,7 @@ globalThis.htmlLegendPlugin = { link.href = `queries?type=${item.text}`; } else { // Encode the forward destination as it may contain an "#" character - link.href = `queries?upstream=${encodeURIComponent(upstreams[item.text])}`; + link.href = `queries?upstream=${encodeURIComponent(upstreamIPs[item.index])}`; } } else { // no clickable links in other charts diff --git a/scripts/js/index.js b/scripts/js/index.js index 9bf49555..f9edc9d5 100644 --- a/scripts/js/index.js +++ b/scripts/js/index.js @@ -226,7 +226,7 @@ function updateClientsOverTime() { }); } -const upstreams = {}; +const upstreamIPs = []; function updateForwardDestinationsPie() { $.getJSON(document.body.dataset.apiurl + "/stats/upstreams", data => { const v = []; @@ -248,11 +248,8 @@ function updateForwardDestinationsPie() { label += "#" + item.port; } - // Store upstreams for generating links to the Query Log - upstreams[label] = item.ip; - if (item.port > 0) { - upstreams[label] += "#" + item.port; - } + // Store upstreams IPs for generating links to the Query Log + upstreamIPs.push(item.port > 0 ? item.ip + "#" + item.port : item.ip); const percent = (100 * item.count) / sum; values.push([label, percent, THEME_COLORS[i++ % THEME_COLORS.length]]); From af471bec94f5af01df071d61ef2f08f4b86e777d Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 15 Sep 2025 22:32:09 -0300 Subject: [PATCH 3/6] Show the upstream server IP on the title tooltip Signed-off-by: RD WebDesign --- scripts/js/charts.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/js/charts.js b/scripts/js/charts.js index 860637c9..967b4bc2 100644 --- a/scripts/js/charts.js +++ b/scripts/js/charts.js @@ -99,6 +99,12 @@ globalThis.htmlLegendPlugin = { } else { // Encode the forward destination as it may contain an "#" character link.href = `queries?upstream=${encodeURIComponent(upstreamIPs[item.index])}`; + + // If server name and IP are different, replace the title tooltip + // including the upstream IP to the text + if (item.text !== upstreamIPs[item.index]) { + link.title = `List ${item.text} (${upstreamIPs[item.index]}) queries`; + } } } else { // no clickable links in other charts From ca57bcfb5c7c388562c0dd9c77be2de8cbe5ebc4 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 16 Sep 2025 16:47:03 -0300 Subject: [PATCH 4/6] Include the upstream DNS server name to the link, when needed The link must send the "upstream" parameter in exactly the same format used by the "suggestions" API. The format is: "upstream=# ()". This will ensure that when a link is clicked, the correct server name will be highlighted in the SELECT element on the queries.lp page and no other OPTION element will be created. Signed-off-by: RD WebDesign --- scripts/js/charts.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/js/charts.js b/scripts/js/charts.js index 967b4bc2..8dc24023 100644 --- a/scripts/js/charts.js +++ b/scripts/js/charts.js @@ -100,10 +100,14 @@ globalThis.htmlLegendPlugin = { // Encode the forward destination as it may contain an "#" character link.href = `queries?upstream=${encodeURIComponent(upstreamIPs[item.index])}`; - // If server name and IP are different, replace the title tooltip - // including the upstream IP to the text + // If server name and IP are different: if (item.text !== upstreamIPs[item.index]) { + // replace the title tooltip to include the upstream IP to the text ... link.title = `List ${item.text} (${upstreamIPs[item.index]}) queries`; + + // ... and include the server name (without port) to the querystring, to match + // the text used on the SELECT element (sent by suggestions API endpoint) + link.href += ` (${item.text.split("#")[0]})`; } } } else { From ec5f8b7037513eeccb478ff0bfa0f1911300902a Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Fri, 19 Sep 2025 16:21:35 -0300 Subject: [PATCH 5/6] Add offset effect on hover to the doughnut charts We need to add a small padding to avoid "clipping" the arc/slice. This happens because when an arc/slice expands, it grows beyond the canvas limits and get clipped. Signed-off-by: RD WebDesign --- scripts/js/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/js/index.js b/scripts/js/index.js index f9edc9d5..3eb1e6ce 100644 --- a/scripts/js/index.js +++ b/scripts/js/index.js @@ -890,6 +890,8 @@ $(() => { elements: { arc: { borderColor: $(".box").css("background-color"), + hoverBorderColor: $(".box").css("background-color"), + hoverOffset: 10, }, }, plugins: { @@ -914,6 +916,9 @@ $(() => { animation: { duration: 750, }, + layout: { + padding: 10, + }, }, }); @@ -936,6 +941,8 @@ $(() => { elements: { arc: { borderColor: $(".box").css("background-color"), + hoverBorderColor: $(".box").css("background-color"), + hoverOffset: 10, }, }, plugins: { @@ -960,6 +967,9 @@ $(() => { animation: { duration: 750, }, + layout: { + padding: 10, + }, }, }); From c6a2e8572e0a75e482cf79d490c94ac986d93611 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Fri, 19 Sep 2025 17:05:49 -0300 Subject: [PATCH 6/6] Trigger the offset effect when the mouse is over a legend item Signed-off-by: RD WebDesign --- scripts/js/charts.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/scripts/js/charts.js b/scripts/js/charts.js index 8dc24023..707c6f79 100644 --- a/scripts/js/charts.js +++ b/scripts/js/charts.js @@ -63,6 +63,23 @@ globalThis.htmlLegendPlugin = { for (const item of items) { const li = document.createElement("li"); + // Select the corresponding "slice" of the chart when the mouse is over a legend item + li.addEventListener("mouseover", () => { + chart.setActiveElements([ + { + datasetIndex: 0, + index: item.index, + }, + ]); + chart.update(); + }); + + // Deselect all "slices" + li.addEventListener("mouseout", () => { + chart.setActiveElements([]); + chart.update(); + }); + // Color checkbox (toggle visibility) const boxSpan = document.createElement("span"); boxSpan.title = "Toggle visibility";