Skip to content

Instantly share code, notes, and snippets.

@mattr555
Last active February 14, 2016 17:00
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 mattr555/94d5d8e7b4057dae4d24 to your computer and use it in GitHub Desktop.
Save mattr555/94d5d8e7b4057dae4d24 to your computer and use it in GitHub Desktop.
MAZE in d3.js
height: 850

Visualization of the rooms in Christopher Manson's MAZE. Types for rooms from into the abyss.

var width = 600, height = 800;
var svg = d3.select("#main")
.attr("width", width)
.attr("height", height);
svg.append("defs").selectAll("marker")
.data(["arrow"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
var nodes = {};
var links = [];
var allNodes, allLinks;
var force, path, node;
d3.text("maze.txt", function(error, resp){
function getNode(n){
return nodes[n] || (nodes[n] = {name: n});
}
resp.split('\n').forEach(function(l){
if (!l) return;
l = l.split(' ')
var source = getNode(l[0]);
l.slice(1, -1).forEach(function(i){
var dest = getNode(i);
links.push({source: source, target: dest});
})
source.type = l[l.length-1]
})
force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(50)
.charge(-300)
.on("tick", tick);
allLinks = links.slice(0)
allNodes = JSON.parse(JSON.stringify(nodes))
path = svg.append("g").attr("id", "links").selectAll('.link')
node = svg.append("g").attr("id", "nodes").selectAll('.node')
restart();
})
function tick() {
path.attr("d", function(d){
return "M" + d.source.x + "," + d.source.y +
"L" + d.target.x + "," + d.target.y;
})
node.attr("transform", function(d){
return "translate(" + d.x + "," + d.y + ")";
})
}
function add_back_all(){
var nodesIn = force.nodes().map(function(n){return n.name});
var toAdd = d3.values(allNodes).filter(function(n){return nodesIn.indexOf(n.name) == -1})
for (var i in toAdd){
force.nodes().push(toAdd[i]);
nodes[toAdd[i].name] = toAdd[i]
}
for (var i in allLinks) {
if (force.links().indexOf(allLinks[i]) === -1){
var sourceInd = nodes[allLinks[i].source.name]
var destInd = nodes[allLinks[i].target.name]
force.links().push({source: sourceInd, target: destInd})
}
}
links = force.links()
}
function filter_type(type){
force.stop()
add_back_all()
if (typeof type === 'undefined') {
restart()
return
};
var newNodes = force.nodes()
var newLinks = force.links()
var i = 0, nodeOne
while (i < newNodes.length){
if (newNodes[i].name == "1") nodeOne = newNodes[i]
if (newNodes[i].type !== type){
newNodes.splice(i, 1);
} else {
i++;
}
}
var i = 0
while (i < newLinks.length){
if (newLinks[i].source.type !== type || newLinks[i].target.type !== type){
newLinks.splice(i, 1)
} else {
i++
}
}
if (type === 'loop'){
newNodes.push(nodeOne)
newNodes.forEach(function(n){
if (n.name == "21") {
newLinks.push({source: nodeOne, target: n})
}
if (n.name == "41") {
newLinks.push({source: nodeOne, target: n})
newLinks.push({source: n, target: nodeOne})
}
})
}
links = newLinks
for (var i in nodes){delete(nodes[i])}
for (var i in newNodes){nodes[newNodes[i].name] = newNodes[i]}
restart();
}
function restart(){
path = svg.select("#links").selectAll('.link').data(force.links(), function(d){return d.source.name + "-" + d.target.name})
path.enter().append("path").attr("class", "link").attr("marker-end", "url(#arrow)")
node = svg.select("#nodes").selectAll('.node').data(force.nodes(), function(d){return d.name})
var node_group = node.enter().append("g")
node_group.attr("class", function(d){
return "node " + d.type
})
.call(force.drag);
node_group.append("circle").attr("r", 8);
node_group.append("text").text(function(d){return d.name});
path.exit().remove();
node.exit().remove();
force.nodes(d3.values(nodes)).links(links).start();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>d3 practice</title>
<style>
.node.loop {
fill: yellow
}
.node.trap {
fill: red
}
.node.path {
fill: green
}
path.link {
stroke-width: 2px;
stroke: #666;
}
#arrow {
fill: #666
}
text {
font: 10px sans-serif;
fill: #000
}
</style>
</head>
<body>
<svg id="main"></svg><br>
<button onclick="filter_type()">show all</button>
<button onclick="filter_type('path')">path filter</button>
<button onclick="filter_type('loop')">loop filter</button>
<button onclick="filter_type('trap')">trap filter</button>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="graph.js"></script>
</body>
</html>
16 36 7 loop
7 16 36 33 loop
36 7 16 loop
33 7 35 3 loop
3 33 18 9 loop
18 3 13 loop
13 25 27 18 loop
27 9 13 loop
9 18 3 loop
25 34 13 35 loop
35 33 loop
34 25 10 loop
10 34 41 14 loop
41 1 10 38 35 loop
1 20 21 26 41 path
38 40 22 43 trap
43 22 38 trap
22 43 38 trap
40 11 6 38 trap
6 40 trap
11 40 24 trap
24 trap
20 1 5 27 path
5 43 22 30 20 path
30 42 34 5 15 path
15 30 3 37 path
37 15 10 42 20 path
42 22 30 4 25 37 path
4 44 29 15 11 16 24 43 path
44 21 18 loop
21 44 24 31 loop
31 44 19 21 loop
19 31 11 loop
14 10 43 24 loop
29 8 40 35 2 17 path
2 29 22 12 path
12 2 21 8 39 path
8 31 6 29 12 path
39 11 4 12 path
26 30 36 38 1 path
17 6 33 45 path
45 28 17 36 19 23 path
28 23 43 45 32 path
23 28 8 45 19 path
32 11 16 6 28 path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment