highstock-rails 1.3.10 → 2.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }));