block by nitaku aebaa163cbb99cd98fcd

Duck Similarity (Pink Floyd)

Full Screen

A more orthodox approach to show the same data of the previous experiment. Clusters are more clear: works (the huge square at top left) are distinct from people (bottom right), movies (bottom right inside the huge square) from songs and albums, which oddly form one cluster for albums and two different ones for songs.

index.js

// Generated by CoffeeScript 1.4.0
(function() {
  var SIZE, height, matrix, simcolor, svg, width, zoom, zoomable_layer;

  svg = d3.select('svg');

  width = svg.node().getBoundingClientRect().width;

  height = svg.node().getBoundingClientRect().height;

  simcolor = d3.scale.linear().domain([0, 1]).range([d3.hcl(80, 0, 100), d3.hcl(80, 75, 25)]).interpolate(d3.interpolateHcl);

  zoomable_layer = svg.append('g');

  zoom = d3.behavior.zoom().scaleExtent([1, 10]).on('zoom', function() {
    return zoomable_layer.attr({
      transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"
    });
  });

  svg.call(zoom);

  matrix = zoomable_layer.append('g').attr('transform', 'translate(230,12)');

  SIZE = 1.9;

  d3.json('//wafi.iit.cnr.it/webvis/tmp/dbpedia/pink_floyd_matrix.json', function(data) {
    var cells, clusters, enter_rows, index, items, matrix_data, rows, sequence, tree;
    index = {};
    items = [];
    data.forEach(function(e1) {
      items.push(e1.k1);
      index[e1.k1] = {};
      return e1.similarities.forEach(function(e2) {
        return index[e1.k1][e2.k2] = e2.sim;
      });
    });
    console.debug('Computing hierarchical clustering...');
    clusters = clusterfck.hcluster(items, function(a, b) {
      return 1 - index[a][b];
    }, clusterfck.SINGLE_LINKAGE);
    tree = tree_utils.binary_to_std(clusters);
    sequence = tree_utils.get_leaves(tree).map(function(d) {
      return d.value;
    });
    matrix_data = [];
    sequence.forEach(function(k1) {
      var e1;
      e1 = {
        k1: k1,
        similarities: []
      };
      matrix_data.push(e1);
      return sequence.forEach(function(k2) {
        return e1.similarities.push({
          k2: k2,
          sim: index[k1][k2]
        });
      });
    });
    rows = matrix.selectAll('.row').data(matrix_data);
    enter_rows = rows.enter().append('g').attr('class', 'row').attr('transform', function(d, i) {
      return "translate(0," + (SIZE * i) + ")";
    });
    cells = rows.selectAll('.cell').data(function(row) {
      return row.similarities;
    });
    cells.enter().append('rect').attr('class', 'cell').attr('width', SIZE).attr('height', SIZE).attr('transform', function(d, i) {
      return "translate(" + (SIZE * i) + ",0)";
    }).attr('fill', function(d) {
      return simcolor(d.sim);
    }).append('title').text(function(d) {
      var k1, k2;
      k1 = d3.select(this.parentNode.parentNode).datum().k1.replace('http://dbpedia.org/resource/', '');
      k2 = d.k2.replace('http://dbpedia.org/resource/', '');
      return "" + k1 + "\n           [" + (d3.format('%')(d.sim)) + "]\n" + k2;
    });
    return matrix.append('rect').attr('class', 'border').attr('x', -1).attr('y', -1).attr('width', SIZE * matrix_data.length + 2).attr('height', SIZE * matrix_data.length + 2);
  });

}).call(this);

index.html

<!DOCTYPE html>
<html>
  <head>
	<meta charset="utf-8">
	<meta name="description" content="Duck Similarity (Pink Floyd)" />
	<title>Duck Similarity (Pink Floyd)</title>
	<link type="text/css" href="index.css" rel="stylesheet"/>
	<script src="//d3js.org/d3.v3.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>
  </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

simcolor = d3.scale.linear()
  .domain([0,1])
  .range([d3.hcl(80,0,100),d3.hcl(80,75,25)])
  .interpolate(d3.interpolateHcl)
  
  
# append a group for zoomable content
zoomable_layer = svg.append('g')
 
# define a zoom behavior
zoom = d3.behavior.zoom()
  .scaleExtent([1,10]) # min-max zoom
  .on 'zoom', () ->
    # GEOMETRIC ZOOM
    zoomable_layer
      .attr
        transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})"

# bind the zoom behavior to the main SVG
svg.call(zoom)


matrix = zoomable_layer.append('g')
  .attr('transform', 'translate(230,12)')

SIZE = 1.9

d3.json '//wafi.iit.cnr.it/webvis/tmp/dbpedia/pink_floyd_matrix.json', (data) ->
  index = {}
  items = []
  data.forEach (e1) ->
    items.push e1.k1
    index[e1.k1] = {}
    e1.similarities.forEach (e2) ->
      index[e1.k1][e2.k2] = e2.sim
  
  console.debug 'Computing hierarchical clustering...'
  clusters = clusterfck.hcluster(
    items,
    (a,b) -> 1-index[a][b],
    clusterfck.SINGLE_LINKAGE
  )
  tree = tree_utils.binary_to_std(clusters)
  sequence = tree_utils.get_leaves(tree).map (d) -> d.value
  
  matrix_data = []
  sequence.forEach (k1) ->
    e1 = {k1: k1, similarities: []}
    matrix_data.push e1
    sequence.forEach (k2) ->
      e1.similarities.push {k2: k2, sim: index[k1][k2]}
      
  rows = matrix.selectAll('.row')
    .data(matrix_data)
  
  enter_rows = rows.enter().append('g')
    .attr('class', 'row')
    .attr('transform', (d,i) -> "translate(0,#{SIZE*i})")
    
  cells = rows.selectAll('.cell')
    .data((row) -> row.similarities)
    
  cells.enter().append('rect')
    .attr('class', 'cell')
    .attr('width', SIZE)
    .attr('height', SIZE)
    .attr('transform', (d, i) -> "translate(#{SIZE*i},0)")
    .attr('fill', (d) -> simcolor(d.sim))
  .append('title')
    .text((d) ->
      k1 = d3.select(this.parentNode.parentNode).datum().k1.replace('http://dbpedia.org/resource/','')
      k2 = d.k2.replace('http://dbpedia.org/resource/','')
      return "#{k1}\n           [#{d3.format('%')(d.sim)}]\n#{k2}"
    )
    
  matrix.append('rect')
    .attr('class','border')
    .attr('x', -1)
    .attr('y', -1)
    .attr('width', SIZE*matrix_data.length+2)
    .attr('height', SIZE*matrix_data.length+2)
    
  #hlabels = matrix.selectAll('.hlabel')
  #  .data(matrix_data)
  #  
  #hlabels.enter().append('a')
  #    .attr('xlink:href', (d) -> d.k1)
  #  .append('text')
  #    .attr('class','hlabel')
  #    .text((d) -> d.k1.replace('http://dbpedia.org/resource/',''))
  #    .attr('transform', (d,i) -> "translate(0,#{SIZE*i})")
  #    .attr('dy', '1em')
  #    .attr('dx', -6)
  #    .classed('highlighted', (d) -> d.k1 is 'http://dbpedia.org/resource/Pink_Floyd')
  #  
  #vlabels = matrix.selectAll('.vlabel')
  #  .data(matrix_data)
  #  
  #vlabels.enter().append('a')
  #    .attr('xlink:href', (d) -> d.k1)
  #  .append('text')
  #    .attr('class','vlabel')
  #    .text((d) -> d.k1.replace('http://dbpedia.org/resource/',''))
  #    .attr('transform', (d,i) -> "translate(#{SIZE*i},0) rotate(-90)")
  #    .attr('dy', '1em')
  #    .attr('dx', 6)
  #    .classed('highlighted', (d) -> d.k1 is 'http://dbpedia.org/resource/Pink_Floyd')
    

index.css

svg {
  background: white;
}
.border {
  stroke-width: 1;
  stroke: #CCC;
  fill: none;
  shape-rendering: crispEdges;
}
.cell {
  shape-rendering: crispEdges;
}
.hlabel, .vlabel {
  fill: #333;
  font-family: sans-serif;
  font-size: 10px;
}
.hlabel {
  text-anchor: end;
}
.vlabel {
  text-anchor: start;
}
.highlighted {
  font-weight: bold;
  fill: black;
}
.hlabel:hover, .vlabel:hover {
  fill: red;
}