Skip to content

Instantly share code, notes, and snippets.

@AndrewJakubowicz
Last active May 13, 2017 05:55
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 AndrewJakubowicz/7d8ccde194ee68750b496ef70af4506b to your computer and use it in GitHub Desktop.
Save AndrewJakubowicz/7d8ccde194ee68750b496ef70af4506b to your computer and use it in GitHub Desktop.
Dynamic Group Changing using WebCola and D3
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dynamic Groups Example</title>
<script src="https://unpkg.com/webcola@3.3.4/WebCola/cola.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<!--Author: Andrew Jakubowicz-->
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
cursor: move;
}
.group {
stroke: #fff;
stroke-width: 1.5px;
cursor: move;
opacity: 0.7;
}
.link {
stroke: #7a4e4e;
stroke-width: 3px;
stroke-opacity: 1;
}
.label {
fill: white;
font-family: Verdana;
font-size: 25px;
text-anchor: middle;
cursor: move;
}
</style>
</head>
<body>
<script>
var graph = {
nodes: [
{name: "a", width: 60, height: 40},
{name: "b", width: 60, height: 40},
{name: "c", width: 60, height: 40},
{name: "d", width: 60, height: 40}],
links: [
{source: 0, target: 1},
{source: 0, target: 2},
{source: 0, target: 3}
],
groups: []
}
var width = 960,
height = 500;
var color = d3.scaleOrdinal(d3.schemeCategory10);
var simulation = cola.d3adaptor(d3)
.linkDistance(100)
.avoidOverlaps(true)
.handleDisconnected(false)
.size([width, height])
.nodes(graph.nodes)
.links(graph.links)
.groups([])
.start();
// Hacky way of showing groups changing
var s = false;
setInterval(() => {
// With simulation.stop() there is strange freezing while the layout settles.
// simulation.stop();
if (s){
graph.groups = [{leaves: [0, 1]}]
} else {
graph.groups = [{leaves:[0, 3]}]
}
restart()
s = !s;
}, 500);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
function restart(){
var group = svg.selectAll(".group")
.data(graph.groups);
var grpEnter = group.enter().insert("rect", 'rect')
.attr("rx", 8).attr("ry", 8)
.attr("class", "group")
.style("fill", function (d, i) { return color(i); })
group = group.merge(grpEnter)
group.call(simulation.drag);
var link = svg.selectAll(".link")
.data(graph.links)
var lnkEnter = link.enter().append("line")
.attr("class", "link")
.attr("stroke-width", 2)
.attr("stroke", "black");
link = link.merge(lnkEnter);
var pad = 3;
var node = svg.selectAll(".node")
.data(graph.nodes);
var nodeEnter = node.enter().append("rect")
.attr("class", "node")
.attr("width", function (d) { return d.width - 2 * pad; })
.attr("height", function (d) { return d.height - 2 * pad; })
.attr("rx", 5).attr("ry", 5)
.style("fill", function (d) { return color(graph.groups.length); })
node = node.merge(nodeEnter);
node.call(simulation.drag);
var label = svg.selectAll(".label")
.data(graph.nodes)
var labelEnter = label.enter().append("text")
.attr("class", "label")
.text(function (d) { return d.name; })
label = label.merge(labelEnter)
label.call(simulation.drag);
node.append("title")
.text(function (d) { return d.name; });
// Because groups are dynamic we need to restart them here.
simulation
.groups(graph.groups)
.start().on("tick", function () {
link.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; });
node.attr("x", function (d) { return d.x - d.width / 2 + pad; })
.attr("y", function (d) { return d.y - d.height / 2 + pad; });
group.attr("x", function (d) { return d.bounds.x; })
.attr("y", function (d) { return d.bounds.y; })
.attr("width", function (d) { return d.bounds.width(); })
.attr("height", function (d) { return d.bounds.height(); });
label.attr("x", function (d) { return d.x; })
.attr("y", function (d) {
var h = this.getBBox().height;
return d.y + h/4;
});
});
};
restart();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment