(function() { var cluster_layout, clusters, height, items, links_a, links_b, links_c, nodes_a, nodes_b, nodes_c, original, result_a, result_b, result_c, 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(40).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]); } }); cluster_layout = d3.layout.cluster().size([440, 200]).separation(function(d) { return 1; }); nodes_a = cluster_layout.nodes(tree_a); links_a = cluster_layout.links(nodes_a); nodes_b = cluster_layout.nodes(tree_b); links_b = cluster_layout.links(nodes_b); nodes_c = cluster_layout.nodes(tree_c); links_c = cluster_layout.links(nodes_c); console.debug('Drawing...'); original = svg.append('g').attr('transform', 'translate(-450,-230)'); result_a = svg.append('g').attr('transform', 'translate(10,-230)'); result_b = svg.append('g').attr('transform', 'translate(-450,10)'); result_c = svg.append('g').attr('transform', 'translate(10,10)'); original.selectAll('.node').data(items).enter().append('rect').attr('class', 'node').attr('x', -4).attr('y', -5).attr('width', 8).attr('height', 24).attr('transform', function(d, i) { return "translate(" + (6 + i * 11) + ",200)"; }).attr('fill', function(d) { return d3.rgb(d[0], d[1], d[2]); }); result_a.selectAll('.link').data(links_a).enter().append('path').attr('class', 'link').attr('d', function(l) { return "M" + l.source.x + " " + l.source.y + " L" + l.target.x + " " + l.source.y + " L" + l.target.x + " " + l.target.y; }); result_a.selectAll('.node').data(nodes_a.filter(function(n) { return n.children == null; })).enter().append('rect').attr('class', 'node').attr('x', -4).attr('y', -5).attr('width', 8).attr('height', 24).attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }).attr('fill', function(d) { return d3.rgb(d.value[0], d.value[1], d.value[2]); }); result_b.selectAll('.link').data(links_b).enter().append('path').attr('class', 'link').attr('d', function(l) { return "M" + l.source.x + " " + l.source.y + " L" + l.target.x + " " + l.source.y + " L" + l.target.x + " " + l.target.y; }); result_b.selectAll('.node').data(nodes_b.filter(function(n) { return n.children == null; })).enter().append('rect').attr('class', 'node').attr('x', -4).attr('y', -5).attr('width', 8).attr('height', 24).attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }).attr('fill', function(d) { return d3.rgb(d.value[0], d.value[1], d.value[2]); }); result_c.selectAll('.link').data(links_c).enter().append('path').attr('class', 'link').attr('d', function(l) { return "M" + l.source.x + " " + l.source.y + " L" + l.target.x + " " + l.source.y + " L" + l.target.x + " " + l.target.y; }); result_c.selectAll('.node').data(nodes_c.filter(function(n) { return n.children == null; })).enter().append('rect').attr('class', 'node').attr('x', -4).attr('y', -5).attr('width', 8).attr('height', 24).attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }).attr('fill', function(d) { return d3.rgb(d.value[0], d.value[1], d.value[2]); }); result_c.selectAll('.internal_node').data(nodes_c.filter(function(n) { return n.children != null; })).enter().append('circle').attr('class', 'internal_node').attr('r', 4).attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }).attr('fill', function(d) { return d.key; }); }).call(this);