highstock-rails 1.3.10 → 2.1.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/images/highstock/meteogram-symbols-30px.png +0 -0
  4. data/app/assets/javascripts/highstock.js +418 -369
  5. data/app/assets/javascripts/highstock/adapters/standalone-framework.js +12 -12
  6. data/app/assets/javascripts/highstock/adapters/standalone-framework.src.js +635 -0
  7. data/app/assets/javascripts/highstock/highcharts-3d.js +48 -0
  8. data/app/assets/javascripts/highstock/highcharts-3d.src.js +1711 -0
  9. data/app/assets/javascripts/highstock/highcharts-more.js +49 -45
  10. data/app/assets/javascripts/highstock/highstock-all.js +637 -0
  11. data/app/assets/javascripts/highstock/modules/boost.js +12 -0
  12. data/app/assets/javascripts/highstock/modules/boost.src.js +591 -0
  13. data/app/assets/javascripts/highstock/modules/canvas-tools.js +9 -9
  14. data/app/assets/javascripts/highstock/modules/canvas-tools.src.js +3114 -0
  15. data/app/assets/javascripts/highstock/modules/data.js +20 -10
  16. data/app/assets/javascripts/highstock/modules/data.src.js +957 -0
  17. data/app/assets/javascripts/highstock/modules/drilldown.js +17 -14
  18. data/app/assets/javascripts/highstock/modules/drilldown.src.js +717 -0
  19. data/app/assets/javascripts/highstock/modules/exporting.js +17 -15
  20. data/app/assets/javascripts/highstock/modules/exporting.src.js +780 -0
  21. data/app/assets/javascripts/highstock/modules/funnel.js +5 -5
  22. data/app/assets/javascripts/highstock/modules/funnel.src.js +322 -0
  23. data/app/assets/javascripts/highstock/modules/heatmap.js +23 -2
  24. data/app/assets/javascripts/highstock/modules/heatmap.src.js +711 -0
  25. data/app/assets/javascripts/highstock/modules/no-data-to-display.js +4 -4
  26. data/app/assets/javascripts/highstock/modules/no-data-to-display.src.js +143 -0
  27. data/app/assets/javascripts/highstock/modules/offline-exporting.js +14 -0
  28. data/app/assets/javascripts/highstock/modules/offline-exporting.src.js +280 -0
  29. data/app/assets/javascripts/highstock/modules/solid-gauge.js +14 -0
  30. data/app/assets/javascripts/highstock/modules/solid-gauge.src.js +273 -0
  31. data/app/assets/javascripts/highstock/modules/treemap.js +30 -0
  32. data/app/assets/javascripts/highstock/modules/treemap.src.js +868 -0
  33. data/app/assets/javascripts/highstock/themes/dark-blue.js +1 -1
  34. data/app/assets/javascripts/highstock/themes/dark-green.js +1 -1
  35. data/app/assets/javascripts/highstock/themes/dark-unica.js +213 -0
  36. data/app/assets/javascripts/highstock/themes/gray.js +1 -1
  37. data/app/assets/javascripts/highstock/themes/grid-light.js +74 -0
  38. data/app/assets/javascripts/highstock/themes/sand-signika.js +104 -0
  39. data/lib/highstock/rails/version.rb +1 -1
  40. metadata +26 -7
  41. data/app/assets/javascripts/highstock/adapters/mootools-adapter.js +0 -13
  42. data/app/assets/javascripts/highstock/adapters/prototype-adapter.js +0 -15
  43. data/app/assets/javascripts/highstock/modules/annotations.js +0 -7
  44. data/app/assets/javascripts/highstock/modules/map.js +0 -41
@@ -0,0 +1,14 @@
1
+ /*
2
+ Highstock JS v2.1.10 (2015-12-07)
3
+ Solid angular gauge module
4
+
5
+ (c) 2010-2014 Torstein Honsi
6
+
7
+ License: www.highcharts.com/license
8
+ */
9
+ (function(a){typeof module==="object"&&module.exports?module.exports=a:a(Highcharts)})(function(a){var q=a.getOptions().plotOptions,r=a.pInt,s=a.pick,j=a.each,k;q.solidgauge=a.merge(q.gauge,{colorByPoint:!0});k={initDataClasses:function(b){var c=this,l=this.chart,d,g=0,e=this.options;this.dataClasses=d=[];j(b.dataClasses,function(f,h){var p,f=a.merge(f);d.push(f);if(!f.color)e.dataClassColor==="category"?(p=l.options.colors,f.color=p[g++],g===p.length&&(g=0)):f.color=c.tweenColors(a.Color(e.minColor),
10
+ a.Color(e.maxColor),h/(b.dataClasses.length-1))})},initStops:function(b){this.stops=b.stops||[[0,this.options.minColor],[1,this.options.maxColor]];j(this.stops,function(b){b.color=a.Color(b[1])})},toColor:function(b,c){var a,d=this.stops,g,e=this.dataClasses,f,h;if(e)for(h=e.length;h--;){if(f=e[h],g=f.from,d=f.to,(g===void 0||b>=g)&&(d===void 0||b<=d)){a=f.color;if(c)c.dataClass=h;break}}else{this.isLog&&(b=this.val2lin(b));a=1-(this.max-b)/(this.max-this.min);for(h=d.length;h--;)if(a>d[h][0])break;
11
+ g=d[h]||d[h+1];d=d[h+1]||g;a=1-(d[0]-a)/(d[0]-g[0]||1);a=this.tweenColors(g.color,d.color,a)}return a},tweenColors:function(b,c,a){var d;!c.rgba.length||!b.rgba.length?b=c.input||"none":(b=b.rgba,c=c.rgba,d=c[3]!==1||b[3]!==1,b=(d?"rgba(":"rgb(")+Math.round(c[0]+(b[0]-c[0])*(1-a))+","+Math.round(c[1]+(b[1]-c[1])*(1-a))+","+Math.round(c[2]+(b[2]-c[2])*(1-a))+(d?","+(c[3]+(b[3]-c[3])*(1-a)):"")+")");return b}};j(["fill","stroke"],function(b){a.addAnimSetter(b,function(c){c.elem.attr(b,k.tweenColors(a.Color(c.start),
12
+ a.Color(c.end),c.pos))})});a.seriesTypes.solidgauge=a.extendClass(a.seriesTypes.gauge,{type:"solidgauge",pointAttrToOptions:{},bindAxes:function(){var b;a.seriesTypes.gauge.prototype.bindAxes.call(this);b=this.yAxis;a.extend(b,k);b.options.dataClasses&&b.initDataClasses(b.options);b.initStops(b.options)},drawPoints:function(){var b=this,c=b.yAxis,l=c.center,d=b.options,g=b.chart.renderer,e=d.overshoot,f=e&&typeof e==="number"?e/180*Math.PI:0;a.each(b.points,function(a){var e=a.graphic,i=c.startAngleRad+
13
+ c.translate(a.y,null,null,null,!0),j=r(s(a.options.radius,d.radius,100))*l[2]/200,m=r(s(a.options.innerRadius,d.innerRadius,60))*l[2]/200,n=c.toColor(a.y,a),o=Math.min(c.startAngleRad,c.endAngleRad),k=Math.max(c.startAngleRad,c.endAngleRad);n==="none"&&(n=a.color||b.color||"none");if(n!=="none")a.color=n;i=Math.max(o-f,Math.min(k+f,i));d.wrap===!1&&(i=Math.max(o,Math.min(k,i)));o=Math.min(i,c.startAngleRad);i=Math.max(i,c.startAngleRad);i-o>2*Math.PI&&(i=o+2*Math.PI);a.shapeArgs=m={x:l[0],y:l[1],
14
+ r:j,innerR:m,start:o,end:i,fill:n};a.startR=j;if(e){if(a=m.d,e.animate(m),a)m.d=a}else a.graphic=g.arc(m).attr({stroke:d.borderColor||"none","stroke-width":d.borderWidth||0,fill:n,"sweep-flag":0}).add(b.group)})},animate:function(b){if(!b)this.startAngleRad=this.yAxis.startAngleRad,a.seriesTypes.pie.prototype.animate.call(this,b)}})});
@@ -0,0 +1,273 @@
1
+ /**
2
+ * @license Highstock JS v2.1.10 (2015-12-07)
3
+ * Solid angular gauge module
4
+ *
5
+ * (c) 2010-2014 Torstein Honsi
6
+ *
7
+ * License: www.highcharts.com/license
8
+ */
9
+
10
+ (function (factory) {
11
+ if (typeof module === 'object' && module.exports) {
12
+ module.exports = factory;
13
+ } else {
14
+ factory(Highcharts);
15
+ }
16
+ }(function (H) {
17
+ 'use strict';
18
+
19
+ var defaultPlotOptions = H.getOptions().plotOptions,
20
+ pInt = H.pInt,
21
+ pick = H.pick,
22
+ each = H.each,
23
+ colorAxisMethods,
24
+ UNDEFINED;
25
+
26
+ // The default options
27
+ defaultPlotOptions.solidgauge = H.merge(defaultPlotOptions.gauge, {
28
+ colorByPoint: true
29
+ });
30
+
31
+
32
+ // These methods are defined in the ColorAxis object, and copied here.
33
+ // If we implement an AMD system we should make ColorAxis a dependency.
34
+ colorAxisMethods = {
35
+
36
+
37
+ initDataClasses: function (userOptions) {
38
+ var axis = this,
39
+ chart = this.chart,
40
+ dataClasses,
41
+ colorCounter = 0,
42
+ options = this.options;
43
+ this.dataClasses = dataClasses = [];
44
+
45
+ each(userOptions.dataClasses, function (dataClass, i) {
46
+ var colors;
47
+
48
+ dataClass = H.merge(dataClass);
49
+ dataClasses.push(dataClass);
50
+ if (!dataClass.color) {
51
+ if (options.dataClassColor === 'category') {
52
+ colors = chart.options.colors;
53
+ dataClass.color = colors[colorCounter++];
54
+ // loop back to zero
55
+ if (colorCounter === colors.length) {
56
+ colorCounter = 0;
57
+ }
58
+ } else {
59
+ dataClass.color = axis.tweenColors(H.Color(options.minColor), H.Color(options.maxColor), i / (userOptions.dataClasses.length - 1));
60
+ }
61
+ }
62
+ });
63
+ },
64
+
65
+ initStops: function (userOptions) {
66
+ this.stops = userOptions.stops || [
67
+ [0, this.options.minColor],
68
+ [1, this.options.maxColor]
69
+ ];
70
+ each(this.stops, function (stop) {
71
+ stop.color = H.Color(stop[1]);
72
+ });
73
+ },
74
+ /**
75
+ * Translate from a value to a color
76
+ */
77
+ toColor: function (value, point) {
78
+ var pos,
79
+ stops = this.stops,
80
+ from,
81
+ to,
82
+ color,
83
+ dataClasses = this.dataClasses,
84
+ dataClass,
85
+ i;
86
+
87
+ if (dataClasses) {
88
+ i = dataClasses.length;
89
+ while (i--) {
90
+ dataClass = dataClasses[i];
91
+ from = dataClass.from;
92
+ to = dataClass.to;
93
+ if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
94
+ color = dataClass.color;
95
+ if (point) {
96
+ point.dataClass = i;
97
+ }
98
+ break;
99
+ }
100
+ }
101
+
102
+ } else {
103
+
104
+ if (this.isLog) {
105
+ value = this.val2lin(value);
106
+ }
107
+ pos = 1 - ((this.max - value) / (this.max - this.min));
108
+ i = stops.length;
109
+ while (i--) {
110
+ if (pos > stops[i][0]) {
111
+ break;
112
+ }
113
+ }
114
+ from = stops[i] || stops[i + 1];
115
+ to = stops[i + 1] || from;
116
+
117
+ // The position within the gradient
118
+ pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
119
+
120
+ color = this.tweenColors(
121
+ from.color,
122
+ to.color,
123
+ pos
124
+ );
125
+ }
126
+ return color;
127
+ },
128
+ /*
129
+ * Return an intermediate color between two colors, according to pos where 0
130
+ * is the from color and 1 is the to color.
131
+ */
132
+ tweenColors: function (from, to, pos) {
133
+ // Check for has alpha, because rgba colors perform worse due to lack of
134
+ // support in WebKit.
135
+ var hasAlpha,
136
+ ret;
137
+
138
+ // Unsupported color, return to-color (#3920)
139
+ if (!to.rgba.length || !from.rgba.length) {
140
+ ret = to.input || 'none';
141
+
142
+ // Interpolate
143
+ } else {
144
+ from = from.rgba;
145
+ to = to.rgba;
146
+ hasAlpha = (to[3] !== 1 || from[3] !== 1);
147
+ ret = (hasAlpha ? 'rgba(' : 'rgb(') +
148
+ Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
149
+ Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
150
+ Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
151
+ (hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
152
+ }
153
+ return ret;
154
+ }
155
+ };
156
+
157
+ /**
158
+ * Handle animation of the color attributes directly
159
+ */
160
+ each(['fill', 'stroke'], function (prop) {
161
+ H.addAnimSetter(prop, function (fx) {
162
+ fx.elem.attr(prop, colorAxisMethods.tweenColors(H.Color(fx.start), H.Color(fx.end), fx.pos));
163
+ });
164
+ });
165
+
166
+ // The series prototype
167
+ H.seriesTypes.solidgauge = H.extendClass(H.seriesTypes.gauge, {
168
+ type: 'solidgauge',
169
+ pointAttrToOptions: {}, // #4301, don't inherit line marker's attribs
170
+ bindAxes: function () {
171
+ var axis;
172
+ H.seriesTypes.gauge.prototype.bindAxes.call(this);
173
+
174
+ axis = this.yAxis;
175
+ H.extend(axis, colorAxisMethods);
176
+
177
+ // Prepare data classes
178
+ if (axis.options.dataClasses) {
179
+ axis.initDataClasses(axis.options);
180
+ }
181
+ axis.initStops(axis.options);
182
+ },
183
+
184
+ /**
185
+ * Draw the points where each point is one needle
186
+ */
187
+ drawPoints: function () {
188
+ var series = this,
189
+ yAxis = series.yAxis,
190
+ center = yAxis.center,
191
+ options = series.options,
192
+ renderer = series.chart.renderer,
193
+ overshoot = options.overshoot,
194
+ overshootVal = overshoot && typeof overshoot === 'number' ? overshoot / 180 * Math.PI : 0;
195
+
196
+ H.each(series.points, function (point) {
197
+ var graphic = point.graphic,
198
+ rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
199
+ radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200,
200
+ innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200,
201
+ shapeArgs,
202
+ d,
203
+ toColor = yAxis.toColor(point.y, point),
204
+ axisMinAngle = Math.min(yAxis.startAngleRad, yAxis.endAngleRad),
205
+ axisMaxAngle = Math.max(yAxis.startAngleRad, yAxis.endAngleRad),
206
+ minAngle,
207
+ maxAngle;
208
+
209
+ if (toColor === 'none') { // #3708
210
+ toColor = point.color || series.color || 'none';
211
+ }
212
+ if (toColor !== 'none') {
213
+ point.color = toColor;
214
+ }
215
+
216
+ // Handle overshoot and clipping to axis max/min
217
+ rotation = Math.max(axisMinAngle - overshootVal, Math.min(axisMaxAngle + overshootVal, rotation));
218
+
219
+ // Handle the wrap option
220
+ if (options.wrap === false) {
221
+ rotation = Math.max(axisMinAngle, Math.min(axisMaxAngle, rotation));
222
+ }
223
+
224
+ minAngle = Math.min(rotation, yAxis.startAngleRad);
225
+ maxAngle = Math.max(rotation, yAxis.startAngleRad);
226
+
227
+ if (maxAngle - minAngle > 2 * Math.PI) {
228
+ maxAngle = minAngle + 2 * Math.PI;
229
+ }
230
+
231
+ point.shapeArgs = shapeArgs = {
232
+ x: center[0],
233
+ y: center[1],
234
+ r: radius,
235
+ innerR: innerRadius,
236
+ start: minAngle,
237
+ end: maxAngle,
238
+ fill: toColor
239
+ };
240
+ point.startR = radius; // For PieSeries.animate
241
+
242
+ if (graphic) {
243
+ d = shapeArgs.d;
244
+ graphic.animate(shapeArgs);
245
+ if (d) {
246
+ shapeArgs.d = d; // animate alters it
247
+ }
248
+ } else {
249
+ point.graphic = renderer.arc(shapeArgs)
250
+ .attr({
251
+ stroke: options.borderColor || 'none',
252
+ 'stroke-width': options.borderWidth || 0,
253
+ fill: toColor,
254
+ 'sweep-flag': 0
255
+ })
256
+ .add(series.group);
257
+ }
258
+ });
259
+ },
260
+
261
+ /**
262
+ * Extend the pie slice animation by animating from start angle and up
263
+ */
264
+ animate: function (init) {
265
+
266
+ if (!init) {
267
+ this.startAngleRad = this.yAxis.startAngleRad;
268
+ H.seriesTypes.pie.prototype.animate.call(this, init);
269
+ }
270
+ }
271
+ });
272
+
273
+ }));
@@ -0,0 +1,30 @@
1
+ /*
2
+ Highstock JS v2.1.10 (2015-12-07)
3
+
4
+ (c) 2014 Highsoft AS
5
+ Authors: Jon Arild Nygard / Oystein Moseng
6
+
7
+ License: www.highcharts.com/license
8
+ */
9
+ (function(f){typeof module==="object"&&module.exports?module.exports=f:f(Highcharts)})(function(f){var j=f.seriesTypes,A=f.map,o=f.merge,t=f.extend,u=f.extendClass,v=f.getOptions().plotOptions,w=function(){},k=f.each,s=f.grep,i=f.pick,m=f.Series,B=f.stableSort,x=f.Color,C=function(a,b,c){var d,c=c||this;for(d in a)a.hasOwnProperty(d)&&b.call(c,a[d],d,a)},y=function(a,b,c,d){d=d||this;a=a||[];k(a,function(e,g){c=b.call(d,c,e,g,a)});return c},r=function(a,b,c){c=c||this;a=b.call(c,a);a!==!1&&r(a,b,
10
+ c)};v.treemap=o(v.scatter,{showInLegend:!1,marker:!1,borderColor:"#E0E0E0",borderWidth:1,dataLabels:{enabled:!0,defer:!1,verticalAlign:"middle",formatter:function(){return this.point.name||this.point.id},inside:!0},tooltip:{headerFormat:"",pointFormat:"<b>{point.name}</b>: {point.node.val}</b><br/>"},layoutAlgorithm:"sliceAndDice",layoutStartingDirection:"vertical",alternateStartingDirection:!1,levelIsConstant:!0,states:{hover:{borderColor:"#A0A0A0",brightness:j.heatmap?0:0.1,shadow:!1}},drillUpButton:{position:{align:"right",
11
+ x:-10,y:10}}});j.treemap=u(j.scatter,o({pointAttrToOptions:{},pointArrayMap:["value"],axisTypes:j.heatmap?["xAxis","yAxis","colorAxis"]:["xAxis","yAxis"],optionalAxis:"colorAxis",getSymbol:w,parallelArrays:["x","y","value","colorValue"],colorKey:"colorValue",translateColors:j.heatmap&&j.heatmap.prototype.translateColors},{type:"treemap",trackerGroups:["group","dataLabelsGroup"],pointClass:u(f.Point,{setVisible:j.pie.prototype.pointClass.prototype.setVisible}),getListOfParents:function(a,b){var c=
12
+ y(a,function(a,c,b){c=i(c.parent,"");a[c]===void 0&&(a[c]=[]);a[c].push(b);return a},{});C(c,function(a,c,g){c!==""&&f.inArray(c,b)===-1&&(k(a,function(a){g[""].push(a)}),delete g[c])});return c},getTree:function(){var a,b=this;a=A(this.data,function(a){return a.id});a=b.getListOfParents(this.data,a);b.nodeMap=[];a=b.buildNode("",-1,0,a,null);r(this.nodeMap[this.rootNode],function(a){var d=!1,e=a.parent;a.visible=!0;if(e||e==="")d=b.nodeMap[e];return d});r(this.nodeMap[this.rootNode].children,function(a){var b=
13
+ !1;k(a,function(a){a.visible=!0;a.children.length&&(b=(b||[]).concat(a.children))});return b});this.setTreeValues(a);return a},init:function(a,b){m.prototype.init.call(this,a,b);this.options.allowDrillToNode&&this.drillTo()},buildNode:function(a,b,c,d,e){var g=this,h=[],z=g.points[b],q;k(d[a]||[],function(b){q=g.buildNode(g.points[b].id,b,c+1,d,a);h.push(q)});b={id:a,i:b,children:h,level:c,parent:e,visible:!1};g.nodeMap[b.id]=b;if(z)z.node=b;return b},setTreeValues:function(a){var b=this,c=b.options,
14
+ d=0,e=[],g,h=b.points[a.i];k(a.children,function(a){a=b.setTreeValues(a);e.push(a);a.ignore?r(a.children,function(a){var c=!1;k(a,function(a){t(a,{ignore:!0,isLeaf:!1,visible:!1});a.children.length&&(c=(c||[]).concat(a.children))});return c}):d+=a.val});B(e,function(a,c){return a.sortIndex-c.sortIndex});g=i(h&&h.value,d);t(a,{children:e,childrenTotal:d,ignore:!(i(h&&h.visible,!0)&&g>0),isLeaf:a.visible&&!d,levelDynamic:c.levelIsConstant?a.level:a.level-b.nodeMap[b.rootNode].level,name:i(h&&h.name,
15
+ ""),sortIndex:i(h&&h.sortIndex,-g),val:g});return a},calculateChildrenAreas:function(a,b){var c=this,d=c.options,e=this.levelMap[a.levelDynamic+1],g=i(c[e&&e.layoutAlgorithm]&&e.layoutAlgorithm,d.layoutAlgorithm),h=d.alternateStartingDirection,f=[],d=s(a.children,function(a){return!a.ignore});if(e&&e.layoutStartingDirection)b.direction=e.layoutStartingDirection==="vertical"?0:1;f=c[g](b,d);k(d,function(a,d){var e=f[d];a.values=o(e,{val:a.childrenTotal,direction:h?1-b.direction:b.direction});a.pointValues=
16
+ o(e,{x:e.x/c.axisRatio,width:e.width/c.axisRatio});a.children.length&&c.calculateChildrenAreas(a,a.values)})},setPointValues:function(){var a=this.xAxis,b=this.yAxis;k(this.points,function(c){var d=c.node.pointValues,e,g,h;d?(e=Math.round(a.translate(d.x,0,0,0,1)),g=Math.round(a.translate(d.x+d.width,0,0,0,1)),h=Math.round(b.translate(d.y,0,0,0,1)),d=Math.round(b.translate(d.y+d.height,0,0,0,1)),c.shapeType="rect",c.shapeArgs={x:Math.min(e,g),y:Math.min(h,d),width:Math.abs(g-e),height:Math.abs(d-
17
+ h)},c.plotX=c.shapeArgs.x+c.shapeArgs.width/2,c.plotY=c.shapeArgs.y+c.shapeArgs.height/2):(delete c.plotX,delete c.plotY)})},setColorRecursive:function(a,b){var c=this,d,e;if(a){d=c.points[a.i];e=c.levelMap[a.levelDynamic];b=i(d&&d.options.color,e&&e.color,b);if(d)d.color=b;a.children.length&&k(a.children,function(a){c.setColorRecursive(a,b)})}},algorithmGroup:function(a,b,c,d){this.height=a;this.width=b;this.plot=d;this.startDirection=this.direction=c;this.lH=this.nH=this.lW=this.nW=this.total=0;
18
+ this.elArr=[];this.lP={total:0,lH:0,nH:0,lW:0,nW:0,nR:0,lR:0,aspectRatio:function(a,c){return Math.max(a/c,c/a)}};this.addElement=function(a){this.lP.total=this.elArr[this.elArr.length-1];this.total+=a;this.direction===0?(this.lW=this.nW,this.lP.lH=this.lP.total/this.lW,this.lP.lR=this.lP.aspectRatio(this.lW,this.lP.lH),this.nW=this.total/this.height,this.lP.nH=this.lP.total/this.nW,this.lP.nR=this.lP.aspectRatio(this.nW,this.lP.nH)):(this.lH=this.nH,this.lP.lW=this.lP.total/this.lH,this.lP.lR=this.lP.aspectRatio(this.lP.lW,
19
+ this.lH),this.nH=this.total/this.width,this.lP.nW=this.lP.total/this.nH,this.lP.nR=this.lP.aspectRatio(this.lP.nW,this.nH));this.elArr.push(a)};this.reset=function(){this.lW=this.nW=0;this.elArr=[];this.total=0}},algorithmCalcPoints:function(a,b,c,d){var e,g,h,f,q=c.lW,n=c.lH,l=c.plot,i,j=0,p=c.elArr.length-1;b?(q=c.nW,n=c.nH):i=c.elArr[c.elArr.length-1];k(c.elArr,function(a){if(b||j<p)c.direction===0?(e=l.x,g=l.y,h=q,f=a/h):(e=l.x,g=l.y,f=n,h=a/f),d.push({x:e,y:g,width:h,height:f}),c.direction===
20
+ 0?l.y+=f:l.x+=h;j+=1});c.reset();c.direction===0?c.width-=q:c.height-=n;l.y=l.parent.y+(l.parent.height-c.height);l.x=l.parent.x+(l.parent.width-c.width);if(a)c.direction=1-c.direction;b||c.addElement(i)},algorithmLowAspectRatio:function(a,b,c){var d=[],e=this,g,f={x:b.x,y:b.y,parent:b},i=0,j=c.length-1,n=new this.algorithmGroup(b.height,b.width,b.direction,f);k(c,function(c){g=b.width*b.height*(c.val/b.val);n.addElement(g);n.lP.nR>n.lP.lR&&e.algorithmCalcPoints(a,!1,n,d,f);i===j&&e.algorithmCalcPoints(a,
21
+ !0,n,d,f);i+=1});return d},algorithmFill:function(a,b,c){var d=[],e,f=b.direction,h=b.x,i=b.y,j=b.width,n=b.height,l,o,m,p;k(c,function(c){e=b.width*b.height*(c.val/b.val);l=h;o=i;f===0?(p=n,m=e/p,j-=m,h+=m):(m=j,p=e/m,n-=p,i+=p);d.push({x:l,y:o,width:m,height:p});a&&(f=1-f)});return d},strip:function(a,b){return this.algorithmLowAspectRatio(!1,a,b)},squarified:function(a,b){return this.algorithmLowAspectRatio(!0,a,b)},sliceAndDice:function(a,b){return this.algorithmFill(!0,a,b)},stripes:function(a,
22
+ b){return this.algorithmFill(!1,a,b)},translate:function(){var a,b;m.prototype.translate.call(this);this.rootNode=i(this.options.rootId,"");this.levelMap=y(this.options.levels,function(a,b){a[b.level]=b;return a},{});b=this.tree=this.getTree();this.axisRatio=this.xAxis.len/this.yAxis.len;this.nodeMap[""].pointValues=a={x:0,y:0,width:100,height:100};this.nodeMap[""].values=a=o(a,{width:a.width*this.axisRatio,direction:this.options.layoutStartingDirection==="vertical"?0:1,val:b.val});this.calculateChildrenAreas(b,
23
+ a);this.colorAxis?this.translateColors():this.options.colorByPoint||this.setColorRecursive(this.tree,void 0);b=this.nodeMap[this.rootNode].pointValues;this.xAxis.setExtremes(b.x,b.x+b.width,!1);this.yAxis.setExtremes(b.y,b.y+b.height,!1);this.xAxis.setScale();this.yAxis.setScale();this.setPointValues()},drawDataLabels:function(){var a=this,b=s(a.points,function(a){return a.node.visible}),c,d;k(b,function(b){d=a.levelMap[b.node.levelDynamic];c={style:{}};if(!b.node.isLeaf)c.enabled=!1;if(d&&d.dataLabels)c=
24
+ o(c,d.dataLabels),a._hasPointLabels=!0;if(b.shapeArgs)c.style.width=b.shapeArgs.width;b.dlOptions=o(c,b.options.dataLabels)});m.prototype.drawDataLabels.call(this)},alignDataLabel:j.column.prototype.alignDataLabel,pointAttribs:function(a,b){var c=this.levelMap[a.node.levelDynamic]||{},d=this.options,e=b&&d.states[b]||{},c={stroke:a.borderColor||c.borderColor||e.borderColor||d.borderColor,"stroke-width":i(a.borderWidth,c.borderWidth,e.borderWidth,d.borderWidth),dashstyle:a.borderDashStyle||c.borderDashStyle||
25
+ e.borderDashStyle||d.borderDashStyle,fill:a.color||this.color,zIndex:b==="hover"?1:0};if(a.node.level<=this.nodeMap[this.rootNode].level)c.fill="none",c["stroke-width"]=0;else if(a.node.isLeaf){if(b)c.fill=x(c.fill).brighten(e.brightness).get()}else c.fill=i(d.interactByLeaf,!d.allowDrillToNode)?"none":x(c.fill).setOpacity(b==="hover"?0.75:0.15).get();return c},drawPoints:function(){var a=this,b=s(a.points,function(a){return a.node.visible});k(b,function(c){var b="levelGroup-"+c.node.levelDynamic;
26
+ a[b]||(a[b]=a.chart.renderer.g(b).attr({zIndex:1E3-c.node.levelDynamic}).add(a.group));c.group=a[b];c.pointAttr={"":a.pointAttribs(c),hover:a.pointAttribs(c,"hover"),select:{}}});j.column.prototype.drawPoints.call(this);a.options.allowDrillToNode&&k(b,function(b){var d;if(b.graphic)d=b.drillId=a.options.interactByLeaf?a.drillToByLeaf(b):a.drillToByGroup(b),b.graphic.css({cursor:d?"pointer":"default"})})},drillTo:function(){var a=this;f.addEvent(a,"click",function(b){var b=b.point,c=b.drillId,d;c&&
27
+ (d=a.nodeMap[a.rootNode].name||a.rootNode,b.setState(""),a.drillToNode(c),a.showDrillUpButton(d))})},drillToByGroup:function(a){var b=!1;if(a.node.level-this.nodeMap[this.rootNode].level===1&&!a.node.isLeaf)b=a.id;return b},drillToByLeaf:function(a){var b=!1;if(a.node.parent!==this.rootNode&&a.node.isLeaf)for(a=a.node;!b;)if(a=this.nodeMap[a.parent],a.parent===this.rootNode)b=a.id;return b},drillUp:function(){var a=null;this.rootNode&&(a=this.nodeMap[this.rootNode],a=a.parent!==null?this.nodeMap[a.parent]:
28
+ this.nodeMap[""]);if(a!==null)this.drillToNode(a.id),a.id===""?this.drillUpButton=this.drillUpButton.destroy():(a=this.nodeMap[a.parent],this.showDrillUpButton(a.name||a.id))},drillToNode:function(a){this.options.rootId=a;this.isDirty=!0;this.chart.redraw()},showDrillUpButton:function(a){var b=this,a=a||"< Back",c=b.options.drillUpButton,d,e;if(c.text)a=c.text;this.drillUpButton?this.drillUpButton.attr({text:a}).align():(e=(d=c.theme)&&d.states,this.drillUpButton=this.chart.renderer.button(a,null,
29
+ null,function(){b.drillUp()},d,e&&e.hover,e&&e.select).attr({align:c.position.align,zIndex:9}).add().align(c.position,!1,c.relativeTo||"plotBox"))},buildKDTree:w,drawLegendSymbol:f.LegendSymbolMixin.drawRectangle,getExtremes:function(){m.prototype.getExtremes.call(this,this.colorValueData);this.valueMin=this.dataMin;this.valueMax=this.dataMax;m.prototype.getExtremes.call(this)},getExtremesFromAll:!0,bindAxes:function(){var a={endOnTick:!1,gridLineWidth:0,lineWidth:0,min:0,dataMin:0,minPadding:0,max:100,
30
+ dataMax:100,maxPadding:0,startOnTick:!1,title:null,tickPositions:[]};m.prototype.bindAxes.call(this);f.extend(this.yAxis.options,a);f.extend(this.xAxis.options,a)}}))});
@@ -0,0 +1,868 @@
1
+ /**
2
+ * @license Highstock JS v2.1.10 (2015-12-07)
3
+ *
4
+ * (c) 2014 Highsoft AS
5
+ * Authors: Jon Arild Nygard / Oystein Moseng
6
+ *
7
+ * License: www.highcharts.com/license
8
+ */
9
+
10
+ (function (factory) {
11
+ if (typeof module === 'object' && module.exports) {
12
+ module.exports = factory;
13
+ } else {
14
+ factory(Highcharts);
15
+ }
16
+ }(function (H) {
17
+ var seriesTypes = H.seriesTypes,
18
+ map = H.map,
19
+ merge = H.merge,
20
+ extend = H.extend,
21
+ extendClass = H.extendClass,
22
+ defaultOptions = H.getOptions(),
23
+ plotOptions = defaultOptions.plotOptions,
24
+ noop = function () {
25
+ },
26
+ each = H.each,
27
+ grep = H.grep,
28
+ pick = H.pick,
29
+ Series = H.Series,
30
+ stableSort = H.stableSort,
31
+ Color = H.Color,
32
+ eachObject = function (list, func, context) {
33
+ var key;
34
+ context = context || this;
35
+ for (key in list) {
36
+ if (list.hasOwnProperty(key)) {
37
+ func.call(context, list[key], key, list);
38
+ }
39
+ }
40
+ },
41
+ reduce = function (arr, func, previous, context) {
42
+ context = context || this;
43
+ arr = arr || []; // @note should each be able to handle empty values automatically?
44
+ each(arr, function (current, i) {
45
+ previous = func.call(context, previous, current, i, arr);
46
+ });
47
+ return previous;
48
+ },
49
+ // @todo find correct name for this function.
50
+ recursive = function (item, func, context) {
51
+ var next;
52
+ context = context || this;
53
+ next = func.call(context, item);
54
+ if (next !== false) {
55
+ recursive(next, func, context);
56
+ }
57
+ };
58
+
59
+ // Define default options
60
+ plotOptions.treemap = merge(plotOptions.scatter, {
61
+ showInLegend: false,
62
+ marker: false,
63
+ borderColor: '#E0E0E0',
64
+ borderWidth: 1,
65
+ dataLabels: {
66
+ enabled: true,
67
+ defer: false,
68
+ verticalAlign: 'middle',
69
+ formatter: function () { // #2945
70
+ return this.point.name || this.point.id;
71
+ },
72
+ inside: true
73
+ },
74
+ tooltip: {
75
+ headerFormat: '',
76
+ pointFormat: '<b>{point.name}</b>: {point.node.val}</b><br/>'
77
+ },
78
+ layoutAlgorithm: 'sliceAndDice',
79
+ layoutStartingDirection: 'vertical',
80
+ alternateStartingDirection: false,
81
+ levelIsConstant: true,
82
+ states: {
83
+ hover: {
84
+ borderColor: '#A0A0A0',
85
+ brightness: seriesTypes.heatmap ? 0 : 0.1,
86
+ shadow: false
87
+ }
88
+ },
89
+ drillUpButton: {
90
+ position: {
91
+ align: 'right',
92
+ x: -10,
93
+ y: 10
94
+ }
95
+ }
96
+ });
97
+
98
+ // Stolen from heatmap
99
+ var colorSeriesMixin = {
100
+ // mapping between SVG attributes and the corresponding options
101
+ pointAttrToOptions: {},
102
+ pointArrayMap: ['value'],
103
+ axisTypes: seriesTypes.heatmap ? ['xAxis', 'yAxis', 'colorAxis'] : ['xAxis', 'yAxis'],
104
+ optionalAxis: 'colorAxis',
105
+ getSymbol: noop,
106
+ parallelArrays: ['x', 'y', 'value', 'colorValue'],
107
+ colorKey: 'colorValue', // Point color option key
108
+ translateColors: seriesTypes.heatmap && seriesTypes.heatmap.prototype.translateColors
109
+ };
110
+
111
+ // The Treemap series type
112
+ seriesTypes.treemap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
113
+ type: 'treemap',
114
+ trackerGroups: ['group', 'dataLabelsGroup'],
115
+ pointClass: extendClass(H.Point, {
116
+ setVisible: seriesTypes.pie.prototype.pointClass.prototype.setVisible
117
+ }),
118
+ /**
119
+ * Creates an object map from parent id to childrens index.
120
+ * @param {Array} data List of points set in options.
121
+ * @param {string} data[].parent Parent id of point.
122
+ * @param {Array} ids List of all point ids.
123
+ * @return {Object} Map from parent id to children index in data.
124
+ */
125
+ getListOfParents: function (data, ids) {
126
+ var listOfParents = reduce(data, function (prev, curr, i) {
127
+ var parent = pick(curr.parent, '');
128
+ if (prev[parent] === undefined) {
129
+ prev[parent] = [];
130
+ }
131
+ prev[parent].push(i);
132
+ return prev;
133
+ }, {});
134
+
135
+ // If parent does not exist, hoist parent to root of tree.
136
+ eachObject(listOfParents, function (children, parent, list) {
137
+ if ((parent !== '') && (H.inArray(parent, ids) === -1)) {
138
+ each(children, function (child) {
139
+ list[''].push(child);
140
+ });
141
+ delete list[parent];
142
+ }
143
+ });
144
+ return listOfParents;
145
+ },
146
+ /**
147
+ * Creates a tree structured object from the series points
148
+ */
149
+ getTree: function () {
150
+ var tree,
151
+ series = this,
152
+ allIds = map(this.data, function (d) {
153
+ return d.id;
154
+ }),
155
+ parentList = series.getListOfParents(this.data, allIds);
156
+
157
+ series.nodeMap = [];
158
+ tree = series.buildNode('', -1, 0, parentList, null);
159
+ recursive(this.nodeMap[this.rootNode], function (node) {
160
+ var next = false,
161
+ p = node.parent;
162
+ node.visible = true;
163
+ if (p || p === '') {
164
+ next = series.nodeMap[p];
165
+ }
166
+ return next;
167
+ });
168
+ recursive(this.nodeMap[this.rootNode].children, function (children) {
169
+ var next = false;
170
+ each(children, function (child) {
171
+ child.visible = true;
172
+ if (child.children.length) {
173
+ next = (next || []).concat(child.children);
174
+ }
175
+ });
176
+ return next;
177
+ });
178
+ this.setTreeValues(tree);
179
+ return tree;
180
+ },
181
+ init: function (chart, options) {
182
+ var series = this;
183
+ Series.prototype.init.call(series, chart, options);
184
+ if (series.options.allowDrillToNode) {
185
+ series.drillTo();
186
+ }
187
+ },
188
+ buildNode: function (id, i, level, list, parent) {
189
+ var series = this,
190
+ children = [],
191
+ point = series.points[i],
192
+ node,
193
+ child;
194
+
195
+ // Actions
196
+ each((list[id] || []), function (i) {
197
+ child = series.buildNode(series.points[i].id, i, (level + 1), list, id);
198
+ children.push(child);
199
+ });
200
+ node = {
201
+ id: id,
202
+ i: i,
203
+ children: children,
204
+ level: level,
205
+ parent: parent,
206
+ visible: false // @todo move this to better location
207
+ };
208
+ series.nodeMap[node.id] = node;
209
+ if (point) {
210
+ point.node = node;
211
+ }
212
+ return node;
213
+ },
214
+ setTreeValues: function (tree) {
215
+ var series = this,
216
+ options = series.options,
217
+ childrenTotal = 0,
218
+ children = [],
219
+ val,
220
+ point = series.points[tree.i];
221
+
222
+ // First give the children some values
223
+ each(tree.children, function (child) {
224
+ child = series.setTreeValues(child);
225
+ children.push(child);
226
+
227
+ if (!child.ignore) {
228
+ childrenTotal += child.val;
229
+ } else {
230
+ // @todo Add predicate to avoid looping already ignored children
231
+ recursive(child.children, function (children) {
232
+ var next = false;
233
+ each(children, function (node) {
234
+ extend(node, {
235
+ ignore: true,
236
+ isLeaf: false,
237
+ visible: false
238
+ });
239
+ if (node.children.length) {
240
+ next = (next || []).concat(node.children);
241
+ }
242
+ });
243
+ return next;
244
+ });
245
+ }
246
+ });
247
+ // Sort the children
248
+ stableSort(children, function (a, b) {
249
+ return a.sortIndex - b.sortIndex;
250
+ });
251
+ // Set the values
252
+ val = pick(point && point.value, childrenTotal);
253
+ extend(tree, {
254
+ children: children,
255
+ childrenTotal: childrenTotal,
256
+ // Ignore this node if point is not visible
257
+ ignore: !(pick(point && point.visible, true) && (val > 0)),
258
+ isLeaf: tree.visible && !childrenTotal,
259
+ levelDynamic: (options.levelIsConstant ? tree.level : (tree.level - series.nodeMap[series.rootNode].level)),
260
+ name: pick(point && point.name, ''),
261
+ sortIndex: pick(point && point.sortIndex, -val),
262
+ val: val
263
+ });
264
+ return tree;
265
+ },
266
+ /**
267
+ * Recursive function which calculates the area for all children of a node.
268
+ * @param {Object} node The node which is parent to the children.
269
+ * @param {Object} area The rectangular area of the parent.
270
+ */
271
+ calculateChildrenAreas: function (parent, area) {
272
+ var series = this,
273
+ options = series.options,
274
+ level = this.levelMap[parent.levelDynamic + 1],
275
+ algorithm = pick((series[level && level.layoutAlgorithm] && level.layoutAlgorithm), options.layoutAlgorithm),
276
+ alternate = options.alternateStartingDirection,
277
+ childrenValues = [],
278
+ children;
279
+
280
+ // Collect all children which should be included
281
+ children = grep(parent.children, function (n) {
282
+ return !n.ignore;
283
+ });
284
+
285
+ if (level && level.layoutStartingDirection) {
286
+ area.direction = level.layoutStartingDirection === 'vertical' ? 0 : 1;
287
+ }
288
+ childrenValues = series[algorithm](area, children);
289
+ each(children, function (child, index) {
290
+ var values = childrenValues[index];
291
+ child.values = merge(values, {
292
+ val: child.childrenTotal,
293
+ direction: (alternate ? 1 - area.direction : area.direction)
294
+ });
295
+ child.pointValues = merge(values, {
296
+ x: (values.x / series.axisRatio),
297
+ width: (values.width / series.axisRatio)
298
+ });
299
+ // If node has children, then call method recursively
300
+ if (child.children.length) {
301
+ series.calculateChildrenAreas(child, child.values);
302
+ }
303
+ });
304
+ },
305
+ setPointValues: function () {
306
+ var series = this,
307
+ xAxis = series.xAxis,
308
+ yAxis = series.yAxis;
309
+ each(series.points, function (point) {
310
+ var node = point.node,
311
+ values = node.pointValues,
312
+ x1,
313
+ x2,
314
+ y1,
315
+ y2;
316
+ // Points which is ignored, have no values.
317
+ if (values) {
318
+ x1 = Math.round(xAxis.translate(values.x, 0, 0, 0, 1));
319
+ x2 = Math.round(xAxis.translate(values.x + values.width, 0, 0, 0, 1));
320
+ y1 = Math.round(yAxis.translate(values.y, 0, 0, 0, 1));
321
+ y2 = Math.round(yAxis.translate(values.y + values.height, 0, 0, 0, 1));
322
+ // Set point values
323
+ point.shapeType = 'rect';
324
+ point.shapeArgs = {
325
+ x: Math.min(x1, x2),
326
+ y: Math.min(y1, y2),
327
+ width: Math.abs(x2 - x1),
328
+ height: Math.abs(y2 - y1)
329
+ };
330
+ point.plotX = point.shapeArgs.x + (point.shapeArgs.width / 2);
331
+ point.plotY = point.shapeArgs.y + (point.shapeArgs.height / 2);
332
+ } else {
333
+ // Reset visibility
334
+ delete point.plotX;
335
+ delete point.plotY;
336
+ }
337
+ });
338
+ },
339
+ setColorRecursive: function (node, color) {
340
+ var series = this,
341
+ point,
342
+ level;
343
+ if (node) {
344
+ point = series.points[node.i];
345
+ level = series.levelMap[node.levelDynamic];
346
+ // Select either point color, level color or inherited color.
347
+ color = pick(point && point.options.color, level && level.color, color);
348
+ if (point) {
349
+ point.color = color;
350
+ }
351
+ // Do it all again with the children
352
+ if (node.children.length) {
353
+ each(node.children, function (child) {
354
+ series.setColorRecursive(child, color);
355
+ });
356
+ }
357
+ }
358
+ },
359
+ algorithmGroup: function (h, w, d, p) {
360
+ this.height = h;
361
+ this.width = w;
362
+ this.plot = p;
363
+ this.direction = d;
364
+ this.startDirection = d;
365
+ this.total = 0;
366
+ this.nW = 0;
367
+ this.lW = 0;
368
+ this.nH = 0;
369
+ this.lH = 0;
370
+ this.elArr = [];
371
+ this.lP = {
372
+ total: 0,
373
+ lH: 0,
374
+ nH: 0,
375
+ lW: 0,
376
+ nW: 0,
377
+ nR: 0,
378
+ lR: 0,
379
+ aspectRatio: function (w, h) {
380
+ return Math.max((w / h), (h / w));
381
+ }
382
+ };
383
+ this.addElement = function (el) {
384
+ this.lP.total = this.elArr[this.elArr.length - 1];
385
+ this.total = this.total + el;
386
+ if (this.direction === 0) {
387
+ // Calculate last point old aspect ratio
388
+ this.lW = this.nW;
389
+ this.lP.lH = this.lP.total / this.lW;
390
+ this.lP.lR = this.lP.aspectRatio(this.lW, this.lP.lH);
391
+ // Calculate last point new aspect ratio
392
+ this.nW = this.total / this.height;
393
+ this.lP.nH = this.lP.total / this.nW;
394
+ this.lP.nR = this.lP.aspectRatio(this.nW, this.lP.nH);
395
+ } else {
396
+ // Calculate last point old aspect ratio
397
+ this.lH = this.nH;
398
+ this.lP.lW = this.lP.total / this.lH;
399
+ this.lP.lR = this.lP.aspectRatio(this.lP.lW, this.lH);
400
+ // Calculate last point new aspect ratio
401
+ this.nH = this.total / this.width;
402
+ this.lP.nW = this.lP.total / this.nH;
403
+ this.lP.nR = this.lP.aspectRatio(this.lP.nW, this.nH);
404
+ }
405
+ this.elArr.push(el);
406
+ };
407
+ this.reset = function () {
408
+ this.nW = 0;
409
+ this.lW = 0;
410
+ this.elArr = [];
411
+ this.total = 0;
412
+ };
413
+ },
414
+ algorithmCalcPoints: function (directionChange, last, group, childrenArea) {
415
+ var pX,
416
+ pY,
417
+ pW,
418
+ pH,
419
+ gW = group.lW,
420
+ gH = group.lH,
421
+ plot = group.plot,
422
+ keep,
423
+ i = 0,
424
+ end = group.elArr.length - 1;
425
+ if (last) {
426
+ gW = group.nW;
427
+ gH = group.nH;
428
+ } else {
429
+ keep = group.elArr[group.elArr.length - 1];
430
+ }
431
+ each(group.elArr, function (p) {
432
+ if (last || (i < end)) {
433
+ if (group.direction === 0) {
434
+ pX = plot.x;
435
+ pY = plot.y;
436
+ pW = gW;
437
+ pH = p / pW;
438
+ } else {
439
+ pX = plot.x;
440
+ pY = plot.y;
441
+ pH = gH;
442
+ pW = p / pH;
443
+ }
444
+ childrenArea.push({
445
+ x: pX,
446
+ y: pY,
447
+ width: pW,
448
+ height: pH
449
+ });
450
+ if (group.direction === 0) {
451
+ plot.y = plot.y + pH;
452
+ } else {
453
+ plot.x = plot.x + pW;
454
+ }
455
+ }
456
+ i = i + 1;
457
+ });
458
+ // Reset variables
459
+ group.reset();
460
+ if (group.direction === 0) {
461
+ group.width = group.width - gW;
462
+ } else {
463
+ group.height = group.height - gH;
464
+ }
465
+ plot.y = plot.parent.y + (plot.parent.height - group.height);
466
+ plot.x = plot.parent.x + (plot.parent.width - group.width);
467
+ if (directionChange) {
468
+ group.direction = 1 - group.direction;
469
+ }
470
+ // If not last, then add uncalculated element
471
+ if (!last) {
472
+ group.addElement(keep);
473
+ }
474
+ },
475
+ algorithmLowAspectRatio: function (directionChange, parent, children) {
476
+ var childrenArea = [],
477
+ series = this,
478
+ pTot,
479
+ plot = {
480
+ x: parent.x,
481
+ y: parent.y,
482
+ parent: parent
483
+ },
484
+ direction = parent.direction,
485
+ i = 0,
486
+ end = children.length - 1,
487
+ group = new this.algorithmGroup(parent.height, parent.width, direction, plot);
488
+ // Loop through and calculate all areas
489
+ each(children, function (child) {
490
+ pTot = (parent.width * parent.height) * (child.val / parent.val);
491
+ group.addElement(pTot);
492
+ if (group.lP.nR > group.lP.lR) {
493
+ series.algorithmCalcPoints(directionChange, false, group, childrenArea, plot);
494
+ }
495
+ // If last child, then calculate all remaining areas
496
+ if (i === end) {
497
+ series.algorithmCalcPoints(directionChange, true, group, childrenArea, plot);
498
+ }
499
+ i = i + 1;
500
+ });
501
+ return childrenArea;
502
+ },
503
+ algorithmFill: function (directionChange, parent, children) {
504
+ var childrenArea = [],
505
+ pTot,
506
+ direction = parent.direction,
507
+ x = parent.x,
508
+ y = parent.y,
509
+ width = parent.width,
510
+ height = parent.height,
511
+ pX,
512
+ pY,
513
+ pW,
514
+ pH;
515
+ each(children, function (child) {
516
+ pTot = (parent.width * parent.height) * (child.val / parent.val);
517
+ pX = x;
518
+ pY = y;
519
+ if (direction === 0) {
520
+ pH = height;
521
+ pW = pTot / pH;
522
+ width = width - pW;
523
+ x = x + pW;
524
+ } else {
525
+ pW = width;
526
+ pH = pTot / pW;
527
+ height = height - pH;
528
+ y = y + pH;
529
+ }
530
+ childrenArea.push({
531
+ x: pX,
532
+ y: pY,
533
+ width: pW,
534
+ height: pH
535
+ });
536
+ if (directionChange) {
537
+ direction = 1 - direction;
538
+ }
539
+ });
540
+ return childrenArea;
541
+ },
542
+ strip: function (parent, children) {
543
+ return this.algorithmLowAspectRatio(false, parent, children);
544
+ },
545
+ squarified: function (parent, children) {
546
+ return this.algorithmLowAspectRatio(true, parent, children);
547
+ },
548
+ sliceAndDice: function (parent, children) {
549
+ return this.algorithmFill(true, parent, children);
550
+ },
551
+ stripes: function (parent, children) {
552
+ return this.algorithmFill(false, parent, children);
553
+ },
554
+ translate: function () {
555
+ var pointValues,
556
+ seriesArea,
557
+ tree,
558
+ val;
559
+
560
+ // Call prototype function
561
+ Series.prototype.translate.call(this);
562
+
563
+ // Assign variables
564
+ this.rootNode = pick(this.options.rootId, '');
565
+ // Create a object map from level to options
566
+ this.levelMap = reduce(this.options.levels, function (arr, item) {
567
+ arr[item.level] = item;
568
+ return arr;
569
+ }, {});
570
+ tree = this.tree = this.getTree(); // @todo Only if series.isDirtyData is true
571
+
572
+ // Calculate plotting values.
573
+ this.axisRatio = (this.xAxis.len / this.yAxis.len);
574
+ this.nodeMap[''].pointValues = pointValues = { x: 0, y: 0, width: 100, height: 100 };
575
+ this.nodeMap[''].values = seriesArea = merge(pointValues, {
576
+ width: (pointValues.width * this.axisRatio),
577
+ direction: (this.options.layoutStartingDirection === 'vertical' ? 0 : 1),
578
+ val: tree.val
579
+ });
580
+ this.calculateChildrenAreas(tree, seriesArea);
581
+
582
+ // Logic for point colors
583
+ if (this.colorAxis) {
584
+ this.translateColors();
585
+ } else if (!this.options.colorByPoint) {
586
+ this.setColorRecursive(this.tree, undefined);
587
+ }
588
+
589
+ // Update axis extremes according to the root node.
590
+ val = this.nodeMap[this.rootNode].pointValues;
591
+ this.xAxis.setExtremes(val.x, val.x + val.width, false);
592
+ this.yAxis.setExtremes(val.y, val.y + val.height, false);
593
+ this.xAxis.setScale();
594
+ this.yAxis.setScale();
595
+
596
+ // Assign values to points.
597
+ this.setPointValues();
598
+ },
599
+ /**
600
+ * Extend drawDataLabels with logic to handle custom options related to the treemap series:
601
+ * - Points which is not a leaf node, has dataLabels disabled by default.
602
+ * - Options set on series.levels is merged in.
603
+ * - Width of the dataLabel is set to match the width of the point shape.
604
+ */
605
+ drawDataLabels: function () {
606
+ var series = this,
607
+ points = grep(series.points, function (n) {
608
+ return n.node.visible;
609
+ }),
610
+ options,
611
+ level;
612
+ each(points, function (point) {
613
+ level = series.levelMap[point.node.levelDynamic];
614
+ // Set options to new object to avoid problems with scope
615
+ options = { style: {} };
616
+
617
+ // If not a leaf, then label should be disabled as default
618
+ if (!point.node.isLeaf) {
619
+ options.enabled = false;
620
+ }
621
+
622
+ // If options for level exists, include them as well
623
+ if (level && level.dataLabels) {
624
+ options = merge(options, level.dataLabels);
625
+ series._hasPointLabels = true;
626
+ }
627
+
628
+ // Set dataLabel width to the width of the point shape.
629
+ if (point.shapeArgs) {
630
+ options.style.width = point.shapeArgs.width;
631
+ }
632
+
633
+ // Merge custom options with point options
634
+ point.dlOptions = merge(options, point.options.dataLabels);
635
+ });
636
+ Series.prototype.drawDataLabels.call(this);
637
+ },
638
+ alignDataLabel: seriesTypes.column.prototype.alignDataLabel,
639
+
640
+ /**
641
+ * Get presentational attributes
642
+ */
643
+ pointAttribs: function (point, state) {
644
+ var level = this.levelMap[point.node.levelDynamic] || {},
645
+ options = this.options,
646
+ attr,
647
+ stateOptions = (state && options.states[state]) || {};
648
+
649
+ // Set attributes by precedence. Point trumps level trumps series. Stroke width uses pick
650
+ // because it can be 0.
651
+ attr = {
652
+ 'stroke': point.borderColor || level.borderColor || stateOptions.borderColor || options.borderColor,
653
+ 'stroke-width': pick(point.borderWidth, level.borderWidth, stateOptions.borderWidth, options.borderWidth),
654
+ 'dashstyle': point.borderDashStyle || level.borderDashStyle || stateOptions.borderDashStyle || options.borderDashStyle,
655
+ 'fill': point.color || this.color,
656
+ 'zIndex': state === 'hover' ? 1 : 0
657
+ };
658
+
659
+ if (point.node.level <= this.nodeMap[this.rootNode].level) {
660
+ // Hide levels above the current view
661
+ attr.fill = 'none';
662
+ attr['stroke-width'] = 0;
663
+ } else if (!point.node.isLeaf) {
664
+ // If not a leaf, then remove fill
665
+ // @todo let users set the opacity
666
+ attr.fill = pick(options.interactByLeaf, !options.allowDrillToNode) ? 'none' : Color(attr.fill).setOpacity(state === 'hover' ? 0.75 : 0.15).get();
667
+ } else if (state) {
668
+ // Brighten and hoist the hover nodes
669
+ attr.fill = Color(attr.fill).brighten(stateOptions.brightness).get();
670
+ }
671
+
672
+ return attr;
673
+ },
674
+
675
+ /**
676
+ * Extending ColumnSeries drawPoints
677
+ */
678
+ drawPoints: function () {
679
+ var series = this,
680
+ points = grep(series.points, function (n) {
681
+ return n.node.visible;
682
+ });
683
+
684
+ each(points, function (point) {
685
+ var groupKey = 'levelGroup-' + point.node.levelDynamic;
686
+ if (!series[groupKey]) {
687
+ series[groupKey] = series.chart.renderer.g(groupKey)
688
+ .attr({
689
+ zIndex: 1000 - point.node.levelDynamic // @todo Set the zIndex based upon the number of levels, instead of using 1000
690
+ })
691
+ .add(series.group);
692
+ }
693
+ point.group = series[groupKey];
694
+ // Preliminary code in prepraration for HC5 that uses pointAttribs for all series
695
+ point.pointAttr = {
696
+ '': series.pointAttribs(point),
697
+ 'hover': series.pointAttribs(point, 'hover'),
698
+ 'select': {}
699
+ };
700
+ });
701
+ // Call standard drawPoints
702
+ seriesTypes.column.prototype.drawPoints.call(this);
703
+
704
+ // If drillToNode is allowed, set a point cursor on clickables & add drillId to point
705
+ if (series.options.allowDrillToNode) {
706
+ each(points, function (point) {
707
+ var cursor,
708
+ drillId;
709
+ if (point.graphic) {
710
+ drillId = point.drillId = series.options.interactByLeaf ? series.drillToByLeaf(point) : series.drillToByGroup(point);
711
+ cursor = drillId ? 'pointer' : 'default';
712
+ point.graphic.css({ cursor: cursor });
713
+ }
714
+ });
715
+ }
716
+ },
717
+ /**
718
+ * Add drilling on the suitable points
719
+ */
720
+ drillTo: function () {
721
+ var series = this;
722
+ H.addEvent(series, 'click', function (event) {
723
+ var point = event.point,
724
+ drillId = point.drillId,
725
+ drillName;
726
+ // If a drill id is returned, add click event and cursor.
727
+ if (drillId) {
728
+ drillName = series.nodeMap[series.rootNode].name || series.rootNode;
729
+ point.setState(''); // Remove hover
730
+ series.drillToNode(drillId);
731
+ series.showDrillUpButton(drillName);
732
+ }
733
+ });
734
+ },
735
+ /**
736
+ * Finds the drill id for a parent node.
737
+ * Returns false if point should not have a click event
738
+ * @param {Object} point
739
+ * @return {string || boolean} Drill to id or false when point should not have a click event
740
+ */
741
+ drillToByGroup: function (point) {
742
+ var series = this,
743
+ drillId = false;
744
+ if ((point.node.level - series.nodeMap[series.rootNode].level) === 1 && !point.node.isLeaf) {
745
+ drillId = point.id;
746
+ }
747
+ return drillId;
748
+ },
749
+ /**
750
+ * Finds the drill id for a leaf node.
751
+ * Returns false if point should not have a click event
752
+ * @param {Object} point
753
+ * @return {string || boolean} Drill to id or false when point should not have a click event
754
+ */
755
+ drillToByLeaf: function (point) {
756
+ var series = this,
757
+ drillId = false,
758
+ nodeParent;
759
+ if ((point.node.parent !== series.rootNode) && (point.node.isLeaf)) {
760
+ nodeParent = point.node;
761
+ while (!drillId) {
762
+ nodeParent = series.nodeMap[nodeParent.parent];
763
+ if (nodeParent.parent === series.rootNode) {
764
+ drillId = nodeParent.id;
765
+ }
766
+ }
767
+ }
768
+ return drillId;
769
+ },
770
+ drillUp: function () {
771
+ var drillPoint = null,
772
+ node,
773
+ parent;
774
+ if (this.rootNode) {
775
+ node = this.nodeMap[this.rootNode];
776
+ if (node.parent !== null) {
777
+ drillPoint = this.nodeMap[node.parent];
778
+ } else {
779
+ drillPoint = this.nodeMap[''];
780
+ }
781
+ }
782
+
783
+ if (drillPoint !== null) {
784
+ this.drillToNode(drillPoint.id);
785
+ if (drillPoint.id === '') {
786
+ this.drillUpButton = this.drillUpButton.destroy();
787
+ } else {
788
+ parent = this.nodeMap[drillPoint.parent];
789
+ this.showDrillUpButton((parent.name || parent.id));
790
+ }
791
+ }
792
+ },
793
+ drillToNode: function (id) {
794
+ this.options.rootId = id;
795
+ this.isDirty = true; // Force redraw
796
+ this.chart.redraw();
797
+ },
798
+ showDrillUpButton: function (name) {
799
+ var series = this,
800
+ backText = (name || '< Back'),
801
+ buttonOptions = series.options.drillUpButton,
802
+ attr,
803
+ states;
804
+
805
+ if (buttonOptions.text) {
806
+ backText = buttonOptions.text;
807
+ }
808
+ if (!this.drillUpButton) {
809
+ attr = buttonOptions.theme;
810
+ states = attr && attr.states;
811
+
812
+ this.drillUpButton = this.chart.renderer.button(
813
+ backText,
814
+ null,
815
+ null,
816
+ function () {
817
+ series.drillUp();
818
+ },
819
+ attr,
820
+ states && states.hover,
821
+ states && states.select
822
+ )
823
+ .attr({
824
+ align: buttonOptions.position.align,
825
+ zIndex: 9
826
+ })
827
+ .add()
828
+ .align(buttonOptions.position, false, buttonOptions.relativeTo || 'plotBox');
829
+ } else {
830
+ this.drillUpButton.attr({
831
+ text: backText
832
+ })
833
+ .align();
834
+ }
835
+ },
836
+ buildKDTree: noop,
837
+ drawLegendSymbol: H.LegendSymbolMixin.drawRectangle,
838
+ getExtremes: function () {
839
+ // Get the extremes from the value data
840
+ Series.prototype.getExtremes.call(this, this.colorValueData);
841
+ this.valueMin = this.dataMin;
842
+ this.valueMax = this.dataMax;
843
+
844
+ // Get the extremes from the y data
845
+ Series.prototype.getExtremes.call(this);
846
+ },
847
+ getExtremesFromAll: true,
848
+ bindAxes: function () {
849
+ var treeAxis = {
850
+ endOnTick: false,
851
+ gridLineWidth: 0,
852
+ lineWidth: 0,
853
+ min: 0,
854
+ dataMin: 0,
855
+ minPadding: 0,
856
+ max: 100,
857
+ dataMax: 100,
858
+ maxPadding: 0,
859
+ startOnTick: false,
860
+ title: null,
861
+ tickPositions: []
862
+ };
863
+ Series.prototype.bindAxes.call(this);
864
+ H.extend(this.yAxis.options, treeAxis);
865
+ H.extend(this.xAxis.options, treeAxis);
866
+ }
867
+ }));
868
+ }));