ntopng/http_src/components/ntopChartApex.js
Matteo Biscosi 4e31f600f6 Revert "Added Vite to frontend builds"
This reverts commit 2b5d2d7949.
2025-05-22 15:32:21 +02:00

748 lines
24 KiB
JavaScript

/**
(C) 2022 - ntop.org
*/
import { ntopng_utility } from '../services/context/ntopng_globals_services';
import NtopUtils from "../utilities/ntop-utils";
import FormatterUtils from "../utilities/formatter-utils.js";
const ntopChartApex = function () {
// define default chartOptions for all chart type.
const _default_BASE_ChartOptions = {
series: [],
chart: {
height: "100%",
width: "100%",
toolbar: {
show: false,
tools: {
zoomout: false,
download: false,
zoomin: false,
zoom: " ",
selection: false,
pan: false,
reset: false
}
},
events: {}
},
xaxis: {
tooltip: {
enabled: false,
},
},
yaxis: {
labels: {
show: true,
style: {
colors: [],
fontSize: "11px",
fontWeight: 400,
cssClass: ""
}
},
title: {
rotate: -90,
offsetY: 0,
offsetX: 0,
style: {
fontSize: "11px",
fontWeight: 900,
cssClass: ""
}
},
tooltip: {
enabled: false,
},
},
grid: {
show: false,
},
legend: {
show: true
},
};
// define default xaxis formatter for chart with datetime on xaxis.
const _setXTimeFormatter = function (chartOptions) {
chartOptions.xaxis.labels.formatter = function (value, { series, seriesIndex, dataPointIndex, w }) {
return ntopng_utility.from_utc_to_server_date_format(value);
};
};
// define default chartOptions for area chart type.
const _default_TS_COLUMN_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_COLUMN_ChartOptions = {
chart: {
stacked: true,
type: "bar",
zoom: {
enabled: false,
type: "x",
},
},
tooltip: {
x: {
format: "dd MMM yyyy HH:mm"
},
y: {}
},
xaxis: {
labels: {
show: true,
datetimeUTC: false,
},
axisTicks: {
show: false,
},
type: "datetime",
axisBorder: {
show: true,
},
convertedCatToNumeric: false
},
dataLabels: {
enabled: false
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
plotOptions: {
bar: {
startingShape: "rounded",
endingShape: "rounded",
borderRadius: 8,
}
}
};
ntopng_utility.copy_object_keys(TS_COLUMN_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_HEATMAP_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let HEATMAP_ChartOptions = {
chart: {
type: "heatmap",
zoom: {
enabled: false,
type: "x",
},
},
tooltip: {
x: {
show: true,
format: "dd MMM yyyy HH:mm"
},
y: {
formatter: (serieName) => {
if (serieName && serieName == 1) {
return "Flows Available";
}
return "No Flows"
}
}
},
xaxis: {
labels: {
show: false,
datetimeUTC: false,
},
axisTicks: {
show: false,
},
type: "datetime",
axisBorder: {
show: true,
},
convertedCatToNumeric: false
},
dataLabels: {
enabled: false
},
stroke: {
show: false,
curve: "smooth"
},
colors: ["#008FFB"],
fill: {
type: "solid"
}
};
ntopng_utility.copy_object_keys(HEATMAP_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_STACKED_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_STACKED_ChartOptions = {
chart: {
stacked: true,
type: "area",
zoom: {
enabled: false,
type: "x",
},
clipMarkers: false
},
tooltip: {
// shared: true,
x: {
format: "dd MMM yyyy HH:mm:ss"
},
y: {}
},
xaxis: {
labels: {
show: true,
datetimeUTC: false,
formatter: null,
},
axisTicks: {
show: false,
},
type: "datetime",
axisBorder: {
show: true,
},
convertedCatToNumeric: false
},
dataLabels: {
enabled: false
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
plotOptions: {
area: {
stacked: true
}
}
};
ntopng_utility.copy_object_keys(TS_STACKED_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_POLAR_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_STACKED_ChartOptions = {
chart: {
stacked: true,
type: "polarArea",
height: 400
},
yaxis: {
show: true,
labels: {
formatter: NtopUtils.bytesToSize
}
},
dataLabels: {
enabled: true,
formatter: function (val, opts) {
return (val ? `${val.toFixed(1)}%` : `0%`)
},
},
legend: {
enabled: true,
position: 'bottom',
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
tooltip: {
y: {
formatter: NtopUtils.bytesToSize
},
},
};
ntopng_utility.copy_object_keys(TS_STACKED_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_DONUT_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_STACKED_ChartOptions = {
chart: {
stacked: true,
type: "donut",
height: 300
},
yaxis: {
show: true,
labels: {
formatter: NtopUtils.bytesToSize
}
},
dataLabels: {
enabled: true,
formatter: function (val, opts) {
return (val ? `${val.toFixed(1)}%` : `0%`)
},
},
legend: {
enabled: true,
position: 'bottom',
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
tooltip: {
y: {
formatter: FormatterUtils.getFormatter("number"),
},
},
noData: {
text: 'No Data',
style: {
color: undefined,
fontSize: '24px',
fontFamily: undefined
}
}
};
ntopng_utility.copy_object_keys(TS_STACKED_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_RADIALBAR_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_STACKED_ChartOptions = {
chart: {
stacked: true,
type: "radialBar",
height: 300
},
yaxis: {
show: true,
},
dataLabels: {
enabled: true,
formatter: function (val, opts) {
return val
},
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
tooltip: {
y: {
formatter: NtopUtils.bytesToSize
},
},
noData: {
text: 'No Data',
style: {
color: undefined,
fontSize: '24px',
fontFamily: undefined
}
},
plotOptions: {
radialBar: {
offsetY: 0,
startAngle: 0,
endAngle: 270,
hollow: {
margin: 5,
size: '30%',
background: 'transparent',
image: undefined,
},
dataLabels: {
name: {
show: false,
},
value: {
show: false,
}
}
}
},
legend: {
show: true,
floating: true,
fontSize: '16px',
position: 'left',
offsetX: 160,
offsetY: 15,
labels: {
useSeriesColors: true,
},
markers: {
size: 0
},
formatter: function (seriesName, opts) {
return seriesName + ": " + opts.w.globals.series[opts.seriesIndex]
},
itemMargin: {
vertical: 3
}
},
responsive: [{
breakpoint: 480,
options: {
legend: {
show: false
}
}
}]
};
ntopng_utility.copy_object_keys(TS_STACKED_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_PIE_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_STACKED_ChartOptions = {
chart: {
stacked: true,
type: "pie",
height: 400
},
yaxis: {
show: true,
labels: {
formatter: NtopUtils.bytesToSize
}
},
dataLabels: {
enabled: true,
formatter: function (val, opts) {
return (val ? `${val.toFixed(1)}%` : `0%`)
},
},
legend: {
enabled: true,
position: 'bottom',
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
tooltip: {
y: {
formatter: NtopUtils.bytesToSize
},
},
};
ntopng_utility.copy_object_keys(TS_STACKED_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for area chart type.
const _default_TS_BAR_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_BAR_ChartOptions = {
chart: {
type: "bar",
height: 300
},
stroke: {
show: true,
width: 2,
colors: ['transparent']
},
dataLabels: {
enabled: false
},
yaxis: {
labels: {
show: true, // Mostra i valori sull'asse Y
},
},
grid: {
show: true, // Abilita la griglia
yaxis: {
lines: {
show: true, // Mostra le linee della griglia su Y
}
}
},
plotOptions: {
bar: {
horizontal: true,
columnWidth: '55%',
borderRadius: 5,
borderRadiusApplication: 'end'
},
},
fill: {
opacity: 1
},
tooltip: {
y: {
title: {
formatter: () => ''
},
formatter: NtopUtils.formatValue
},
},
};
ntopng_utility.copy_object_keys(TS_BAR_ChartOptions, chartOptions, true);
return chartOptions;
}();
// define default chartOptions for line chart type.
const _default_TS_LINE_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_LINE_ChartOptions = {
chart: {
type: "line",
zoom: {
enabled: false,
type: "x",
},
},
tooltip: {
shared: true,
x: {
format: "dd MMM yyyy HH:mm:ss"
},
y: {}
},
xaxis: {
labels: {
show: false,
datetimeUTC: false,
formatter: null,
},
axisTicks: {
show: true
},
type: "datetime",
axisBorder: {
show: true
},
convertedCatToNumeric: false
},
stroke: {
show: true,
width: 2,
curve: "smooth"
},
grid: {
show: true,
},
dataLabels: {
enabled: false
},
};
ntopng_utility.copy_object_keys(TS_LINE_ChartOptions, chartOptions, true);
return chartOptions;
}();
const format_label_from_xname = function ({ series, seriesIndex, dataPointIndex, w }) {
const serie = w.config.series[seriesIndex]["data"][dataPointIndex];
const name = serie["name"]
const y_value = serie["y"];
const host_name = serie["meta"]["label"];
const x_axis_title = w.config.xaxis.title.text;
const y_axis_title = w.config.yaxis[0].title.text;
return (`
<div class='apexcharts-theme-light apexcharts-active' id='test'>
<div class='apexcharts-tooltip-title' style='font-family: Helvetica, Arial, sans-serif; font-size: 12px;'>
${host_name}
</div>
<div class='apexcharts-tooltip-series-group apexcharts-active d-block'>
<div class='apexcharts-tooltip-text text-left'>
<b>${x_axis_title}</b>: ${name}
</div>
<div class='apexcharts-tooltip-text text-left'>
<b>${y_axis_title}</b>: ${y_value}
</div>
</div>
</div>`)
};
// define default chartOptions for line chart type.
const _default_TS_BUBBLE_ChartOptions = function () {
let chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
let TS_BUBBLE_ChartOptions = {
chart: {
width: '100%',
height: '100%',
stacked: true,
type: "bubble",
zoom: {
autoScaleYaxis: true
},
},
legend: {
enabled: true,
position: 'bottom',
},
stroke: {
show: false,
curve: "smooth"
},
fill: {
type: "solid"
},
events: {
dataPointSelection: "standard",
},
grid: {
padding: {
left: 6
},
},
xaxis: {
type: 'numeric',
labels: {}
},
yaxis: {
type: 'numeric',
forceNiceScale: true,
labels: {}
},
dataLabels: {
enabled: false
},
tooltip: {
custom: format_label_from_xname,
}
};
ntopng_utility.copy_object_keys(TS_BUBBLE_ChartOptions, chartOptions, true);
return chartOptions;
}();
return {
typeChart: {
TS_LINE: "TS_LINE",
TS_STACKED: "TS_STACKED",
TS_COLUMN: "TS_COLUMN",
PIE: "PIE",
DONUT: "DONUT",
RADIALBAR: "RADIALBAR",
HEATMAP: "HEATMAP",
RADAR: "RADAR",
BUBBLE: "BUBBLE",
BASE: "BASE",
BAR: "BAR"
},
newChart: function (type) {
let _chartOptions = {};
let _chart;
let _chartHtmlElement;
if (type == this.typeChart.TS_STACKED) {
_chartOptions = ntopng_utility.clone(_default_TS_STACKED_ChartOptions);
_setXTimeFormatter(_chartOptions);
} else if (type == this.typeChart.TS_LINE) {
_chartOptions = ntopng_utility.clone(_default_TS_LINE_ChartOptions);
_setXTimeFormatter(_chartOptions);
} else if (type == this.typeChart.TS_COLUMN) {
_chartOptions = ntopng_utility.clone(_default_TS_COLUMN_ChartOptions);
_setXTimeFormatter(_chartOptions);
} else if (type == this.typeChart.HEATMAP) {
_chartOptions = ntopng_utility.clone(_default_HEATMAP_ChartOptions);
_setXTimeFormatter(_chartOptions);
} else if (type == this.typeChart.PIE) {
_chartOptions = ntopng_utility.clone(_default_TS_PIE_ChartOptions);
} else if (type == this.typeChart.DONUT) {
_chartOptions = ntopng_utility.clone(_default_TS_DONUT_ChartOptions);
} else if (type == this.typeChart.RADIALBAR) {
_chartOptions = ntopng_utility.clone(_default_TS_RADIALBAR_ChartOptions);
} else if (type == this.typeChart.BAR) {
_chartOptions = ntopng_utility.clone(_default_TS_BAR_ChartOptions);
} else if (type == this.typeChart.POLAR) {
_chartOptions = ntopng_utility.clone(_default_TS_POLAR_ChartOptions);
} else if (type == this.typeChart.BUBBLE) {
_chartOptions = ntopng_utility.clone(_default_TS_BUBBLE_ChartOptions);
} else if (type == this.typeChart.BASE) {
_chartOptions = ntopng_utility.clone(_default_BASE_ChartOptions);
} else {
throw `ntopChartApex::newChart: chart type = ${type} unsupported`;
}
const setYaxisFormatter = (chartOptions) => {
if (typeof (chartOptions?.yaxis?.labels?.formatter) == "string") {
const formatter = chartOptions.yaxis.labels.formatter;
let chartFormatter = FormatterUtils.getFormatter(formatter);
if (chartFormatter != null) {
chartOptions.yaxis.labels.formatter = chartFormatter;
} else {
if (formatter == "formatValue") {
chartOptions.yaxis.labels.formatter = FormatterUtils.getFormatter("number");
}
else if (formatter == "bytesToSize") {
chartOptions.yaxis.labels.formatter = FormatterUtils.getFormatter("bytes");
}
}
}
};
return {
drawChart: function (htmlElement, chartOptions) {
// add/replace chartOptions fields in _chartOptions
setYaxisFormatter(chartOptions);
ntopng_utility.copy_object_keys(chartOptions, _chartOptions, true);
_chart = new ApexCharts(htmlElement, _chartOptions);
_chartHtmlElement = htmlElement;
_chart.render();
},
to_data_uri: async function (options) {
if (_chart == null) { return; }
let res = await _chart.dataURI(options);
return res.imgURI;
},
destroyChart: function () {
if (_chart == null) { return; }
_chart.destroy();
},
updateChart: function (chartOptions) {
if (_chart == null) { return; }
setYaxisFormatter(chartOptions);
_chart.updateOptions(chartOptions, false, false, false);
},
updateSeries: function (series) {
if (_chart == null) { return; }
_chart.updateSeries(series);
},
registerEvent: function (eventName, callback, updateChart = false) {
_chartOptions.chart.events[eventName] = callback;
if (updateChart == true) {
_chart.updateOptions(_chartOptions);
}
},
};
},
};
}();
export { ntopChartApex };