author | nowmad@23.1.168.192.in-addr.arpa |
Fri, 22 Jan 2016 11:14:11 +0100 | |
changeset 96 | 719390899adf |
parent 95 | f7ab931581af |
child 123 | 4c97e9da1416 |
permissions | -rw-r--r-- |
39
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
1 |
import Ember from 'ember'; |
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
2 |
|
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
3 |
export default Ember.Component.extend({ |
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
4 |
didInsertElement: function(){ |
51
70dff07a76ff
add click event on visu-carto and visu-langue and update the url with the selected element as filter parameter
nowmad@nowmads-macbook-pro.local
parents:
45
diff
changeset
|
5 |
var _this = this; |
84 | 6 |
var margin = {top: 20, right: 0, bottom: 0, left: 0}, |
95 | 7 |
width = Ember.$("#chart_div").width(), |
84 | 8 |
height = 600 - margin.top - margin.bottom, |
9 |
formatNumber = d3.format(",d"), |
|
10 |
transitioning; |
|
11 |
||
12 |
var x = d3.scale.linear() |
|
13 |
.domain([0, width]) |
|
14 |
.range([0, width]); |
|
15 |
||
16 |
var y = d3.scale.linear() |
|
17 |
.domain([0, height]) |
|
18 |
.range([0, height]); |
|
19 |
||
20 |
var treemap = d3.layout.treemap() |
|
21 |
.children(function(d, depth) { return depth ? null : d._children; }) |
|
22 |
.sort(function(a, b) { return a.value - b.value; }) |
|
23 |
.ratio(height / width * 0.5 * (1 + Math.sqrt(5))) |
|
24 |
.round(false); |
|
25 |
||
26 |
var svg = d3.select("#chart_div").append("svg") |
|
27 |
.attr("width", width + margin.left + margin.right) |
|
28 |
.attr("height", height + margin.bottom + margin.top) |
|
29 |
.style("margin-left", -margin.left + "px") |
|
30 |
.style("margin.right", -margin.right + "px") |
|
31 |
.append("g") |
|
32 |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") |
|
33 |
.style("shape-rendering", "crispEdges"); |
|
34 |
||
35 |
var grandparent = svg.append("g") |
|
36 |
.attr("class", "grandparent"); |
|
37 |
||
38 |
grandparent.append("rect") |
|
39 |
.attr("y", -margin.top) |
|
40 |
.attr("width", width) |
|
41 |
.attr("height", margin.top); |
|
42 |
||
43 |
grandparent.append("text") |
|
44 |
.attr("x", 6) |
|
45 |
.attr("y", 6 - margin.top) |
|
46 |
.attr("dy", ".75em"); |
|
47 |
||
48 |
d3.json("langues.json", function(root) { |
|
49 |
initialize(root); |
|
50 |
accumulate(root); |
|
51 |
layout(root); |
|
52 |
display(root); |
|
53 |
||
54 |
function initialize(root) { |
|
55 |
root.x = root.y = 0; |
|
56 |
root.dx = width; |
|
57 |
root.dy = height; |
|
58 |
root.depth = 0; |
|
59 |
} |
|
60 |
||
61 |
// Aggregate the values for internal nodes. This is normally done by the |
|
62 |
// treemap layout, but not here because of our custom implementation. |
|
63 |
// We also take a snapshot of the original children (_children) to avoid |
|
64 |
// the children being overwritten when when layout is computed. |
|
65 |
function accumulate(d) { |
|
92 | 66 |
return (d._children = d.children) ? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 0) : d.value; |
84 | 67 |
} |
68 |
||
69 |
// Compute the treemap layout recursively such that each group of siblings |
|
70 |
// uses the same size (1×1) rather than the dimensions of the parent cell. |
|
71 |
// This optimizes the layout for the current zoom state. Note that a wrapper |
|
72 |
// object is created for the parent node for each group of siblings so that |
|
73 |
// the parent’s dimensions are not discarded as we recurse. Since each group |
|
74 |
// of sibling was laid out in 1×1, we must rescale to fit using absolute |
|
75 |
// coordinates. This lets us use a viewport to zoom. |
|
76 |
function layout(d) { |
|
77 |
if (d._children) { |
|
78 |
treemap.nodes({_children: d._children}); |
|
79 |
d._children.forEach(function(c) { |
|
80 |
c.x = d.x + c.x * d.dx; |
|
81 |
c.y = d.y + c.y * d.dy; |
|
82 |
c.dx *= d.dx; |
|
83 |
c.dy *= d.dy; |
|
84 |
c.parent = d; |
|
85 |
layout(c); |
|
86 |
}); |
|
87 |
} |
|
88 |
} |
|
89 |
||
90 |
function display(d) { |
|
91 |
grandparent |
|
92 |
.datum(d.parent) |
|
93 |
.on("click", transition) |
|
94 |
.select("text") |
|
95 |
.text(name(d)); |
|
39
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
96 |
|
84 | 97 |
var g1 = svg.insert("g", ".grandparent") |
98 |
.datum(d) |
|
99 |
.attr("class", "depth"); |
|
100 |
||
101 |
var g = g1.selectAll("g") |
|
102 |
.data(d._children) |
|
103 |
.enter().append("g"); |
|
104 |
||
92 | 105 |
g.classed("bla", true).on("click", selectHandler); |
84 | 106 |
|
107 |
g.filter(function(d) { return d._children; }) |
|
108 |
.classed("children", true) |
|
109 |
.on("click", transition); |
|
110 |
||
111 |
g.append("rect") |
|
112 |
.attr("class", "parent") |
|
113 |
// .attr("fill", (d.color || "#bbb")) |
|
114 |
.call(rect) |
|
115 |
.append("title") |
|
116 |
.text(function(d) { return formatNumber(d.value); }); |
|
117 |
||
118 |
g.append("text") |
|
119 |
.attr("dy", ".75em") |
|
120 |
.text(function(d) { return d.name; }) |
|
121 |
.call(text); |
|
122 |
||
123 |
function transition(d) { |
|
92 | 124 |
if (transitioning || !d) { return; } |
84 | 125 |
selectHandler(d); |
126 |
transitioning = true; |
|
127 |
||
128 |
var g2 = display(d), |
|
129 |
t1 = g1.transition().duration(750), |
|
130 |
t2 = g2.transition().duration(750); |
|
131 |
||
132 |
// Update the domain only after entering new elements. |
|
133 |
x.domain([d.x, d.x + d.dx]); |
|
134 |
y.domain([d.y, d.y + d.dy]); |
|
135 |
||
136 |
// Enable anti-aliasing during the transition. |
|
137 |
svg.style("shape-rendering", null); |
|
39
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
138 |
|
84 | 139 |
// Draw child nodes on top of parent nodes. |
140 |
svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; }); |
|
141 |
||
142 |
// Fade-in entering text. |
|
143 |
g2.selectAll("text").style("fill-opacity", 0); |
|
144 |
||
145 |
// Transition to the new view. |
|
146 |
t1.selectAll("text").call(text).style("fill-opacity", 0); |
|
147 |
t2.selectAll("text").call(text).style("fill-opacity", 1); |
|
148 |
t1.selectAll("rect").call(rect); |
|
149 |
t2.selectAll("rect").call(rect); |
|
150 |
||
151 |
// Remove the old node when the transition is finished. |
|
152 |
t1.remove().each("end", function() { |
|
153 |
svg.style("shape-rendering", "crispEdges"); |
|
154 |
transitioning = false; |
|
155 |
}); |
|
156 |
} |
|
157 |
||
158 |
function selectHandler (d){ |
|
159 |
if (d.name === "Global"){ |
|
160 |
return _this.sendAction('action', null); |
|
161 |
} |
|
162 |
_this.sendAction('action', d.name); |
|
163 |
} |
|
164 |
||
165 |
return g; |
|
166 |
} |
|
167 |
||
93 | 168 |
function text(text) { |
84 | 169 |
text.attr("x", function(d) { return x(d.x) + 6; }) |
170 |
.attr("y", function(d) { return y(d.y) + 6; }); |
|
171 |
} |
|
172 |
||
93 | 173 |
function rect(rect) { |
84 | 174 |
rect.attr("x", function(d) { return x(d.x); }) |
175 |
.attr("y", function(d) { return y(d.y); }) |
|
176 |
.attr("width", function(d) { return x(d.x + d.dx) - x(d.x); }) |
|
177 |
.attr("height", function(d) { return y(d.y + d.dy) - y(d.y); }) |
|
178 |
.attr("fill", function(d) { return (d.color || "#bbb")}); |
|
179 |
} |
|
180 |
||
181 |
function name(d) { |
|
92 | 182 |
return d.parent ? name(d.parent) + "." + d.name : d.name; |
84 | 183 |
} |
39
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
184 |
}); |
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
185 |
} |
c693e8673d5b
add visu-langue with google treemap
nowmad@23.1.168.192.in-addr.arpa
parents:
diff
changeset
|
186 |
}); |