Skip to content

Instantly share code, notes, and snippets.

@emeeks
Created April 30, 2016 17:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save emeeks/38b7f4552e63c88f2c3afe76efda0b58 to your computer and use it in GitHub Desktop.
Save emeeks/38b7f4552e63c88f2c3afe76efda0b58 to your computer and use it in GitHub Desktop.
Boole Hasse Diagram

A Hasse diagram drawn using the new D3v4 force-layout by specifying a d3.forceY constraint based on the distance from an arbitrary root node, in this case "FALSE".

source target
FALSE p&q
FALSE p&¬q
FALSE ¬p&q
FALSE ¬p&¬q
p&q p
p&q q
p&q p IFF q
p&¬q p
p&¬q p IFF ¬q
p&¬q (¬q)
¬p&q p IFF ¬q
¬p&q q
¬p&q (¬p)
¬p&¬q p IFF q
¬p&¬q (¬q)
¬p&¬q (¬p)
p pvq
p q IMPLIES p
q pvq
q p IMPLIES q
p IFF q q IMPLIES p
p IFF q p IMPLIES q
p IFF ¬q pvq
p IFF ¬q ¬pv¬q
(¬q) q IMPLIES p
(¬q) ¬pv¬q
(¬p) p IMPLIES q
(¬p) ¬pv¬q
pvq TRUE
q IMPLIES p TRUE
p IMPLIES q TRUE
¬pv¬q TRUE
<html>
<head>
<title>d3v4 Boole Hasse Diagram</title>
<meta charset="utf-8" />
<script src="https://d3js.org/d3.v4.0.0-alpha.33.min.js"></script>
</head>
<style>
svg {
height: 500px;
width: 500px;
border: 1px solid gray;
}
</style>
<body>
<div id="viz">
<svg class="main">
</svg>
</div>
</body>
<footer>
<script>
d3.csv("hasse_boole.csv",function(error,data) {createNetwork(data)});
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
function createNetwork(data) {
var edges = data;
var nodes = [];
var nodeHash = {};
edges.forEach(function (d) {
if (!nodeHash[d.source]) {
var newNode = {id: d.source}
nodes.push(newNode)
nodeHash[d.source] = newNode;
}
if (!nodeHash[d.target]) {
var newNode = {id: d.target}
nodes.push(newNode)
nodeHash[d.target] = newNode;
}
d.source = nodeHash[d.source];
d.target = nodeHash[d.target];
})
var rootNode = nodes.filter(function (d) {return d.id === "FALSE"})[0]
rootNode.row = 0;
friendlyBFS(rootNode);
//Easy to do because this is a simple DAG
function friendlyBFS(node) {
var targets = edges.filter(function (d) {return d.source === node}).map(function (d) {return d.target});
targets.forEach(function (d) {
d.row = node.row + 1;
friendlyBFS(d)
})
}
var networkCenter = d3.forceCenter().x(250).y(250);
var manyBody = d3.forceManyBody().strength(-1000)
var linkForce = d3.forceLink(edges).id(function (d) {return d.id}).distance(30).iterations(1)
//Generic gravity for the X position
var forceX = d3.forceX(function (d) {return 250})
.strength(0.05)
//strong y positioning based on row
var forceY = d3.forceY(function (d) {return d.row * 50})
.strength(0.5)
var force = d3.forceSimulation(nodes)
.force("charge", manyBody)
.force("link", linkForce)
.force("center", networkCenter)
.force("x", forceX)
.force("y", forceY)
.force("collide", function (d) {return 50})
.on("tick", updateNetwork);
var edgeEnter = d3.select("svg.main").selectAll("g.edge")
.data(edges)
.enter()
.append("g")
.attr("class", "edge");
edgeEnter
.append("line")
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"})
.style("stroke", "black")
.style("pointer-events", "none");
var nodeEnter = d3.select("svg.main").selectAll("g.node")
.data(nodes, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "node")
nodeEnter.append("ellipse")
.attr("rx", 28)
.attr("ry", 14)
.style("fill", "white")
.style("stroke", "black")
.style("stroke-width", function (d) {return d.border ? "3px" : "1px"})
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 3)
.style("stroke-width", "1px")
.style("stroke-opacity", 0.75)
.style("stroke", "white")
.style("font-size", "8px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 3)
.style("font-size", "8px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
function updateNetwork(e) {
d3.select("svg.main").selectAll("line")
.attr("x1", function (d) {return d.source.x})
.attr("y1", function (d) {return d.source.y})
.attr("x2", function (d) {return d.target.x})
.attr("y2", function (d) {return d.target.y});
d3.select("svg.main").selectAll("g.node")
.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"});
}
}
</script>
</footer>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment