Skip to content

Instantly share code, notes, and snippets.

@strawstack
Created November 19, 2019 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save strawstack/bd339d1b304a6bf02d68bfdc80e1f2d1 to your computer and use it in GitHub Desktop.
Save strawstack/bd339d1b304a6bf02d68bfdc80e1f2d1 to your computer and use it in GitHub Desktop.
<!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