|
// Generated by CoffeeScript 1.4.0 |
|
(function() { |
|
var DH, PAD, color, correct_x, correct_y, height, iso_layout, isometric, ordering, parallelepipedon, path_generator, svg, treemap, vis, width, zoom, zoomable_layer; |
|
|
|
svg = d3.select('svg'); |
|
|
|
width = svg.node().getBoundingClientRect().width; |
|
|
|
height = svg.node().getBoundingClientRect().height; |
|
|
|
zoomable_layer = svg.append('g'); |
|
|
|
zoom = d3.behavior.zoom().scaleExtent([1, 100]).on('zoom', function() { |
|
return zoomable_layer.attr({ |
|
transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" |
|
}); |
|
}); |
|
|
|
svg.call(zoom); |
|
|
|
vis = zoomable_layer.append('g').attr({ |
|
"class": 'vis', |
|
transform: "translate(" + (width / 2) + "," + (height / 3 - 112) + ")" |
|
}); |
|
|
|
isometric = function(_3d_p) { |
|
return [-Math.sqrt(3) / 2 * _3d_p[0] + Math.sqrt(3) / 2 * _3d_p[1], +0.5 * _3d_p[0] + 0.5 * _3d_p[1] - _3d_p[2]]; |
|
}; |
|
|
|
parallelepipedon = function(d) { |
|
var fb, ft, mlb, mlt, mrb, mrt, nb, nt; |
|
if (!(d.x != null)) { |
|
d.x = 0; |
|
} |
|
if (!(d.y != null)) { |
|
d.y = 0; |
|
} |
|
if (!(d.h != null)) { |
|
d.h = 0; |
|
} |
|
if (!(d.dx != null)) { |
|
d.dx = 10; |
|
} |
|
if (!(d.dy != null)) { |
|
d.dy = 10; |
|
} |
|
if (!(d.dh != null)) { |
|
d.dh = 10; |
|
} |
|
fb = isometric([d.x, d.y, d.h], mlb = isometric([d.x + d.dx, d.y, d.h], nb = isometric([d.x + d.dx, d.y + d.dy, d.h], mrb = isometric([d.x, d.y + d.dy, d.h], ft = isometric([d.x, d.y, d.h + d.dh], mlt = isometric([d.x + d.dx, d.y, d.h + d.dh], nt = isometric([d.x + d.dx, d.y + d.dy, d.h + d.dh], mrt = isometric([d.x, d.y + d.dy, d.h + d.dh])))))))); |
|
d.iso = { |
|
face_bottom: [fb, mrb, nb, mlb], |
|
face_left: [mlb, mlt, nt, nb], |
|
face_right: [nt, mrt, mrb, nb], |
|
face_top: [ft, mrt, nt, mlt], |
|
outline: [ft, mrt, mrb, nb, mlb, mlt], |
|
fb: fb, |
|
mlb: mlb, |
|
nb: nb, |
|
mrb: mrb, |
|
ft: ft, |
|
mlt: mlt, |
|
nt: nt, |
|
mrt: mrt |
|
}; |
|
return d; |
|
}; |
|
|
|
ordering = function(a, b) { |
|
return b.i - a.i; |
|
}; |
|
|
|
iso_layout = function(data, shape, scale) { |
|
if (!(scale != null)) { |
|
scale = 1; |
|
} |
|
data.forEach(function(d) { |
|
return shape(d, scale); |
|
}); |
|
return data.sort(ordering); |
|
}; |
|
|
|
path_generator = function(d) { |
|
return 'M' + d.map(function(p) { |
|
return p.join(' '); |
|
}).join('L') + 'z'; |
|
}; |
|
|
|
DH = 5; |
|
|
|
PAD = 4; |
|
|
|
treemap = d3.layout.treemap().size([400, 400]).value(function(d) { |
|
return d.size; |
|
}).sort(function(a, b) { |
|
return ordering(b, a); |
|
}).padding(PAD).round(false); |
|
|
|
color = d3.scale.category20c(); |
|
|
|
correct_x = d3.scale.linear().domain([0, width]).range([0, width * 1.05]); |
|
|
|
correct_y = d3.scale.linear().domain([0, height]).range([0, height * 3 / 4]); |
|
|
|
d3.json('flare.json', function(tree) { |
|
var data, enter_labels, enter_labels_g, enter_pipedons, i, pipedons, walk, walk_i; |
|
walk = function(n, depth) { |
|
var child, _i, _len, _ref; |
|
n.depth = depth; |
|
n.dh = DH; |
|
n.h = DH * depth; |
|
if (n.children != null) { |
|
_ref = n.children; |
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|
child = _ref[_i]; |
|
walk(child, depth + 1); |
|
} |
|
n.children.sort(function(a, b) { |
|
return a.size - b.size; |
|
}); |
|
return n.size = d3.sum(n.children, function(d) { |
|
return d.size; |
|
}); |
|
} |
|
}; |
|
walk(tree, 0); |
|
i = 0; |
|
walk_i = function(n) { |
|
var child, _i, _len, _ref; |
|
if (n.children != null) { |
|
_ref = n.children; |
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|
child = _ref[_i]; |
|
walk_i(child); |
|
} |
|
} |
|
n.i = i; |
|
return i += 1; |
|
}; |
|
walk_i(tree); |
|
data = treemap.nodes(tree); |
|
iso_layout(data, parallelepipedon); |
|
data.forEach(function(d, i) { |
|
return d.template_color = d3.hcl(color(d.i)); |
|
}); |
|
pipedons = vis.selectAll('.pipedon').data(data); |
|
enter_pipedons = pipedons.enter().append('g').attr({ |
|
"class": 'pipedon' |
|
}); |
|
enter_pipedons.append('path').attr({ |
|
"class": 'iso face bottom', |
|
d: function(d) { |
|
return path_generator(d.iso.face_bottom); |
|
} |
|
}); |
|
enter_pipedons.append('path').attr({ |
|
"class": 'iso face left', |
|
d: function(d) { |
|
return path_generator(d.iso.face_left); |
|
}, |
|
fill: function(d) { |
|
return d.template_color; |
|
} |
|
}); |
|
enter_pipedons.append('path').attr({ |
|
"class": 'iso face right', |
|
d: function(d) { |
|
return path_generator(d.iso.face_right); |
|
}, |
|
fill: function(d) { |
|
return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l - 12); |
|
} |
|
}); |
|
enter_pipedons.append('path').attr({ |
|
"class": 'iso face top', |
|
d: function(d) { |
|
return path_generator(d.iso.face_top); |
|
}, |
|
fill: function(d) { |
|
return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l + 12); |
|
} |
|
}); |
|
enter_labels_g = enter_pipedons.append('g').classed('hidden', function(d) { |
|
return d.children != null; |
|
}); |
|
enter_labels = enter_labels_g.append('svg').attr({ |
|
"class": 'label' |
|
}); |
|
enter_labels.append('text').text(function(d) { |
|
return d.name.toUpperCase(); |
|
}).attr({ |
|
dy: '.35em' |
|
}).each(function(node) { |
|
var bbox, bbox_aspect, node_bbox, node_bbox_aspect, rotate; |
|
bbox = this.getBBox(); |
|
bbox_aspect = bbox.width / bbox.height; |
|
node_bbox = { |
|
width: node.dx, |
|
height: node.dy |
|
}; |
|
node_bbox_aspect = node_bbox.width / node_bbox.height; |
|
rotate = bbox_aspect >= 1 && node_bbox_aspect < 1 || bbox_aspect < 1 && node_bbox_aspect >= 1; |
|
node.label_bbox = { |
|
x: bbox.x + (bbox.width - correct_x(bbox.width)) / 2, |
|
y: bbox.y + (bbox.height - correct_y(bbox.height)) / 2, |
|
width: correct_x(bbox.width), |
|
height: correct_y(bbox.height) |
|
}; |
|
if (rotate) { |
|
node.label_bbox = { |
|
x: node.label_bbox.y, |
|
y: node.label_bbox.x, |
|
width: node.label_bbox.height, |
|
height: node.label_bbox.width |
|
}; |
|
return d3.select(this).attr('transform', 'rotate(90) translate(0,1)'); |
|
} |
|
}); |
|
enter_labels.each(function(d) { |
|
d.iso_x = isometric([d.x + d.dx / 2, d.y + d.dy / 2, d.h + d.dh])[0] - d.dx / 2; |
|
return d.iso_y = isometric([d.x + d.dx / 2, d.y + d.dy / 2, d.h + d.dh])[1] - d.dy / 2; |
|
}); |
|
enter_labels.attr({ |
|
x: function(d) { |
|
return d.iso_x; |
|
}, |
|
y: function(d) { |
|
return d.iso_y; |
|
}, |
|
width: function(node) { |
|
return node.dx; |
|
}, |
|
height: function(node) { |
|
return node.dy; |
|
}, |
|
viewBox: function(node) { |
|
return "" + node.label_bbox.x + " " + node.label_bbox.y + " " + node.label_bbox.width + " " + node.label_bbox.height; |
|
}, |
|
preserveAspectRatio: 'none', |
|
fill: function(d) { |
|
return d3.hcl(d.template_color.h, d.template_color.c, d.template_color.l - 12); |
|
} |
|
}); |
|
enter_labels_g.attr({ |
|
transform: function(d) { |
|
return "translate(" + (d.iso_x + d.dx / 2) + "," + (d.iso_y + d.dy / 2) + ") scale(1, " + (1 / Math.sqrt(3)) + ") rotate(-45) translate(" + (-(d.iso_x + d.dx / 2)) + "," + (-(d.iso_y + d.dy / 2)) + ")"; |
|
} |
|
}); |
|
enter_pipedons.append('path').attr({ |
|
"class": 'iso outline', |
|
d: function(d) { |
|
return path_generator(d.iso.outline); |
|
} |
|
}); |
|
return enter_pipedons.append('title').text(function(d) { |
|
return d.name; |
|
}); |
|
}); |
|
|
|
}).call(this); |