Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/2d502924bad6152acbe5 to your computer and use it in GitHub Desktop.
Save nitaku/2d502924bad6152acbe5 to your computer and use it in GitHub Desktop.
Basic treemap (flare)

A reference example for implementing treemaps in D3.js, showing the flare software package hierarchy.

This example is intentionally basic, and it lacks many important features such as labels or interaction.

# layout, behaviors and scales
SCALE = 400
PADDING = 8
TIP = 10
treemap = d3.layout.treemap()
.size([SCALE, SCALE])
.value((node) -> node.size)
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}"
# 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)
# group the visualization
vis = zoomable_layer.append('g')
.attr
transform: "translate(#{-SCALE/2},#{-SCALE/2})"
d3.json 'http://wafi.iit.cnr.it/webvis/tmp/flare.json', (tree) ->
nodes_data = treemap.nodes(tree)
nodes = vis.selectAll('.node')
.data(nodes_data)
enter_nodes = nodes.enter().insert('rect','rect')
.attr
class: 'node'
x: (node) -> node.x
y: (node) -> node.y
width: (node) -> node.dx
height: (node) -> node.dy
stroke: (node) ->
switch node.depth
when 0 then '#333'
when 1 then '#999'
else '#DDD'
'stroke-width': (node) ->
switch node.depth
when 0 then 3
when 1 then 2
else 1
enter_nodes.append('title')
.text((node) -> node.name)
svg {
background: white;
}
.node {
shape-rendering: crispEdges;
vector-effect: non-scaling-stroke;
fill: none;
}
.label {
text-anchor: middle;
font-family: sans-serif;
/*text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;*/
text-shadow: -2px 0 white, 0 2px white, 2px 0 white, 0 -2px white, -1px -1px white, 1px -1px white, 1px 1px white, -1px 1px white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Basic treemap (flare)" />
<title>Basic treemap (flare)</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<svg height="500" width="960"></svg>
<script src="index.js"></script>
</body>
</html>
(function() {
var PADDING, SCALE, TIP, height, svg, treemap, vis, width, zoom, zoomable_layer;
SCALE = 400;
PADDING = 8;
TIP = 10;
treemap = d3.layout.treemap().size([SCALE, SCALE]).value(function(node) {
return node.size;
});
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([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 enter_nodes, nodes, nodes_data;
nodes_data = treemap.nodes(tree);
nodes = vis.selectAll('.node').data(nodes_data);
enter_nodes = nodes.enter().insert('rect', '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;
},
stroke: function(node) {
switch (node.depth) {
case 0:
return '#333';
case 1:
return '#999';
default:
return '#DDD';
}
},
'stroke-width': function(node) {
switch (node.depth) {
case 0:
return 3;
case 1:
return 2;
default:
return 1;
}
}
});
return enter_nodes.append('title').text(function(node) {
return node.name;
});
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment