ntopng/httpdocs/js/pages/graph-map.js
2021-09-23 09:43:04 +02:00

386 lines
9.4 KiB
JavaScript

/**
* (C) 2020-21 - ntop.org
* Script used by the network inside the Service/Periodicity Map.
*/
let network;
let updateViewStateId;
let highlightActive = false;
let nodesDataset = [];
let edgesDataser = [];
const SAVE_TIMEOUT = 500;
const MIN_SCALE = 0.15;
if (MAP === undefined) {
console.error("The MAP constant is not defined!");
}
const defaultOptions = {
autoResize: true,
nodes: {
shape: "dot",
scaling: {
min: 10,
max: 30,
label: {
min: 15,
max: 15,
},
},
shadow: false,
},
edges: {
width: 0.15,
color: { inherit: "from" },
smooth: {
type: "continuous",
roundness: 0
},
},
interaction: {
tooltipDelay: 150,
hideEdgesOnDrag: true,
hideEdgesOnZoom: true,
},
physics: {
barnesHut: {
springConstant: 0,
avoidOverlap: 0.3,
gravitationalConstant: -1000,
damping: 0.65,
centralGravity: 0
},
stabilization: {
onlyDynamicEdges: false
}
},
groups: {
unknown: {
shape: "dot",
},
printer: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf02f",
size: 50,
weight:"bold",
},
},
video: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf03d",
size: 50,
weight:"bold",
},
},
workstation: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf108",
size: 50,
weight:"bold",
},
},
laptop: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf109",
size: 50,
weight:"bold",
},
},
tablet: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf10a",
size: 50,
weight:"bold",
},
},
phone: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf10b",
size: 50,
weight:"bold",
},
},
tv: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf26c",
size: 50,
weight:"bold",
},
},
networking: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf0b2",
size: 50,
weight:"bold",
},
},
wifi: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf1eb",
size: 50,
weight:"bold",
},
},
nas: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf1c0",
size: 50,
weight:"bold",
},
},
multimedia: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf001",
size: 50,
weight:"bold",
},
},
iot: {
shape: "icon",
icon: {
face: "'Font Awesome 5 Free'",
code: "\uf491",
size: 50,
weight:"bold",
},
},
},
};
function getTimestampByTime(time) {
if (time === undefined || time === '' || time === 'none') return undefined;
if (time === 'day') return Math.floor(Date.now() / 1000) - 86400;
if (time === 'week') return Math.floor(Date.now() / 1000) - 604800;
if (time === 'month') return Math.floor(Date.now() / 1000) - 2419200;
return Math.floor(Date.now() / 1000);
}
function saveTopologyView(network) {
// get all nodes position
const positions = network.getPositions(data.nodes.map(x => x.id));
// save the nodes position, the network scale and the network view position
const info = {
positions: positions,
network: {
scale: network.getScale(),
position: network.getViewPosition()
}
};
$.post(`${http_prefix}/lua/pro/enterprise/map_handler.lua`, { ifid:ifid, JSON: JSON.stringify(info), csrf: VIEW_CSRF, map: MAP, action: 'save_view',
host: host,
host_pool_id: hostPoolId,
vlan: vlanId,
unicast_only: unicastOnly,
l7proto: l7proto,
only_memory: only_memory,
only_alerted_hosts: only_alerted_hosts,
first_seen: getTimestampByTime(age),
age: age,
});
}
function setEventListenersNetwork(network) {
network.on("click", function(params) {
const target = params.nodes[0];
const selectedNode = data.nodes.find(n => n.id == target);
if(selectedNode) {
$(`#host-extra-info`).removeAttr("hidden");
document.getElementById('host-extra-info').innerHTML = selectedNode.host_extra_info;
}
else
$(`#host-extra-info`).attr("hidden", "hidden");
});
network.on("doubleClick", function (params) {
const target = params.nodes[0];
const selectedNode = data.nodes.find(n => n.id == target);
let query = "";
// same thing for the host_pool_id
if (hostPoolId !== "") {
query += `&host_pool_id=${hostPoolId}`;
}
// for the VLAN id as well
if (vlanId !== "") {
query += `&vlan=${vlanId}`;
}
if (unicastOnly !== "") {
query += `&unicast_only=${unicastOnly}`;
}
if (only_memory !== "") {
query += `&only_memory=${only_memory}`;
}
if (only_alerted_hosts !== "") {
query += `&only_alerted_hosts=${only_alerted_hosts}`;
}
if (l7proto !== "") {
query += `&l7proto=${l7proto}`;
}
if (age !== "") {
query += `&age=${age}`;
}
if (selectedNode !== undefined) {
window.location.href = http_prefix + `/lua/pro/enterprise/${MAP}_map.lua?page=graph&host=` + selectedNode.id + query;
}
});
network.on('zoom', function(e) {
if (network.getScale() <= MIN_SCALE) {
network.moveTo({
scale: MIN_SCALE + 0.25,
position: {x: 0, y: 0},
animation: { duration: 1000, easingFunction: 'easeInOutCubic' }
});
}
if (SAVE_TIMEOUT !== undefined) {
clearTimeout(updateViewStateId);
}
updateViewStateId = setTimeout(saveTopologyView, SAVE_TIMEOUT, network);
});
network.on("dragEnd", function(e) {
if (updateViewStateId !== undefined) {
clearTimeout(updateViewStateId);
}
saveTopologyView(network);
});
}
function loadGraph(container) {
const dataRequest = { ifid: ifid, action: 'load_graph', map: MAP};
// if an host has been defined inside the URL query then add it to the request
const url = NtopUtils.buildURL(`${http_prefix}/lua/pro/enterprise/map_handler.lua`, {
host: host,
host_pool_id: hostPoolId,
vlan: vlanId,
unicast_only: unicastOnly,
l7proto: l7proto,
only_memory: only_memory,
only_alerted_hosts: only_alerted_hosts,
first_seen: getTimestampByTime(age),
age: age,
});
const request = $.get(url, dataRequest);
request.then(function(response) {
data = response;
const {nodes, edges} = data;
// if there are no nodes then show a simple message
if (nodes.length === 0) {
// hide the spinner and show the message
$(`#load-spinner`).fadeOut(function() {
$(this).remove();
$(`#empty-map-message`).fadeIn();
});
return;
}
nodesDataset = new vis.DataSet(nodes);
edgesDataset = new vis.DataSet(edges);
const datasets = {nodes: nodesDataset, edges: edgesDataset};
network = new vis.Network(container, datasets, defaultOptions);
saveTopologyView(network);
setEventListenersNetwork(network);
});
}
function saveScale() {
const scale = {width: $(`.resizable-y-container`).width(), height: $(`.resizable-y-container`).height()};
NtopUtils.saveElementScale($(this), scale);
}
function stabilizeNetwork(network) {
if (network === undefined) {
console.error("The network is undefined!");
return;
}
if (!(network instanceof vis.Network)) {
console.error("Not a vis.Network instance!");
return;
}
network.stabilize(1000);
setTimeout(() => { saveTopologyView(network) }, 1000);
$(`#autolayout-modal`).modal('hide');
}
(() => {
// load old scale for resizable containers
const oldScale = NtopUtils.loadElementScale($(`.resizable-y-container`))
if(oldScale === undefined) {
saveScale();
return;
}
$(`.resizable-y-container`).width(oldScale.width);
$(`.resizable-y-container`).height(oldScale.height);
})();
$(function() {
$(`.resizable-y-container`).on('mouseup', function() {
saveScale();
});
$(`button[data-toggle="tooltip"]`).tooltip();
});