Skip to content

Instantly share code, notes, and snippets.

@ulve
Created October 4, 2017 15:35
Show Gist options
  • Select an option

  • Save ulve/93d1dd6a787567a4d8081ebf43afae88 to your computer and use it in GitHub Desktop.

Select an option

Save ulve/93d1dd6a787567a4d8081ebf43afae88 to your computer and use it in GitHub Desktop.
D3 server graph
<!DOCTYPE html>
<html>
<head>
<title>Miljöinfo</title>
<meta charset="utf-8" />
</head>
<style>
.node {
fill: #f15;
stroke: #fff;
stroke-width: 2px;
}
.link {
stroke: #ccc;
pointer-events: none;
stroke-width: 4px;
}
.edgepath {
fill-opacity: 0;
stroke-opacity: 0;
fill: #32f;
stroke: #f41;
pointer-events: none;
}
.nodelabel {
stroke: "black";
font-size: 16px;
}
.edgelabel {
font-size: 14px;
fill: #500;
}
.info {
display: none;
}
.block {
display: block;
}
</style>
<body>
</body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
function addNodeInfo(node, id) {
var elemDiv = document.createElement('div');
elemDiv.classList.add('info')
elemDiv.innerHTML = '<b>' + node.name + '</b><br/>' + node.data;
elemDiv.id = "info" + id;
document.body.appendChild(elemDiv);
}
function addLinkInfo(link, id) {
var elemDiv = document.createElement('div');
elemDiv.classList.add('info')
elemDiv.innerHTML = '<b>' + link.type + '</b><br>' + link.data;
elemDiv.id = "linkInfo" + id;
document.body.appendChild(elemDiv);
}
let width = 640,
height = 480;
let colors = d3.scale.category10();
let nodes = [
{ name: "Personinfo", data: "Köer: Kö1, Kö2, kö3<br/>Servernamn:u30913<br/>Port:1324" },
{ name: "Sara", data: "Serivces: ArkiveringsTjänst, PersonTjänst<br/>Schemalagda jobb: Rapportgenerator 03:00:00" },
{ name: "Distribution", data: "Köer: Kö1, Kö2, kö3<br/>Servernamn:u30913<br/>Port:1324" },
{ name: "Basinfo", data: "Nå med laser" }
];
let links = [
{ source: 0, target: 1, type: "wls", data: "Portöppning: 192.16.5.2:28000 -> 192.168.5.2:2800" },
{ source: 0, target: 2, type: "https", data: "Portöppning: 192.16.5.2:28000 -> 192.168.5.2:2800" },
{ source: 0, target: 3, type: "shs", data: "Portöppning: 192.16.5.2:28000 -> 192.168.5.2:2800<br/>Lämningskatalog: c:\\lolo\\funfun" },
{ source: 1, target: 2, type: "ftps", data: "Portöppning: 192.16.5.2:28000 -> 192.168.5.2:2800" }
];
let svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
let force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkDistance([200])
.charge([-100])
.theta(0.1)
.gravity(0.05)
.start();
let link = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr("id", function (d, i) { return 'link' + i })
.attr('class', 'link');
let node = svg.selectAll('.node')
.data(nodes)
.enter().append('circle')
.attr({ "r": 30 })
.style("fill", function (d, i) { return colors(i); })
.attr('class', 'node').call(force.drag)
.on('click', function (d, i) {
let el = document.querySelector('#info' + i);
el.classList.toggle('block')
});
let nodelabels = svg.selectAll(".nodelabel")
.data(nodes)
.enter()
.append("text")
.attr({
"x": function (d) { return d.x; },
"y": function (d) { return d.y; },
})
.attr('class', 'nodelabel')
.text(function (d) { return d.name; });
let edgepaths = svg.selectAll(".edgepath")
.data(links)
.enter()
.append('path')
.attr({
'd': function (d) { return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y },
'class': 'edgepath',
'id': function (d, i) { return 'edgepath' + i }
});
let edgelabels = svg.selectAll(".edgelabel")
.data(links)
.enter()
.append('text')
.attr({
'class': 'edgelabel',
'id': function (d, i) { return 'edgelabel' + i },
'dx': 80,
'dy': 0
})
edgelabels.append('textPath')
.attr('xlink:href', function (d, i) { return '#edgepath' + i })
.style("pointer-events", "none")
.text(function (d, i) { return d.type })
.on('click', function (d, i) {
let el = document.querySelector('#linkInfo' + i);
el.classList.toggle('block')
});
svg.append('defs').append('marker')
.attr({
'id': 'arrowhead',
'viewBox': '-0 -5 10 10',
'refX': 10,
'refY': 0,
'orient': 'auto',
'markerWidth': 10,
'markerHeight': 10,
'xoverflow': 'visible'
})
.append('svg:path')
.attr('d', 'M 0,-5 L 10 ,0 L 0,5')
.attr('fill', '#ccc')
.attr('stroke', '#ccc');
force.on("tick", function () {
link.attr({
"x1": function (d) { return d.source.x; },
"y1": function (d) { return d.source.y; },
"x2": function (d) { return d.target.x; },
"y2": function (d) { return d.target.y; }
});
node.attr({
"cx": function (d) { return d.x; },
"cy": function (d) { return d.y; }
});
nodelabels.attr("x", function (d) { return d.x; })
.attr("y", function (d) { return d.y; });
edgepaths.attr('d', function (d) {
var path = 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
return path
});
edgelabels.attr('transform', function (d, i) {
if (d.target.x < d.source.x) {
bbox = this.getBBox();
rx = bbox.x + bbox.width / 2;
ry = bbox.y + bbox.height / 2;
return 'rotate(180 ' + rx + ' ' + ry + ')';
}
else {
return 'rotate(0)';
}
});
});
force.start();
nodes.forEach(addNodeInfo);
links.forEach(addLinkInfo);
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment