Created
November 19, 2019 21:15
-
-
Save strawstack/bd339d1b304a6bf02d68bfdc80e1f2d1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html><head> | |
<!-- REQUIRED --> | |
<!-- | |
File called 'graph.json' in the same directory containing | |
list of edges. Example: | |
[ | |
["A", "B"], | |
["C", "D"], | |
["A", "C"], | |
["C", "E"] | |
] | |
Serve this file over http/https | |
--> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Include D3.js --> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<style> | |
html, body { | |
padding: 0px; | |
margin: 0px; | |
height: 100%; | |
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; | |
font-weight: 300; | |
} | |
svg { | |
width: 100vw; | |
height: 100vh; | |
} | |
.edge { | |
stroke: #555; | |
} | |
.node>text { | |
stroke: #333; | |
} | |
.node>circle { | |
stroke: #555; | |
stroke-width: 3px; | |
fill: white; | |
cursor: pointer; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
var width = 960, | |
height = 500; | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
d3.json("graph.json").then(data => { | |
// Object to hold nodes and edges | |
let graph = {"nodes": {}, "edges": []}; | |
// For each edge from graph.json | |
// create an object with a source and target | |
data.forEach(edge => graph.edges.push({ | |
"source": edge[0], | |
"target": edge[1] | |
})); | |
// Create flat (1-dimensional) array from the list of edges | |
let nodes = data.flat(); | |
// Remove duplicates from the list of vertices | |
nodes = [...new Set(nodes)]; | |
// Create dictionary where each node will map to its properties | |
for (node of nodes) { | |
graph.nodes[node] = { | |
"label": node, | |
// Assign random coordinates to each vertex | |
"x": Math.random() * 500 + 100, | |
"y": Math.random() * 500 + 100 | |
}; | |
} | |
// Add node refs to each link | |
graph.edges.forEach(d => { | |
d.source = graph.nodes[d.source]; | |
d.target = graph.nodes[d.target]; | |
}); | |
//console.log(graph); | |
var edge = svg.selectAll(".edge") | |
.data(graph.edges) | |
.enter().append("line") | |
.attr("class", "edge") | |
.attr("x1", d => d.source.x) | |
.attr("y1", d => d.source.y) | |
.attr("x2", d => d.target.x) | |
.attr("y2", d => d.target.y); | |
var node = svg.selectAll("node") | |
.data(Object.values(graph.nodes)) | |
.enter().append("g") | |
.attr("class", "node"); | |
node.append("circle") | |
.attr("r", 20) | |
.attr("cx", d => d.x) | |
.attr("cy", d => d.y) | |
.call(d3.drag().on("drag", dragged)); | |
node.append("text") | |
.attr("dx", d => d.x) | |
.attr("dy", d => d.y) | |
.attr("text-anchor", "middle") | |
.attr("dominant-baseline", "central") | |
.attr("pointer-events", "none") | |
.text(d => d.label); | |
function dragged(d) { | |
d.x = d3.event.x, d.y = d3.event.y; | |
d3.select(this).attr("cx", d.x).attr("cy", d.y); | |
d3.select(this.parentNode).select("text").attr("dx", d.x).attr("dy", d.y); | |
edge.filter(function(l) { return l.source === d; }).attr("x1", d.x).attr("y1", d.y); | |
edge.filter(function(l) { return l.target === d; }).attr("x2", d.x).attr("y2", d.y); | |
} | |
}).catch(e => console.log(e)); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment