1 (function ($) { |
|
2 |
|
3 $.fn._vs.aggregate = { |
|
4 defaultSettings:{ |
|
5 }, |
|
6 |
|
7 // Returns n layers |
|
8 strata_layers: function (_this, n, m, p) { |
|
9 var sn = d3.scale.linear().domain([1, m-2]).range([Math.PI/2, 2*Math.PI-Math.PI/2]); |
|
10 var logscale = d3.scale.pow().exponent(10).domain([0, m]).range([0,1]); |
|
11 |
|
12 return d3.range(n).map(function(i) { |
|
13 var r = 5*Math.random(); |
|
14 |
|
15 return d3.range(m).map(function(j) { |
|
16 |
|
17 if(_this.settings.sedimentation.aggregation.strataType=="sin") { |
|
18 if(i==1) return 20; |
|
19 var x = 5+r*5*Math.sin(sn(j))+(i*50); |
|
20 if(x<0) return -x; else return x; |
|
21 } else if(_this.settings.sedimentation.aggregation.strataType=="log") { |
|
22 return i+1; |
|
23 //return logscale(j);//logscale(i); |
|
24 } else { |
|
25 if(typeof(p)=='undefined') |
|
26 p=0; |
|
27 return _this.settings.data.strata[p][i].value; |
|
28 } |
|
29 }).map(stream_index); |
|
30 }); |
|
31 |
|
32 function stream_index(d, i) { |
|
33 return {x: i, y: Math.max(0, d)}; |
|
34 } |
|
35 |
|
36 }, |
|
37 |
|
38 init:function (_this){ |
|
39 |
|
40 // Skip layers if no strata is defined |
|
41 if(typeof(_this.settings.data.strata)=='undefined' || _this.settings.data.strata.length==0 || _this.settings.data.strata[0].length==0) |
|
42 return; |
|
43 |
|
44 var color = _this.token.colorRange; |
|
45 |
|
46 |
|
47 if(_this.settings.chart.type=='StackedAreaChart') { |
|
48 |
|
49 var w = _this.settings.chart.width/_this.settings.data.model.length, |
|
50 h = _this.settings.sedimentation.aggregation.height; |
|
51 |
|
52 var vis = d3.select("#"+_this.settings.DOMelement.id) |
|
53 //.insert("div", ":first-child") |
|
54 .append("div") |
|
55 .attr("class", "vis") |
|
56 // .style("position", "relative") |
|
57 .style("z-index", 10) |
|
58 .append("svg") |
|
59 .attr("width", _this.settings.width) |
|
60 .attr("height", _this.settings.height) |
|
61 |
|
62 .append("g") |
|
63 .attr("transform", "translate(" + _this.settings.chart.x + "," + _this.settings.chart.y + ")"); |
|
64 |
|
65 var g = vis.selectAll("g.gcol") |
|
66 .data(_this.settings.data.strata, function(d) {return [d];}) |
|
67 .enter() |
|
68 .append("g") |
|
69 .attr("transform", function(d, i) { |
|
70 return "translate("+(i*w)+", "+(_this.settings.chart.height-_this.settings.sedimentation.aggregation.height)+")"; |
|
71 }).attr("class", function(d,i) { return "gcol col_"+i;});; |
|
72 |
|
73 var data =_this.settings.data.strata.map(function(d) { return {value:d[0].value};}); |
|
74 |
|
75 var sn = _this.settings.data.strata[0].length, // number of layers |
|
76 sm = 20; // number of samples per layer |
|
77 smx = sm - 1, smy = 0; |
|
78 |
|
79 var hh=0; |
|
80 |
|
81 // Rectangular strata |
|
82 var area = d3.svg.area() |
|
83 .x(function(d) { return _this.settings.chart.spacer+d.x * (w-2*_this.settings.chart.spacer) / smx; }) |
|
84 .y0(function(d) { return (h - d.y0 * hh); }) //hh/smy |
|
85 .y1(function(d) { return (h - (d.y + d.y0) * hh ); }); //hh/smy |
|
86 |
|
87 var hhh = []; |
|
88 |
|
89 var gpath = g.selectAll("gpath") |
|
90 .data(function(d,i) { |
|
91 var sd = d3.layout.stack().offset("expand")(_this.aggregate.strata_layers(_this, d.length, sm, i)); |
|
92 smy = d3.max(sd, function(d) { |
|
93 return d3.max(d, function(d) { |
|
94 return d.y0 + d.y; |
|
95 }); |
|
96 }); |
|
97 sd.map(function(d) {d.map(function(d) {d.col=i;return d;});}); // Put col # in data |
|
98 return sd; |
|
99 }) |
|
100 .enter().append("g").attr("class", "gpath"); |
|
101 |
|
102 gpath.append("path") |
|
103 .attr("d", function(d,i) { |
|
104 hh = _this.settings.chart.height-_this.chart.getPosition(_this)[d[0].col].y; |
|
105 return area(d); |
|
106 }).style("fill", function(d,i) { |
|
107 if(_this.settings.data.strata[d[0].col][i].texture!=null) { |
|
108 return "url(#RectanglePattern_"+d[0].col+"_"+i+")"; |
|
109 } else { |
|
110 |
|
111 return d3.rgb(color(d[0].col)) |
|
112 .darker(_this.settings.data.strata[d[0].col].length/2-(i+1)/2); // The more away from the token, the darker |
|
113 } |
|
114 }) |
|
115 .attr("class", function(d,i) { return "layer";}) |
|
116 .attr("class", function(d,i) { return "col_"+d[0].col+" layer_"+i;}); |
|
117 |
|
118 // Textures |
|
119 // strata.texture: {url:"../..", size:1}, |
|
120 var patternWidth = w/1; |
|
121 var patternHeight = patternWidth; |
|
122 |
|
123 for(var s=0; s<_this.settings.data.strata.length; s++) { |
|
124 for(var l=0; l<_this.settings.data.strata[s].length; l++) { |
|
125 if(_this.settings.data.strata[s][l].texture!=null) { |
|
126 |
|
127 var pattern = vis.append('pattern') |
|
128 .attr('id','RectanglePattern_'+s+"_"+l) |
|
129 .attr('height', patternHeight) |
|
130 .attr('width', patternWidth) |
|
131 .attr('patternTransform', 'translate(0, 0) scale('+_this.settings.data.strata[s][l].texture.size+', '+_this.settings.data.strata[s][l].texture.size+') rotate(0)') |
|
132 .attr('patternUnits','userSpaceOnUse'); |
|
133 |
|
134 pattern.append('image') |
|
135 .attr('x', 0) |
|
136 .attr('y', 0) |
|
137 .attr('height', patternHeight) |
|
138 .attr('width', patternWidth) |
|
139 .attr('xlink:href', function() { return _this.settings.data.strata[s][l].texture.url;}); |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 // PIE CHAR |
|
145 } else if(_this.settings.chart.type=='CircleLayout') { |
|
146 |
|
147 // strata |
|
148 var svg = d3.select("#"+_this.settings.DOMelement.id) |
|
149 .append("div") |
|
150 .attr("class", "vis")//.style("margin-top", "-"+_this.settings.height+"px") |
|
151 .attr("width", _this.settings.width) |
|
152 .attr("height", _this.settings.height) |
|
153 .append("svg") |
|
154 .attr("width", _this.settings.width) |
|
155 .attr("height", _this.settings.height); |
|
156 |
|
157 // bubble chart |
|
158 if(typeof(_this.settings.chart.treeLayout)!="undefined") { |
|
159 |
|
160 for(var i=0; i<_this.settings.data.model.length; i++) { |
|
161 var data =_this.settings.data.strata[i]; |
|
162 var color = function(s) { return _this.token.colorRange(i)}; |
|
163 _this.aggregate.create_pie_chart(_this, data, svg, data[0].value, color, |
|
164 ((i+1/2))*_this.settings.chart.width/(_this.settings.data.model.length)+_this.settings.chart.x, |
|
165 _this.settings.chart.y+_this.settings.chart.height/6); |
|
166 |
|
167 } |
|
168 |
|
169 } else { |
|
170 var data =_this.settings.data.strata.map(function(d) { return {value:d[0].value};}); |
|
171 console.log(_this.settings.data.strata, data); |
|
172 var color = _this.token.colorRange; |
|
173 _this.aggregate.create_pie_chart(_this, data, svg, _this.settings.chart.radius, color, |
|
174 _this.settings.chart.x+_this.settings.chart.width/2, |
|
175 _this.settings.chart.y+_this.settings.chart.height/2); |
|
176 } |
|
177 |
|
178 } |
|
179 }, |
|
180 |
|
181 create_pie_chart: function(_this, data, svg, r, color, posx, posy) { |
|
182 |
|
183 var w = _this.settings.width/_this.settings.data.model.length, |
|
184 h = _this.settings.sedimentation.aggregation.height;//_this.settings.height; |
|
185 /* |
|
186 var vis = d3.select("#"+_this.settings.DOMelement.id) |
|
187 .append("div") |
|
188 .attr("class", "vis") //.style("margin-top", "-"+_this.settings.height+"px")//+_this.settings.DOMelement.id |
|
189 .append("svg") |
|
190 .attr("width", _this.settings.width) |
|
191 .attr("height", _this.settings.height); |
|
192 |
|
193 var g = vis.selectAll("g") |
|
194 .data(_this.settings.data.strata, function(d) {return [d];}) |
|
195 .enter() |
|
196 .append("g") |
|
197 .attr("transform", function(d, i) { |
|
198 return "translate("+(i*w)+", "+(_this.settings.height-_this.settings.sedimentation.aggregation.height)+")"; |
|
199 }); |
|
200 */ |
|
201 var x = d3.scale.linear() |
|
202 .domain([0, _this.settings.data.strata.length-1]) |
|
203 .range([0, _this.settings.width]); |
|
204 |
|
205 |
|
206 var y = d3.scale.linear() |
|
207 .domain([0, d3.max(data, function(d) {return d.value; })]) |
|
208 .rangeRound([0, h]); |
|
209 |
|
210 /* |
|
211 var sn = _this.settings.data.strata[0].length, // number of layers |
|
212 sm = 20; // number of samples per layer |
|
213 |
|
214 var sdata0 = d3.layout.stack().offset("expand")(strata_layers(sn, sm)), |
|
215 sdata1 = d3.layout.stack().offset("expand")(strata_layers(sn, sm)), |
|
216 smx = sm - 1, smy = 0; |
|
217 */ |
|
218 |
|
219 // CIRCLE |
|
220 var wp = _this.settings.width, |
|
221 hp = _this.settings.height, |
|
222 hhp = _this.settings.sedimentation.aggregation.height; |
|
223 //Math.min(w, hh) / 2, |
|
224 labelr = r + 30, // radius for label anchor |
|
225 donut = d3.layout.pie().sort(null), |
|
226 arc = d3.svg.arc().innerRadius(0).outerRadius(r); |
|
227 |
|
228 var id=Math.random(); |
|
229 svg.append("g.arcs_"+id) |
|
230 .attr("class", "arcs_"+id); |
|
231 |
|
232 var garcs = svg.selectAll(".arcs") |
|
233 .data(donut(data.map(function(d, i) { return d.value}))) |
|
234 .enter().append("svg:g").attr("transform", "translate(" + posx + "," + posy + ")"); |
|
235 /* |
|
236 var arcs = garcs.append("path") |
|
237 .attr("fill", function(d, i) { return color(i); }) |
|
238 .attr("d", function(d) { |
|
239 |
|
240 |
|
241 return arc(d); |
|
242 |
|
243 }) |
|
244 .each(function(d) { this._current = d; }); |
|
245 |
|
246 */ |
|
247 // END CIRCLE |
|
248 |
|
249 |
|
250 var hh=0; |
|
251 |
|
252 // Rectangular strata |
|
253 var area = d3.svg.area() |
|
254 .x(function(d) { return _this.settings.chart.spacer+d.x * (w-2*_this.settings.chart.spacer) / smx; }) |
|
255 .y0(function(d) { return (h - d.y0 * hh); }) //hh/smy |
|
256 .y1(function(d) { return (h - (d.y + d.y0) * hh ); }); //hh/smy |
|
257 |
|
258 var arcs = garcs.append("path") |
|
259 .attr("fill", function(d, i) { return color(i); }) |
|
260 .attr("d", function(d,i) { |
|
261 |
|
262 /* |
|
263 .data(function(d,i) { |
|
264 var sd = d3.layout.stack().offset("expand")(strata_layers(d.length, sm)); |
|
265 smy = d3.max(sd, function(d) { |
|
266 return d3.max(d, function(d) { |
|
267 return d.y0 + d.y; |
|
268 }); |
|
269 }); |
|
270 sd.map(function(d) {d.map(function(d) {d.col=i;return d;});}); // Put col # in data |
|
271 return sd; |
|
272 }) |
|
273 */ |
|
274 return arc(d); |
|
275 |
|
276 }) |
|
277 .each(function(d) { this._current = d; }); |
|
278 |
|
279 /* |
|
280 var hhh = []; |
|
281 |
|
282 g.selectAll("path") |
|
283 .data(function(d,i) { |
|
284 var sd = d3.layout.stack().offset("expand")(strata_layers(d.length, sm)); |
|
285 smy = d3.max(sd, function(d) { |
|
286 return d3.max(d, function(d) { |
|
287 return d.y0 + d.y; |
|
288 }); |
|
289 }); |
|
290 sd.map(function(d) {d.map(function(d) {d.col=i;return d;});}); // Put col # in data |
|
291 return sd; |
|
292 }) |
|
293 .enter().append("path") |
|
294 .attr("d", function(d,i) { |
|
295 hh = 450-_this.chart.getPosition(_this)[d[0].col].y; |
|
296 return area(d); |
|
297 }).style("fill", function(d,i) { |
|
298 if(_this.settings.data.strata[d[0].col][i].texture!=null) { |
|
299 return "url(#RectanglePattern_"+d[0].col+"_"+i+")"; |
|
300 } else { |
|
301 // The more away from the token, the darker |
|
302 return d3.rgb(color(d[0].col)).darker(_this.settings.data.strata[d[0].col].length/2-(i+1)/2); |
|
303 } |
|
304 }); |
|
305 |
|
306 */ |
|
307 |
|
308 |
|
309 /* else if(_this.settings.chart.type=='CircleLayout2') { |
|
310 |
|
311 var data1 = _this.settings.data.strata, |
|
312 data = data1, |
|
313 data2 = _this.settings.data.strata; // 2nd dataset if we want to update |
|
314 |
|
315 console.log("data", data); |
|
316 |
|
317 var w = _this.settings.width, |
|
318 h = _this.settings.height, |
|
319 hh = _this.settings.sedimentation.aggregation.height; |
|
320 r = _this.settings.chart.radius,//Math.min(w, hh) / 2, |
|
321 labelr = r + 30, // radius for label anchor |
|
322 donut = d3.layout.pie().sort(null), |
|
323 arc = d3.svg.arc().innerRadius(0).outerRadius(r); |
|
324 |
|
325 console.log("donut", donut(data)); |
|
326 |
|
327 // strata |
|
328 |
|
329 var svg = d3.select("#"+_this.settings.DOMelement.id).attr("class", "vis")//.style("margin-top", "-"+_this.settings.height+"px") |
|
330 .append("svg:svg") |
|
331 .attr("width", w) |
|
332 .attr("height", h) |
|
333 //.style("position", "absolute") |
|
334 .append("svg:g") |
|
335 .attr("class", "arcs") |
|
336 .attr("transform", "translate(" + (w/2) + "," + (h/2) + ")"); |
|
337 |
|
338 var ddd = donut(_this.settings.data.strata.map(function(d, i) { return d[0].value})); |
|
339 |
|
340 |
|
341 var garcs = svg.selectAll("g") |
|
342 .data(donut(data.map(function(d, i) { return d[0].value}))) |
|
343 .enter().append("svg:g"); |
|
344 |
|
345 var arcs = garcs.append("path") |
|
346 .attr("fill", function(d, i) { return color(i); }) |
|
347 .attr("d", function(d) { return arc(d);}) |
|
348 .each(function(d) { this._current = d; }); |
|
349 |
|
350 |
|
351 var labels = garcs.append("svg:text") |
|
352 .attr("transform", function(d) { |
|
353 var c = arc.centroid(d), |
|
354 x = c[0], |
|
355 y = c[1], |
|
356 h = Math.sqrt(x*x + y*y); // pythagorean theorem for hypotenuse |
|
357 return "translate(" + (x/h * labelr) + ',' + |
|
358 (y/h * labelr) + ")"; |
|
359 }) |
|
360 .attr("dy", ".35em") |
|
361 .attr("text-anchor", function(d) { |
|
362 return (d.endAngle + d.startAngle)/2 > Math.PI ? // are we past the center? |
|
363 "end" : "start"; |
|
364 }) |
|
365 .text(function(d, i) { return _this.settings.data.model[i].label; }); //.toFixed(2) if num val |
|
366 |
|
367 d3.select(window).on("click", function() { |
|
368 data = data === data1 ? data2 : data1; // swap the data |
|
369 arcs = arcs.data(donut(data.map(function(d) { return d[0].value}))); // recompute the angles and rebind the data |
|
370 arcs.transition().duration(750).attrTween("d", arcTween); // redraw the arcs |
|
371 |
|
372 labels.data(donut(data.map(function(d,i) { return d[0].value}))) |
|
373 .transition().duration(750).attr("transform", function(d) { |
|
374 var c = arc.centroid(d), |
|
375 x = c[0], |
|
376 y = c[1], |
|
377 // pythagorean theorem for hypotenuse |
|
378 h = Math.sqrt(x*x + y*y); |
|
379 |
|
380 return "translate(" + (x/h * labelr) + ',' + |
|
381 (y/h * labelr) + ")"; |
|
382 }) |
|
383 .attr("dy", ".35em") |
|
384 .attr("text-anchor", function(d) { |
|
385 // are we past the center? |
|
386 return (d.endAngle + d.startAngle)/2 > Math.PI ? |
|
387 "end" : "start"; |
|
388 }) |
|
389 .text(function(d, i) { return _this.settings.data.model[i].label}); //d.value.toFixed(2); }); |
|
390 }); |
|
391 |
|
392 // Store the currently-displayed angles in this._current. |
|
393 // Then, interpolate from this._current to the new angles. |
|
394 function arcTween(a) { |
|
395 var i = d3.interpolate(this._current, a); |
|
396 this._current = i(0); |
|
397 return function(t) { |
|
398 return arc(i(t)); |
|
399 }; |
|
400 } |
|
401 } // end if char/pie layout |
|
402 */ |
|
403 |
|
404 }, |
|
405 |
|
406 update : function (_this) { |
|
407 |
|
408 if(typeof(_this.settings.data.strata)=='undefined' || _this.settings.data.strata.length==0 || _this.settings.data.strata[0].length==0) // Skip layers if no strata is defined |
|
409 return; |
|
410 |
|
411 var w = _this.settings.chart.width/_this.settings.data.model.length; |
|
412 var h = _this.settings.sedimentation.aggregation.height; |
|
413 |
|
414 var x = d3.scale.linear() |
|
415 .domain([0, _this.settings.data.strata.length-1]) |
|
416 .range([0, _this.settings.width]); |
|
417 |
|
418 var data =_this.settings.data.strata.map(function(d) { return {value:d[0].value};}); |
|
419 |
|
420 var sum_strata =_this.settings.data.strata.map( |
|
421 function(d) { |
|
422 for(var v=0, res=0; v<d.length; v++) |
|
423 res+=d[v].value; |
|
424 return res; |
|
425 }); |
|
426 |
|
427 var y = d3.scale.linear() |
|
428 .domain([0, d3.max(sum_strata)]) |
|
429 .range([0, _this.settings.sedimentation.aggregation.height]); |
|
430 |
|
431 var sn = _this.settings.data.strata[0].length, // number of layers |
|
432 sm = 20; // number of samples per layer |
|
433 smx = sm - 1, smy = 0; |
|
434 |
|
435 var hh=0; |
|
436 |
|
437 // Rectangular strata |
|
438 var area = d3.svg.area() |
|
439 .x(function(d) { return _this.settings.chart.spacer+d.x * (w-2*_this.settings.chart.spacer) / smx; }) |
|
440 .y0(function(d) { return (h - d.y0 * hh); }) //hh/smy |
|
441 .y1(function(d) { return (h - (d.y + d.y0) * hh ); }); //hh/smy |
|
442 |
|
443 var vis = d3.select("svg"); |
|
444 var g = vis.selectAll(".gcol"); |
|
445 |
|
446 g.data(_this.settings.data.strata, function(d,i) { return [d];}); |
|
447 |
|
448 var gpath = g.selectAll(".gpath") |
|
449 .data(function(d,i) { |
|
450 var sd = d3.layout.stack().offset("expand")(_this.aggregate.strata_layers(_this, d.length, sm, i)); |
|
451 smy = d3.max(sd, function(d) { |
|
452 return d3.max(d, function(d) { |
|
453 return d.y0 + d.y; |
|
454 }); |
|
455 }); |
|
456 sd.map(function(d) {d.map(function(d) {d.col=i;return d;});}); // Put col # in data |
|
457 return sd; |
|
458 }); |
|
459 |
|
460 gpath.select("path") |
|
461 .transition() |
|
462 .duration(100) |
|
463 .attr("d", function(d,i) { |
|
464 _this.chartUpdate(i, -y(sum_strata[i])-(h-_this.settings.chart.height)); |
|
465 hh = _this.settings.chart.height-_this.chart.getPosition(_this)[d[0].col].y; |
|
466 return area(d); |
|
467 }); |
|
468 } |
|
469 } |
|
470 })(jQuery); |
|