Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:16
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 nitaku/e6889f0fa74bf172c897 to your computer and use it in GitHub Desktop.
Save nitaku/e6889f0fa74bf172c897 to your computer and use it in GitHub Desktop.
Gosper Clustering II
svg = d3.select('svg')
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
# translate the viewBox to have (0,0) at the center of the vis
svg
.attr
viewBox: "#{-width/2} #{-height/2} #{width} #{height}"
items = d3.range(686).map (d) -> [
30+Math.random()*200,
30+Math.random()*200,
30+Math.random()*200
]
console.debug 'Computing hierarchical clustering...'
clusters = clusterfck.hcluster(
items,
clusterfck.EUCLIDEAN_DISTANCE,
clusterfck.SINGLE_LINKAGE
)
tree = tree_utils.binary_to_std(clusters)
tree_a = _.cloneDeep tree
tree_b = _.cloneDeep tree
tree_c = _.cloneDeep tree
tree_utils.canonical_sort(tree_b)
tree_utils.recursive_sort(
tree_c,
(a,b) -> d3.hcl(a.key).l - d3.hcl(b.key).l,
(n) ->
if n.children?
n.key = _.min(n.children, (c) -> d3.hcl(c.key).l).key
else
n.key = d3.rgb(n.value[0],n.value[1],n.value[2])
)
leaves_a = tree_utils.get_leaves(tree_a)
leaves_b = tree_utils.get_leaves(tree_b)
leaves_c = tree_utils.get_leaves(tree_c)
console.debug 'Computing the Space-Filling Curve layouts...'
scale = 10
sfc_layout.displace(items, sfc_layout.GOSPER, scale, scale, -2*Math.PI/6)
sfc_layout.displace(leaves_a, sfc_layout.GOSPER, scale, scale, -2*Math.PI/6)
sfc_layout.displace(leaves_b, sfc_layout.GOSPER, scale, scale, -2*Math.PI/6)
sfc_layout.displace(leaves_c, sfc_layout.GOSPER, scale, scale, -2*Math.PI/6)
console.debug 'Drawing...'
original = svg.append('g')
.attr('transform', 'translate(-240,-125)')
result_a = svg.append('g')
.attr('transform', 'translate(240,-125)')
result_b = svg.append('g')
.attr('transform', 'translate(-240,125)')
result_c = svg.append('g')
.attr('transform', 'translate(240,125)')
original.selectAll('.cell')
.data(items)
.enter().append('path')
.attr('class', 'cell')
.attr('d', jigsaw.hex_generate_svg_path(scale))
.attr('transform', (d) -> "translate(#{d.x},#{d.y}) rotate(30)")
.attr('fill', (d) -> d3.rgb(d[0],d[1],d[2]))
result_a.selectAll('.cell')
.data(leaves_a)
.enter().append('path')
.attr('class', 'cell')
.attr('d', jigsaw.hex_generate_svg_path(scale))
.attr('transform', (d) -> "translate(#{d.x},#{d.y}) rotate(30)")
.attr('fill', (d) -> d3.rgb(d.value[0],d.value[1],d.value[2]))
result_b.selectAll('.cell')
.data(leaves_b)
.enter().append('path')
.attr('class', 'cell')
.attr('d', jigsaw.hex_generate_svg_path(scale))
.attr('transform', (d) -> "translate(#{d.x},#{d.y}) rotate(30)")
.attr('fill', (d) -> d3.rgb(d.value[0],d.value[1],d.value[2]))
result_c.selectAll('.cell')
.data(leaves_c)
.enter().append('path')
.attr('class', 'cell')
.attr('d', jigsaw.hex_generate_svg_path(scale))
.attr('transform', (d) -> "translate(#{d.x},#{d.y}) rotate(30)")
.attr('fill', (d) -> d3.rgb(d.value[0],d.value[1],d.value[2]))
svg {
background: white;
}
.cell {
shape-rendering: crispEdges;
}
.label {
fill: #333;
font-family: sans-serif;
text-anchor: middle;
pointer-events: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Gosper Clustering II" />
<title>Gosper Clustering II</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="//wafi.iit.cnr.it/webvis/tmp/clusterfck.js"></script>
<script src="//wafi.iit.cnr.it/webvis/libs/jigmaps/zip.js"></script>
<script src="//wafi.iit.cnr.it/webvis/libs/jigmaps/tree_utils.js"></script>
<script src="//wafi.iit.cnr.it/webvis/libs/jigmaps/sfc_layout.js"></script>
<script src="//wafi.iit.cnr.it/webvis/libs/jigmaps/jigsaw.js"></script>
</head>
<body>
<svg height="500" width="960"></svg>
<script src="index.js"></script>
</body>
</html>
(function() {
var clusters, height, items, leaves_a, leaves_b, leaves_c, original, result_a, result_b, result_c, scale, svg, tree, tree_a, tree_b, tree_c, width;
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
svg.attr({
viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height
});
items = d3.range(686).map(function(d) {
return [30 + Math.random() * 200, 30 + Math.random() * 200, 30 + Math.random() * 200];
});
console.debug('Computing hierarchical clustering...');
clusters = clusterfck.hcluster(items, clusterfck.EUCLIDEAN_DISTANCE, clusterfck.SINGLE_LINKAGE);
tree = tree_utils.binary_to_std(clusters);
tree_a = _.cloneDeep(tree);
tree_b = _.cloneDeep(tree);
tree_c = _.cloneDeep(tree);
tree_utils.canonical_sort(tree_b);
tree_utils.recursive_sort(tree_c, function(a, b) {
return d3.hcl(a.key).l - d3.hcl(b.key).l;
}, function(n) {
if (n.children != null) {
return n.key = _.min(n.children, function(c) {
return d3.hcl(c.key).l;
}).key;
} else {
return n.key = d3.rgb(n.value[0], n.value[1], n.value[2]);
}
});
leaves_a = tree_utils.get_leaves(tree_a);
leaves_b = tree_utils.get_leaves(tree_b);
leaves_c = tree_utils.get_leaves(tree_c);
console.debug('Computing the Space-Filling Curve layouts...');
scale = 10;
sfc_layout.displace(items, sfc_layout.GOSPER, scale, scale, -2 * Math.PI / 6);
sfc_layout.displace(leaves_a, sfc_layout.GOSPER, scale, scale, -2 * Math.PI / 6);
sfc_layout.displace(leaves_b, sfc_layout.GOSPER, scale, scale, -2 * Math.PI / 6);
sfc_layout.displace(leaves_c, sfc_layout.GOSPER, scale, scale, -2 * Math.PI / 6);
console.debug('Drawing...');
original = svg.append('g').attr('transform', 'translate(-240,-125)');
result_a = svg.append('g').attr('transform', 'translate(240,-125)');
result_b = svg.append('g').attr('transform', 'translate(-240,125)');
result_c = svg.append('g').attr('transform', 'translate(240,125)');
original.selectAll('.cell').data(items).enter().append('path').attr('class', 'cell').attr('d', jigsaw.hex_generate_svg_path(scale)).attr('transform', function(d) {
return "translate(" + d.x + "," + d.y + ") rotate(30)";
}).attr('fill', function(d) {
return d3.rgb(d[0], d[1], d[2]);
});
result_a.selectAll('.cell').data(leaves_a).enter().append('path').attr('class', 'cell').attr('d', jigsaw.hex_generate_svg_path(scale)).attr('transform', function(d) {
return "translate(" + d.x + "," + d.y + ") rotate(30)";
}).attr('fill', function(d) {
return d3.rgb(d.value[0], d.value[1], d.value[2]);
});
result_b.selectAll('.cell').data(leaves_b).enter().append('path').attr('class', 'cell').attr('d', jigsaw.hex_generate_svg_path(scale)).attr('transform', function(d) {
return "translate(" + d.x + "," + d.y + ") rotate(30)";
}).attr('fill', function(d) {
return d3.rgb(d.value[0], d.value[1], d.value[2]);
});
result_c.selectAll('.cell').data(leaves_c).enter().append('path').attr('class', 'cell').attr('d', jigsaw.hex_generate_svg_path(scale)).attr('transform', function(d) {
return "translate(" + d.x + "," + d.y + ") rotate(30)";
}).attr('fill', function(d) {
return d3.rgb(d.value[0], d.value[1], d.value[2]);
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment