From f425a0523bac577fde840d989a4ecf2b929aed09 Mon Sep 17 00:00:00 2001 From: Herbert Wolverson Date: Fri, 28 Jun 2024 13:51:20 -0500 Subject: [PATCH] Work in Progress - 3D RTT histo playground. --- .../js_build/src/dashlets/dashlet_index.js | 3 + .../js_build/src/dashlets/rtt_histo3d_dash.js | 35 ++++++ .../js_build/src/graphs/rtt_histo_3d.js | 114 ++++++++++++++++++ .../src/node_manager/static2/template.html | 1 + 4 files changed, 153 insertions(+) create mode 100644 src/rust/lqosd/src/node_manager/js_build/src/dashlets/rtt_histo3d_dash.js create mode 100644 src/rust/lqosd/src/node_manager/js_build/src/graphs/rtt_histo_3d.js diff --git a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashlet_index.js b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashlet_index.js index 07f57de3..fc1e550b 100644 --- a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashlet_index.js +++ b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/dashlet_index.js @@ -16,6 +16,7 @@ import {CpuDash} from "./cpu_dash"; import {RamDash} from "./ram_dash"; import {TopTreeSummary} from "./top_tree_summary"; import {CombinedTopDashlet} from "./combined_top_dash"; +import {RttHisto3dDash} from "./rtt_histo3d_dash"; export const DashletMenu = [ { name: "Throughput Bits/Second", tag: "throughputBps", size: 3 }, @@ -24,6 +25,7 @@ export const DashletMenu = [ { name: "Tracked Flows Counter", tag: "trackedFlowsCount", size: 3 }, { name: "Last 5 Minutes Throughput", tag: "throughputRing", size: 6 }, { name: "Round-Trip Time Histogram", tag: "rttHistogram", size: 6 }, + { name: "Round-Trip Time Histogram 3D", tag: "rttHistogram3D", size: 6 }, { name: "Top 10 Downloaders", tag: "top10downloaders", size: 6 }, { name: "Worst 10 Round-Trip Time", tag: "worst10downloaders", size: 6 }, { name: "Worst 10 Retransmits", tag: "worst10retransmits", size: 6 }, @@ -47,6 +49,7 @@ export function widgetFactory(widgetName, count) { case "trackedFlowsCount": widget = new TrackedFlowsCount(count); break; case "throughputRing": widget = new ThroughputRingDash(count); break; case "rttHistogram": widget = new RttHistoDash(count); break; + case "rttHistogram3D": widget = new RttHisto3dDash(count); break; case "top10downloaders":widget = new Top10Downloaders(count); break; case "worst10downloaders":widget = new Worst10Downloaders(count); break; case "worst10retransmits":widget = new Worst10Retransmits(count); break; diff --git a/src/rust/lqosd/src/node_manager/js_build/src/dashlets/rtt_histo3d_dash.js b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/rtt_histo3d_dash.js new file mode 100644 index 00000000..912ee293 --- /dev/null +++ b/src/rust/lqosd/src/node_manager/js_build/src/dashlets/rtt_histo3d_dash.js @@ -0,0 +1,35 @@ +import {BaseDashlet} from "./base_dashlet"; +import {RttHistogram3D} from "../graphs/rtt_histo_3d"; + +export class RttHisto3dDash extends BaseDashlet{ + constructor(slot) { + super(slot); + } + + title() { + return "Round-Trip Time Histogram 3D"; + } + + subscribeTo() { + return [ "RttHistogram" ]; + } + + buildContainer() { + let base = super.buildContainer(); + let gd = this.graphDiv(); + gd.style.height = "500px"; + base.appendChild(gd); + return base; + } + + setup() { + super.setup(); + this.graph = new RttHistogram3D(this.graphDivId()); + } + + onMessage(msg) { + if (msg.event === "RttHistogram") { + this.graph.update(msg.data); + } + } +} \ No newline at end of file diff --git a/src/rust/lqosd/src/node_manager/js_build/src/graphs/rtt_histo_3d.js b/src/rust/lqosd/src/node_manager/js_build/src/graphs/rtt_histo_3d.js new file mode 100644 index 00000000..23c7d4bb --- /dev/null +++ b/src/rust/lqosd/src/node_manager/js_build/src/graphs/rtt_histo_3d.js @@ -0,0 +1,114 @@ +import {DashboardGraph} from "./dashboard_graph"; +import {lerpGreenToRedViaOrange} from "../helpers/scaling"; + +export class RttHistogram3D extends DashboardGraph { + constructor(id) { + super(id); + this.ring = new RingBuffer(300); + + let timeAxis = []; + for (let i=0; i<300; i++) timeAxis.push(i.toString()); + + let catAxis = []; + for (let i=0; i<20; i++) catAxis.push(i.toString()); + + /*let data = []; + for (let z=0; z<300; z++) { + for (let x=0; x<20; x++) { + data.push([ x, z, 1 ]); + } + }*/ + let data = this.ring.series(); + + this.option = { + tooltip: {}, + visualMap: { + max: 20, + inRange: { + color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'] + } + }, + xAxis3D: { + type: 'category', + data: catAxis + }, + yAxis3D: { + type: 'category', + data: timeAxis + }, + zAxis3D: { + type: 'value' + }, + grid3D: { + boxWidth: 100, + boxDepth: 100, + light: { + main: { + intensity: 1.2 + }, + ambient: { + intensity: 0.3 + } + } + }, + series: [{ + type: 'bar3D', + data: data, + shading: 'color', + label: { + show: false + }, + }] + }; + this.option && this.chart.setOption(this.option); + } + + update(rtt) { + this.chart.hideLoading(); + this.ring.push(rtt); + this.option.series[0].data = this.ring.series(); + this.chart.setOption(this.option); + } +} + +class RingBuffer { + constructor(size) { + this.size = size; + let data = []; + for (let i=0; i +