|
(function() { |
|
var PADDING, SCALE, drag, height, redraw, subtrees_data, svg, treemap, vis, width, zoom, zoomable_layer; |
|
|
|
subtrees_data = []; |
|
|
|
SCALE = 200; |
|
|
|
PADDING = 8; |
|
|
|
treemap = d3.layout.treemap().size([SCALE, SCALE]).value(function(node) { |
|
return node.size; |
|
}); |
|
|
|
drag = d3.behavior.drag().origin(function(d) { |
|
return d; |
|
}); |
|
|
|
drag.on('dragstart', function() { |
|
return d3.event.sourceEvent.stopPropagation(); |
|
}); |
|
|
|
drag.on('drag', function(d) { |
|
d.x = d3.event.x; |
|
d.y = d3.event.y; |
|
return redraw(); |
|
}); |
|
|
|
svg = d3.select('svg'); |
|
|
|
width = svg.node().getBoundingClientRect().width; |
|
|
|
height = svg.node().getBoundingClientRect().height; |
|
|
|
svg.attr({ |
|
viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height |
|
}); |
|
|
|
zoomable_layer = svg.append('g'); |
|
|
|
zoom = d3.behavior.zoom().scaleExtent([0.1, 10]).on('zoom', function() { |
|
return zoomable_layer.attr({ |
|
transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" |
|
}); |
|
}); |
|
|
|
svg.call(zoom); |
|
|
|
vis = zoomable_layer.append('g').attr({ |
|
transform: "translate(" + (-SCALE / 2) + "," + (-SCALE / 2) + ")" |
|
}); |
|
|
|
d3.json('http://wafi.iit.cnr.it/webvis/tmp/flare.json', function(tree) { |
|
var subtree_data; |
|
|
|
treemap.nodes(tree); |
|
subtree_data = { |
|
tree: tree, |
|
x: 0, |
|
y: 0 |
|
}; |
|
tree.subtree = subtree_data; |
|
subtrees_data.push(subtree_data); |
|
return redraw(); |
|
}); |
|
|
|
redraw = function(duration) { |
|
var enter_nodes, enter_subtrees, links, nodes, subtrees; |
|
|
|
duration = duration != null ? duration : 0; |
|
links = vis.selectAll('.link').data(subtrees_data.filter(function(subtree_data) { |
|
return subtree_data.tree.depth !== 0; |
|
})); |
|
links.enter().append('path').attr({ |
|
"class": 'link' |
|
}); |
|
links.transition().duration(duration).attr({ |
|
d: function(subtree_data) { |
|
var parent; |
|
|
|
parent = subtree_data.tree.parent.subtree; |
|
return "M" + (parent.x + subtree_data.tree.x + subtree_data.tree.dx / 2) + " " + (parent.y + subtree_data.tree.y + subtree_data.tree.dy / 2) + " L" + (subtree_data.x + subtree_data.tree.x + subtree_data.tree.dx / 2) + " " + (subtree_data.y + subtree_data.tree.y + subtree_data.tree.dy / 2); |
|
} |
|
}); |
|
subtrees = vis.selectAll('.subtree').data(subtrees_data); |
|
enter_subtrees = subtrees.enter().append('g').call(drag).attr({ |
|
"class": 'subtree' |
|
}); |
|
enter_subtrees.append('rect').attr({ |
|
"class": 'handle', |
|
x: function(subtree_data) { |
|
return subtree_data.tree.x - PADDING; |
|
}, |
|
y: function(subtree_data) { |
|
return subtree_data.tree.y - PADDING; |
|
}, |
|
width: function(subtree_data) { |
|
return subtree_data.tree.dx + 2 * PADDING; |
|
}, |
|
height: function(subtree_data) { |
|
return subtree_data.tree.dy + 2 * PADDING; |
|
} |
|
}); |
|
enter_subtrees.append('text').text(function(subtree_data) { |
|
return subtree_data.tree.name; |
|
}).attr({ |
|
"class": 'label', |
|
x: function(subtree_data) { |
|
return subtree_data.tree.x + subtree_data.tree.dx / 2; |
|
}, |
|
y: function(subtree_data) { |
|
return subtree_data.tree.y; |
|
}, |
|
dy: '-1em' |
|
}); |
|
subtrees.transition().duration(duration).attr({ |
|
transform: function(subtree_data) { |
|
return "translate(" + subtree_data.x + "," + subtree_data.y + ")"; |
|
} |
|
}); |
|
nodes = subtrees.selectAll('.node').data(function(subtree_data) { |
|
if (subtree_data.tree.children != null) { |
|
return subtree_data.tree.children; |
|
} else { |
|
return []; |
|
} |
|
}); |
|
enter_nodes = nodes.enter().append('rect').attr({ |
|
"class": 'node', |
|
x: function(node) { |
|
return node.x; |
|
}, |
|
y: function(node) { |
|
return node.y; |
|
}, |
|
width: function(node) { |
|
return node.dx; |
|
}, |
|
height: function(node) { |
|
return node.dy; |
|
}, |
|
fill: 'transparent' |
|
}); |
|
enter_nodes.on('click', function(node) { |
|
var subtree_data, x, y; |
|
|
|
if (node.exploded === true) { |
|
return; |
|
} |
|
node.exploded = true; |
|
x = d3.select(this.parentNode).datum().x; |
|
y = d3.select(this.parentNode).datum().y; |
|
subtree_data = { |
|
tree: node, |
|
x: x, |
|
y: y |
|
}; |
|
node.subtree = subtree_data; |
|
subtrees_data.push(subtree_data); |
|
redraw(); |
|
subtree_data.x += 30; |
|
subtree_data.y += 30; |
|
return window.requestAnimationFrame(function() { |
|
return redraw(1000); |
|
}); |
|
}); |
|
enter_nodes.append('title').text(function(node) { |
|
return node.name; |
|
}); |
|
return nodes.classed('exploded', function(node) { |
|
return node.exploded; |
|
}); |
|
}; |
|
|
|
}).call(this); |