mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Offer visual sankey alternatives for Top 10 Downloaders, Worst 10 RTT and Worst 10 Retransmit.
This commit is contained in:
parent
f9e416ba07
commit
699542501c
@ -22,6 +22,8 @@ import {TreeCapacityDash} from "./tree_capacity_dash";
|
||||
import {CircuitCapacityDash} from "./circuit_capacity_dash";
|
||||
import {TopTreeSankey} from "./top_tree_sankey";
|
||||
import {Top10DownloadersVisual} from "./top10_downloads_graphic";
|
||||
import {Worst10DownloadersVisual} from "./worst10_downloaders_graphic";
|
||||
import {Worst10RetransmitsVisual} from "./worst10_retransmits_graphic";
|
||||
|
||||
export const DashletMenu = [
|
||||
{ name: "Throughput Bits/Second", tag: "throughputBps", size: 3 },
|
||||
@ -33,7 +35,9 @@ export const DashletMenu = [
|
||||
{ name: "Top 10 Downloaders", tag: "top10downloaders", size: 6 },
|
||||
{ name: "Top 10 Downloaders (Visual)", tag: "top10downloadersV", size: 6 },
|
||||
{ name: "Worst 10 Round-Trip Time", tag: "worst10downloaders", size: 6 },
|
||||
{ name: "Worst 10 Round-Trip Time (Visual)", tag: "worst10downloadersV", size: 6 },
|
||||
{ name: "Worst 10 Retransmits", tag: "worst10retransmits", size: 6 },
|
||||
{ name: "Worst 10 Retransmits (Visual)", tag: "worst10retransmitsV", size: 6 },
|
||||
{ name: "Top 10 Flows (total bytes)", tag: "top10flowsBytes", size: 6 },
|
||||
{ name: "Top 10 Flows (rate)", tag: "top10flowsRate", size: 6 },
|
||||
{ name: "Top 10 Endpoints by Country", tag: "top10endpointsCountry", size: 6 },
|
||||
@ -63,7 +67,9 @@ export function widgetFactory(widgetName, count) {
|
||||
case "top10downloaders":widget = new Top10Downloaders(count); break;
|
||||
case "top10downloadersV":widget = new Top10DownloadersVisual(count); break;
|
||||
case "worst10downloaders":widget = new Worst10Downloaders(count); break;
|
||||
case "worst10downloadersV":widget = new Worst10DownloadersVisual(count); break;
|
||||
case "worst10retransmits":widget = new Worst10Retransmits(count); break;
|
||||
case "worst10retransmitsV":widget = new Worst10RetransmitsVisual(count); break;
|
||||
case "top10flowsBytes" : widget = new Top10FlowsBytes(count); break;
|
||||
case "top10flowsRate" : widget = new Top10FlowsRate(count); break;
|
||||
case "top10endpointsCountry" : widget = new Top10EndpointsByCountry(count); break;
|
||||
|
@ -1,40 +1,10 @@
|
||||
import {BaseDashlet} from "./base_dashlet";
|
||||
import {RttHistogram} from "../graphs/rtt_histo";
|
||||
import {clearDashDiv, theading, TopNTableFromMsgData, topNTableHeader, topNTableRow} from "../helpers/builders";
|
||||
import {
|
||||
scaleNumber,
|
||||
rttCircleSpan,
|
||||
formatThroughput,
|
||||
formatRtt,
|
||||
formatRetransmit,
|
||||
lerpGreenToRedViaOrange, lerpColor
|
||||
} from "../helpers/scaling";
|
||||
import {redactCell} from "../helpers/redact";
|
||||
import {DashboardGraph} from "../graphs/dashboard_graph";
|
||||
|
||||
class Top10DownloadSankey extends DashboardGraph {
|
||||
constructor(id) {
|
||||
super(id);
|
||||
this.option = {
|
||||
series: [
|
||||
{
|
||||
nodeAlign: 'left',
|
||||
type: 'sankey',
|
||||
data: [],
|
||||
links: []
|
||||
}
|
||||
]
|
||||
};
|
||||
this.option && this.chart.setOption(this.option);
|
||||
}
|
||||
|
||||
update(data, links) {
|
||||
this.option.series[0].data = data;
|
||||
this.option.series[0].links = links;
|
||||
this.chart.hideLoading();
|
||||
this.chart.setOption(this.option);
|
||||
}
|
||||
}
|
||||
import {TopNSankey} from "../graphs/top_n_sankey";
|
||||
|
||||
export class Top10DownloadersVisual extends BaseDashlet {
|
||||
constructor(slot) {
|
||||
@ -65,60 +35,13 @@ export class Top10DownloadersVisual extends BaseDashlet {
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
this.graph = new Top10DownloadSankey(this.graphDivId());
|
||||
this.graph = new TopNSankey(this.graphDivId());
|
||||
}
|
||||
|
||||
onMessage(msg) {
|
||||
if (msg.event === "TopDownloads") {
|
||||
//console.log(msg);
|
||||
|
||||
let nodes = [];
|
||||
let links = [];
|
||||
|
||||
nodes.push({
|
||||
name: "Root",
|
||||
label: "Root",
|
||||
});
|
||||
|
||||
msg.data.forEach((r) => {
|
||||
let label = {
|
||||
fontSize: 9,
|
||||
color: "#999"
|
||||
};
|
||||
|
||||
let name = r.ip_address+ " (" + scaleNumber(r.bits_per_second.down, 0) + ", " + r.tcp_retransmits.down + "/" + r.tcp_retransmits.up + ")";
|
||||
let bytes = r.bits_per_second.down / 8;
|
||||
let bytesAsMegabits = bytes / 1000000;
|
||||
let maxBytes = r.plan.down / 8;
|
||||
let percent = Math.min(100, (bytesAsMegabits / maxBytes) * 100);
|
||||
let capacityColor = lerpGreenToRedViaOrange(100 - percent, 100);
|
||||
|
||||
let rttColor = lerpGreenToRedViaOrange(200 - r.median_tcp_rtt, 200);
|
||||
|
||||
let percentRxmit = Math.min(100, r.tcp_retransmits.down + r.tcp_retransmits.up) / 100;
|
||||
let rxmitColor = lerpColor([0, 255, 0], [255, 0, 0], percentRxmit);
|
||||
|
||||
nodes.push({
|
||||
name: name,
|
||||
label: label,
|
||||
itemStyle: {
|
||||
color: rxmitColor,
|
||||
borderWidth: 4,
|
||||
borderColor: rttColor,
|
||||
}
|
||||
});
|
||||
|
||||
links.push({
|
||||
source: "Root",
|
||||
target: name,
|
||||
value: r.bits_per_second.down,
|
||||
lineStyle: {
|
||||
color: capacityColor
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.graph.update(nodes, links);
|
||||
this.graph.processMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import {BaseDashlet} from "./base_dashlet";
|
||||
import {TopNSankey} from "../graphs/top_n_sankey";
|
||||
|
||||
export class Worst10DownloadersVisual extends BaseDashlet {
|
||||
constructor(slot) {
|
||||
super(slot);
|
||||
}
|
||||
|
||||
canBeSlowedDown() {
|
||||
return true;
|
||||
}
|
||||
|
||||
title() {
|
||||
return "Worst 10 Round-Trip Time";
|
||||
}
|
||||
|
||||
tooltip() {
|
||||
return "<h5>Worst 10 Round-Trip Time</h5><p>Worst 10 Downloaders by round-trip time, including IP address, download and upload rates, round-trip time, TCP retransmits, and shaping plan.</p>";
|
||||
}
|
||||
|
||||
subscribeTo() {
|
||||
return [ "WorstRTT" ];
|
||||
}
|
||||
|
||||
buildContainer() {
|
||||
let base = super.buildContainer();
|
||||
base.appendChild(this.graphDiv());
|
||||
return base;
|
||||
}
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
this.graph = new TopNSankey(this.graphDivId());
|
||||
}
|
||||
|
||||
onMessage(msg) {
|
||||
if (msg.event === "WorstRTT") {
|
||||
this.graph.processMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
import {BaseDashlet} from "./base_dashlet";
|
||||
import {RttHistogram} from "../graphs/rtt_histo";
|
||||
import {clearDashDiv, theading, TopNTableFromMsgData, topNTableHeader, topNTableRow} from "../helpers/builders";
|
||||
import {scaleNumber, rttCircleSpan, formatRtt, formatThroughput} from "../helpers/scaling";
|
||||
import {redactCell} from "../helpers/redact";
|
||||
import {TopNSankey} from "../graphs/top_n_sankey";
|
||||
|
||||
export class Worst10RetransmitsVisual extends BaseDashlet {
|
||||
constructor(slot) {
|
||||
super(slot);
|
||||
}
|
||||
|
||||
canBeSlowedDown() {
|
||||
return true;
|
||||
}
|
||||
|
||||
title() {
|
||||
return "Worst 10 TCP Re-transmits";
|
||||
}
|
||||
|
||||
tooltip() {
|
||||
return "<h5>Worst 10 TCP Re-transmits</h5><p>Worst 10 Downloaders by TCP retransmits, including IP address, download and upload rates, round-trip time, TCP retransmits, and shaping plan.</p>";
|
||||
}
|
||||
|
||||
subscribeTo() {
|
||||
return [ "WorstRetransmits" ];
|
||||
}
|
||||
|
||||
buildContainer() {
|
||||
let base = super.buildContainer();
|
||||
base.appendChild(this.graphDiv());
|
||||
return base;
|
||||
}
|
||||
|
||||
setup() {
|
||||
super.setup();
|
||||
this.graph = new TopNSankey(this.graphDivId());
|
||||
}
|
||||
|
||||
onMessage(msg) {
|
||||
if (msg.event === "WorstRetransmits") {
|
||||
this.graph.processMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
import {DashboardGraph} from "./dashboard_graph";
|
||||
import {lerpColor, lerpGreenToRedViaOrange, scaleNumber} from "../helpers/scaling";
|
||||
|
||||
export class TopNSankey extends DashboardGraph {
|
||||
constructor(id) {
|
||||
super(id);
|
||||
this.option = {
|
||||
series: [
|
||||
{
|
||||
nodeAlign: 'left',
|
||||
type: 'sankey',
|
||||
data: [],
|
||||
links: []
|
||||
}
|
||||
]
|
||||
};
|
||||
this.option && this.chart.setOption(this.option);
|
||||
}
|
||||
|
||||
update(data, links) {
|
||||
this.option.series[0].data = data;
|
||||
this.option.series[0].links = links;
|
||||
this.chart.hideLoading();
|
||||
this.chart.setOption(this.option);
|
||||
}
|
||||
|
||||
processMessage(msg) {
|
||||
let nodes = [];
|
||||
let links = [];
|
||||
|
||||
nodes.push({
|
||||
name: "Root",
|
||||
label: "Root",
|
||||
});
|
||||
|
||||
msg.data.forEach((r) => {
|
||||
let label = {
|
||||
fontSize: 9,
|
||||
color: "#999"
|
||||
};
|
||||
|
||||
let name = r.ip_address+ " (" + scaleNumber(r.bits_per_second.down, 0) + ", " + r.tcp_retransmits.down + "/" + r.tcp_retransmits.up + ")";
|
||||
let bytes = r.bits_per_second.down / 8;
|
||||
let bytesAsMegabits = bytes / 1000000;
|
||||
let maxBytes = r.plan.down / 8;
|
||||
let percent = Math.min(100, (bytesAsMegabits / maxBytes) * 100);
|
||||
let capacityColor = lerpGreenToRedViaOrange(100 - percent, 100);
|
||||
|
||||
let rttColor = lerpGreenToRedViaOrange(200 - r.median_tcp_rtt, 200);
|
||||
|
||||
let percentRxmit = Math.min(100, r.tcp_retransmits.down + r.tcp_retransmits.up) / 100;
|
||||
let rxmitColor = lerpColor([0, 255, 0], [255, 0, 0], percentRxmit);
|
||||
|
||||
nodes.push({
|
||||
name: name,
|
||||
label: label,
|
||||
itemStyle: {
|
||||
color: rxmitColor,
|
||||
borderWidth: 4,
|
||||
borderColor: rttColor,
|
||||
}
|
||||
});
|
||||
|
||||
links.push({
|
||||
source: "Root",
|
||||
target: name,
|
||||
value: r.bits_per_second.down,
|
||||
lineStyle: {
|
||||
color: capacityColor
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.update(nodes, links);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user