Files
ThingsBoard/Widgets/topology/topology.js
2022-07-21 13:58:09 -05:00

158 lines
5.2 KiB
JavaScript

self.onInit = function () {
//self.onResize();
//self.draw();
};
self.onDataUpdated = function () {
//self.draw();
};
//function for scaling a canvas
function fitToContainer(canvas) {
canvas.style.width = "100%";
canvas.style.height = "100%";
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
}
class Node {
constructor(id, x, y, radius, data) {
this.id = id;
this.x = x;
this.y = y;
this.radius = Math.min(radius, 25);
this.lineLength = 25;
this.data = data;
}
draw() {
this.node = new Path2D();
this.node.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
self.ctx.canvas.textAlign = "center";
self.ctx.canvas.textBaseline = "middle";
self.ctx.canvas.strokeText(this.data, this.x, this.y);
self.ctx.canvas.fillStyle = "White";
self.ctx.canvas.stroke(this.node);
self.ctx.canvas.fill(this.node);
}
setX(x) {
this.x = x;
}
setY(y) {
this.y = y;
}
setRadius(radius) {
this.radius = radius;
}
}
class Edge {
constructor(source, target) {
this.source = source;
this.target = target;
//this.draw();
}
draw() {
self.ctx.canvas.moveTo(self.nodes[this.source].x, self.nodes[this.source].y);
self.ctx.canvas.lineTo(self.nodes[this.target].x, self.nodes[this.target].y);
self.ctx.canvas.stroke();
}
}
function getDepth(edges) {
var depth = 1;
console.log(edges);
if (Object.keys(edges).length > 0) {
Object.keys(edges).forEach((target) => {
console.log("Target: " + target);
Object.keys(edges).forEach((nTarget) => {
edges[nTarget].forEach((edge) => {
console.log("Source: " + edge.source);
if (edge.source == target) {
console.log("recurse");
var slice = Object.fromEntries(Object.entries(edges).slice(0, Object.keys(edges).indexOf(target)) + Object.entries(edges).slice(Object.keys(edges).indexOf(target)) + 1);
depth = depth + getDepth(slice);
}
});
});
});
}
console.log("Depth: " + depth);
return depth;
}
function placeNodes() {
var numSourceNodes = Object.keys(self.nodes).length - Object.keys(self.edges).length;
var depth = getDepth(self.edges);
console.log(depth);
if (Object.keys(self.nodes).length == 1) {
self.nodes[Object.keys(self.nodes)[0]].setX(self.canvas.width / 2);
self.nodes[Object.keys(self.nodes)[0]].setY(self.canvas.height / 2);
self.nodes[Object.keys(self.nodes)[0]].setRadius(self.canvas.height * 0.1);
} else {
var counter = 0;
Object.keys(self.edges).forEach((target) => {
self.edges[target].forEach((edge) => {
self.nodes[edge.source].setX(self.canvas.width * (1 / (Object.keys(self.edges).length + 2)));
self.nodes[edge.source].setY(self.canvas.height * ((counter + 1) / (numSourceNodes + 1)));
self.nodes[edge.source].setRadius(self.canvas.height * (1 / (2 * (Object.keys(self.nodes).length + 1))));
self.nodes[edge.target].setX(self.canvas.width * (2 / (Object.keys(self.edges).length + 2)));
self.nodes[edge.target].setY(self.canvas.height * ((Object.keys(self.edges).indexOf(target) + 1) / (Object.keys(self.edges).length + 1)));
self.nodes[edge.target].setRadius(self.canvas.height * (1 / (2 * (Object.keys(self.nodes).length + 1))));
counter++;
});
});
}
}
self.draw = function () {
self.canvas = document.getElementById("topology");
self.ctx.canvas = self.canvas.getContext("2d");
fitToContainer(self.canvas);
self.ctx.canvas.globalCompositeOperation = "destination-over";
var collapse = false;
self.nodes = {};
let numNodes = 9;
//var centerNode = new Node(100, self.canvas.width * 0.11, self.canvas.height * 0.5, self.canvas.height * (1 / (2 * (numNodes + 1))), 1);
for (let i = 0; i < numNodes; i++) {
self.nodes[i] = new Node(i, 0, 0, 0, i);
//self.nodes[i] = new Node(i, self.canvas.width * 0.11, self.canvas.height * ((i + 1) / (numNodes + 1)), self.canvas.height * (1 / (2 * (numNodes + 1))), (Math.random() * 10).toFixed(2));
//self.nodes[i].draw();
}
self.edges = { 0: [new Edge(3, 0), new Edge(4, 0), new Edge(5, 0), new Edge(6, 0)], 8: [new Edge(0, 8)], 7: [new Edge(8, 7)], 2: [new Edge(1, 2)] };
placeNodes();
Object.keys(self.nodes).forEach((key) => {
self.nodes[key].draw();
});
Object.keys(self.edges).forEach((target) => {
self.edges[target].forEach((edge) => {
edge.draw();
});
});
//self.edges.push(new Edge(0,0));
/*let rNodes = Math.round(numNodes * 0.5);
for (let i = 0; i < rNodes; i++) {
self.nodes[i + numNodes] = new Node(i + numNodes, self.canvas.width * 0.89, self.canvas.height * ((i + 1) / (rNodes + 1)), self.canvas.height * (1 / (2 * (rNodes + 1))), (Math.random() * 20).toFixed(2));
self.nodes[i + numNodes].draw();
}
//self.nodes["hidden1"] = new Node("hidden1", self.canvas.width * 0.3, self.canvas.height * 0.5, 0, "");
//self.nodes["hidden2"] = new Node("hidden2", self.canvas.width * 0.6, self.canvas.height * 0.5, 0, "");
for (i = 0; i < numNodes; i++) {
new Edge(i, "hidden1");
}
new Edge("hidden1", "hidden2");
for (i = numNodes; i < numNodes + rNodes; i++) {
new Edge("hidden2", i);
}
*/
};
self.onResize = function () {
self.draw();
};
self.onDestroy = function () {};