Skip to content

Instantly share code, notes, and snippets.

@ryanthejuggler
Last active August 29, 2015 13:59
Show Gist options
  • Save ryanthejuggler/10911656 to your computer and use it in GitHub Desktop.
Save ryanthejuggler/10911656 to your computer and use it in GitHub Desktop.
Data clustering
// Number of demo points
var N = 40;
// Merging threshold
var threshold = 0.05;
// Generate a random array of items
var items = _.range(N).map(Math.random);
var width = 600;
var height = 20;
var margin = 20;
var x = d3.scale.linear()
.range([margin, width - margin]);
var $svg = d3.select('#chart').attr('width', width).attr('height', height);
var $layer1 = $svg.append('g');
var $layer2 = $svg.append('g');
var $circle = $layer2.selectAll('circle');
$circle.data(items).enter().append('circle')
.attr('cx', x)
.attr('cy', height * 0.75)
.attr('r', 2);
// Generate the tree form of the clusters
var clusterTrees = clusterfck.hcluster(
items.map(function (n) {
return [n]
}),
clusterfck.MAX_DISTANCE,
clusterfck.COMPLETE_LINKAGE,
threshold);
// Convert the tree into a more digestible format
var clusters = clusterTrees.map(flattenTree).map(function (cluster) {
return cluster.map(function (n) {
return {
min: n[0],
max: n[0],
count: 1
};
}).reduce(function (a, b) {
return {
min: Math.min(a.min, b.min),
max: Math.max(a.max, b.max),
count: a.count + b.count
};
});
});
// Draw the clusters
var $cluster = $layer1.selectAll('rect').data(clusters)
.enter();
$cluster.append('rect')
.attr('x', function (d) {
return x(d.min);
})
.attr('y', 0)
.attr('width', function (d) {
return x(d.max) - x(d.min)
})
.attr('height', height);
$cluster.append('text')
.attr('x', function (d) {
return x((d.min + d.max) / 2);
})
.attr('y', height * 0.5)
.text(function (d) {
return d.count
});
// Utility function for converting a left/right tree
// into an array, recursively
function flattenTree(t) {
if (t.size === 1) {
return [t.value];
}
return _.flatten([flattenTree(t.left), flattenTree(t.right)], true);
}
<html>
<head>
<title>Clustering demo</title>
<script type='text/javascript' src="http://harthur.github.io/clusterfck/demos/colors/clusterfck.js"></script>
<script type='text/javascript' src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script type='text/javascript' src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type='text/javascript' src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.5/d3.min.js"></script>
<style type='text/css'>
circle {
fill: black;
}
rect {
fill: white;
stroke: steelblue;
}
text {
text-anchor: middle;
font: 8px sans-serif;
}
body {
text-align: center;
padding-top: 60px;
}
</style>
</head>
<body>
<svg id="chart"></svg>
<script src="clustering.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment