ntopng/http_src/vue/dashboard-timeseries.vue
2023-09-25 10:06:07 +00:00

208 lines
6.6 KiB
Vue

<!--
(C) 2013-22 - ntop.org
-->
<!-- :get_params_url_request="get_url_params" -->
<template>
<div>
<TimeseriesChart
ref="chart"
:id="id"
:chart_type="chart_type"
:base_url_request="base_url"
:get_custom_chart_options="get_chart_options"
:register_on_status_change="false"
:disable_pointer_events="true">
</TimeseriesChart>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeMount, watch, computed } from "vue";
import metricsManager from "../utilities/metrics-manager.js";
import { default as TimeseriesChart } from "./timeseries-chart.vue";
import timeseriesUtils from "../utilities/timeseries-utils.js";
/* *************************************************** */
const height_per_row = 62.5 /* px */
const chart_type = ref(ntopChartApex.typeChart.TS_LINE);
const chart = ref(null);
const timeseries_groups = ref([]);
const group_option_mode = ref(null);
const height = ref(null);
const ts_request = ref([]);
/* *************************************************** */
const props = defineProps({
id: String, /* Component ID */
i18n_title: String, /* Title (i18n) */
ifid: Number, /* Interface ID */
epoch_begin: Number, /* Time interval begin */
epoch_end: Number, /* Time interval end */
max_width: Number, /* Component Width (4, 8, 12) */
max_height: Number, /* Component Hehght (4, 8, 12)*/
params: Object, /* Component-specific parameters from the JSON template definition */
get_component_data: Function, /* Callback to request data (REST) */
csrf: String
});
/* *************************************************** */
/* Return the base url of the REST API */
const base_url = computed(() => {
return `${http_prefix}${props.params.url}`;
});
function substitute_ifid(params_to_format, current_ifid) {
let new_formatted_params = {};
for(const param in (params_to_format)) {
if(params_to_format[param].contains('$IFID$')) {
/* Contains $IFID$, substitute with the interface id */
new_formatted_params[param] = params_to_format[param].replace('$IFID$', current_ifid);
} else {
/* does NOT Contains $IFID$, add the plain param */
new_formatted_params[param] = params_to_format[param];
}
}
return new_formatted_params;
}
/* *************************************************** */
/* This function is used to substitute to the $IFID$ found in the
* configuration the correct interface id
*/
async function format_ifids(params_to_format) {
if(ts_request.value.length > 0) {
/* Already populated, return */
return;
}
const ifid_url = "lua/rest/v2/get/ntopng/interfaces.lua"
const ifid_list = await ntopng_utility.http_request(`${http_prefix}/${ifid_url}`) || [];
ifid_list.forEach((iface) => {
let new_formatted_params = substitute_ifid(params_to_format, iface.ifid);
ts_request.value.push(new_formatted_params);
});
}
/* *************************************************** */
/* This function is used to transform the $ANY$ params in the
* correct value (e.g. $ANY_IFID$ -> list of all ifid)
*/
async function resolve_any_params() {
/* Here possible ANY, can be found in the post_params */
const params = props.params.post_params?.ts_requests;
for(const any_param in (params || {})) {
switch (any_param) {
case '$ANY_IFID$':
await format_ifids(params[any_param]);
break;
default:
ts_request.value.push(substitute_ifid(params[any_param], props.ifid));
break;
}
}
}
/* *************************************************** */
/* The source_type can be found on the json and the source_array is automatically generated
* by using the source_type
*/
async function get_timeseries_groups_from_metric(metric_schema, key) {
const status = {
epoch_begin: props.epoch_begin,
epoch_end: props.epoch_end,
};
const source_type = metricsManager.get_source_type_from_id(props.params?.source_type);
const source_array = await metricsManager.get_source_array_from_value_array(http_prefix, source_type, [key]);
const metric = await metricsManager.get_metric_from_schema(http_prefix, source_type, source_array, metric_schema, null, status);
const ts_group = metricsManager.get_ts_group(source_type, source_array, metric);
return ts_group;
}
/* *************************************************** */
async function retrieve_basic_info() {
/* Return the timeseries group, info found in the json */
if(timeseries_groups.value.length == 0) {
for(const value of ts_request.value) {
const metric_schema = value?.ts_schema;
const group = await get_timeseries_groups_from_metric(metric_schema, value.tskey);
timeseries_groups.value.push(group);
}
}
/* NOTE: currently only accepted the 1_chart_x_yaxis mode */
if(group_option_mode.value == null) {
group_option_mode.value = timeseriesUtils.getGroupOptionMode('1_chart_x_yaxis');
}
}
/* *************************************************** */
/* This function run the REST API with the data */
async function get_chart_options() {
await resolve_any_params();
await retrieve_basic_info();
const url = base_url.value;
const post_params = {
csrf: props.csrf,
ifid: props.ifid,
epoch_begin: props.epoch_begin,
epoch_end: props.epoch_end,
...props.params.post_params,
...{
ts_requests: ts_request.value
}
}
/* Have to be used this get_component_data, in order to create report too */
let result = await props.get_component_data(url, '', post_params);
/* Format the result in the format needed by Dygraph */
result = timeseriesUtils.tsArrayToOptionsArray(result, timeseries_groups.value, group_option_mode.value, '');
if(result[0]) {
result[0].height = height.value;
}
return result?.[0];
}
/* *************************************************** */
/* Watch - detect changes on epoch_begin / epoch_end and refresh the component */
watch(() => [props.epoch_begin, props.epoch_end], (cur_value, old_value) => {
refresh_chart();
}, { flush: 'pre'});
/* *************************************************** */
/* Run the init here */
onBeforeMount(async() => {
await init();
});
/* *************************************************** */
onMounted(async() => {});
/* *************************************************** */
/* Defining the needed info by the get_chart_options function */
async function init() {
height.value = (props.max_height || 4) * height_per_row;
}
/* *************************************************** */
/* Refresh function */
async function refresh_chart() {
if(chart.value) {
const result = await get_chart_options();
chart.value.update_chart_series(result.data);
}
}
</script>