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.
// 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);
<!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>
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')
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;
}