block by nitaku e6889f0fa74bf172c897

Gosper Clustering II

Full Screen

index.js

(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);

index.html

<!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="//d3js.org/d3.v3.min.js"></script>
        <script src="//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>

index.coffee

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]))
    

index.css

svg {
  background: white;
}

.cell {
  shape-rendering: crispEdges;
}
.label {
  fill: #333;
  font-family: sans-serif;
  text-anchor: middle;
  pointer-events: none;
}