aucoin/tools/network-visualization/script.js
Casper V. Kristensen b7053ad014
Publish
2018-07-15 23:30:55 +02:00

167 lines
3.5 KiB
JavaScript

let input = document.getElementById('select-json');
let textInput = document.getElementById('text-json');
let text = document.getElementById('text');
let simulation;
let links;
let nodes;
let context;
textInput.onchange = function change() {
try {
json = JSON.parse(this.value);
nodes = buildNodes(json);
links = buildLinks(json);
} catch (e) {
alert(e.message);
return;
}
render(json);
}
input.onchange = function change() {
var reader = new FileReader();
reader.onload = () => {
let text = reader.result;
try {
json = JSON.parse(text);
nodes = buildNodes(json);
links = buildLinks(json);
} catch (e) {
alert(e.message);
return;
}
render(json);
}
reader.readAsText(this.files[0]);
};
function buildNodes(json) {
let keys = Object.keys(json);
return keys.map(key => ({ id: key, group: 1 }));
}
function buildLinks(json) {
let keys = Object.keys(json);
let lengths = {};
keys.forEach(key => lengths[key] = json[key].length);
return keys.reduce((acc, key) => {
let list = [];
json[key].forEach(t => {
if (keys.indexOf(t) > -1) {
list.push({ source: key, target: t });
}
});
return acc.concat(list);
}, []);
}
function render(json) {
let n = nodes.length;
text.innerText = `Total of ${n} nodes`;
let canvas = document.querySelector("canvas");
let width = window.innerWidth,
height = window.innerHeight;
context = canvas.getContext("2d");
d3.select(canvas)
.attr('width', width * window.devicePixelRatio)
.attr('height', height * window.devicePixelRatio)
.style('width', width + 'px')
.style('height', height + 'px');
context.scale(window.devicePixelRatio, window.devicePixelRatio);
simulation = d3.forceSimulation()
.force('link', d3.forceLink().id(d => d.id).distance(300))
.force('charge', d3.forceManyBody())
.force('center', d3.forceCenter(width / 2, height / 2));
simulation.nodes(nodes)
.on('tick', ticked);
simulation.force('link')
.links(links);
d3.select(canvas)
.call(d3.drag()
.container(canvas)
.subject(dragsubject)
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended));
function ticked() {
context.clearRect(0, 0, width, height);
links.forEach(drawLink);
nodes.forEach(drawNode);
}
function dragsubject() {
return simulation.find(d3.event.x, d3.event.y);
}
}
function dragstarted() {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d3.event.subject.fx = d3.event.subject.x;
d3.event.subject.fy = d3.event.subject.y;
}
function dragged() {
d3.event.subject.fx = d3.event.x;
d3.event.subject.fy = d3.event.y;
}
function dragended() {
if (!d3.event.active) simulation.alphaTarget(0);
d3.event.subject.fx = null;
d3.event.subject.fy = null;
}
function drawLink(d) {
context.beginPath();
context.moveTo(d.source.x, d.source.y);
context.lineTo(d.target.x, d.target.y);
context.lineWidth = 3;
if (d.target.id === "127.0.0.1" || d.source.id === "127.0.0.1") {
context.strokeStyle = "red";
} else if (d.target.id === "127.0.0.2" || d.source.id === "127.0.0.2") {
context.strokeStyle = "green";
} else {
context.strokeStyle = "#aaa";
}
context.stroke();
}
function drawNode(d) {
context.beginPath();
context.moveTo(d.x + 10, d.y);
context.arc(d.x, d.y, 10, 0, 2 * Math.PI);
context.lineWidth = 1;
if (d.id === "127.0.0.1") {
context.fillStyle = "red";
} else if (d.id === "127.0.0.2" ) {
context.fillStyle = "green";
} else {
context.fillStyle = "black";
}
context.fill();
context.strokeStyle = "#fff";
context.stroke();
}