highcharts-rails 4.1.8 → 4.1.9
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.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +51 -0
- data/app/assets/javascripts/highcharts.js +340 -178
- data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +15 -8
- data/app/assets/javascripts/highcharts/highcharts-3d.js +78 -35
- data/app/assets/javascripts/highcharts/highcharts-more.js +43 -19
- data/app/assets/javascripts/highcharts/modules/boost.js +4 -4
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +1 -5
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/app/assets/javascripts/highcharts/modules/data.js +1 -1
- data/app/assets/javascripts/highcharts/modules/exporting.js +4 -3
- data/app/assets/javascripts/highcharts/modules/heatmap.js +18 -12
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +3 -2
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +1 -1
- data/app/assets/javascripts/highcharts/modules/treemap.js +227 -236
- data/lib/highcharts/version.rb +1 -1
- metadata +2 -2
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.9 (2015-10-07)
|
3
3
|
* Exporting module
|
4
4
|
*
|
5
5
|
* (c) 2010-2014 Torstein Honsi
|
@@ -293,7 +293,8 @@ extend(Chart.prototype, {
|
|
293
293
|
extend(options.chart, {
|
294
294
|
animation: false,
|
295
295
|
renderTo: sandbox,
|
296
|
-
forExport:
|
296
|
+
forExport: true,
|
297
|
+
renderer: 'SVGRenderer',
|
297
298
|
width: sourceWidth,
|
298
299
|
height: sourceHeight
|
299
300
|
});
|
@@ -353,7 +354,7 @@ extend(Chart.prototype, {
|
|
353
354
|
if (allowHTML) {
|
354
355
|
html = svg.match(/<\/svg>(.*?$)/);
|
355
356
|
if (html) {
|
356
|
-
html = '<foreignObject x="0" y="0 width="200" height="200">' +
|
357
|
+
html = '<foreignObject x="0" y="0" width="200" height="200">' +
|
357
358
|
'<body xmlns="http://www.w3.org/1999/xhtml">' +
|
358
359
|
html[1] +
|
359
360
|
'</body>' +
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.9 (2015-10-07)
|
3
3
|
*
|
4
4
|
* (c) 2011-2014 Torstein Honsi
|
5
5
|
*
|
@@ -256,20 +256,23 @@ extend(ColorAxis.prototype, {
|
|
256
256
|
return color;
|
257
257
|
},
|
258
258
|
|
259
|
+
/**
|
260
|
+
* Override the getOffset method to add the whole axis groups inside the legend.
|
261
|
+
*/
|
259
262
|
getOffset: function () {
|
260
263
|
var group = this.legendGroup,
|
261
264
|
sideOffset = this.chart.axisOffset[this.side];
|
262
265
|
|
263
266
|
if (group) {
|
264
267
|
|
268
|
+
// Hook for the getOffset method to add groups to this parent group
|
269
|
+
this.axisParent = group;
|
270
|
+
|
271
|
+
// Call the base
|
265
272
|
Axis.prototype.getOffset.call(this);
|
266
|
-
|
267
|
-
if (!this.axisGroup.parentGroup) {
|
268
273
|
|
269
|
-
|
270
|
-
|
271
|
-
this.gridGroup.add(group);
|
272
|
-
this.labelGroup.add(group);
|
274
|
+
// First time only
|
275
|
+
if (!this.added) {
|
273
276
|
|
274
277
|
this.added = true;
|
275
278
|
|
@@ -644,17 +647,20 @@ seriesTypes.heatmap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
|
|
644
647
|
var series = this,
|
645
648
|
options = series.options,
|
646
649
|
xAxis = series.xAxis,
|
647
|
-
yAxis = series.yAxis
|
650
|
+
yAxis = series.yAxis,
|
651
|
+
between = function (x, a, b) {
|
652
|
+
return Math.min(Math.max(a, x), b);
|
653
|
+
};
|
648
654
|
|
649
655
|
series.generatePoints();
|
650
656
|
|
651
657
|
each(series.points, function (point) {
|
652
658
|
var xPad = (options.colsize || 1) / 2,
|
653
659
|
yPad = (options.rowsize || 1) / 2,
|
654
|
-
x1 = Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)),
|
655
|
-
x2 = Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)),
|
656
|
-
y1 = Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)),
|
657
|
-
y2 = Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1));
|
660
|
+
x1 = between(Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
661
|
+
x2 = between(Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
662
|
+
y1 = between(Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)), 0, yAxis.len),
|
663
|
+
y2 = between(Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)), 0, yAxis.len);
|
658
664
|
|
659
665
|
// Set plotX and plotY for use in K-D-Tree and more
|
660
666
|
point.plotX = point.clientX = (x1 + x2) / 2;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.9 (2015-10-07)
|
3
3
|
* Client side exporting module
|
4
4
|
*
|
5
5
|
* (c) 2015 Torstein Honsi / Oystein Moseng
|
@@ -85,7 +85,8 @@ Highcharts.Chart.prototype.exportChartLocal = function (exportingOptions, chartO
|
|
85
85
|
svgToDataUrl = function (svg) {
|
86
86
|
try {
|
87
87
|
// Safari requires data URI since it doesn't allow navigation to blob URLs
|
88
|
-
|
88
|
+
// Firefox has an issue with Blobs and internal references, leading to gradients not working using Blobs (#4550)
|
89
|
+
if (!webKit && navigator.userAgent.toLowerCase().indexOf('firefox') < 0) {
|
89
90
|
return domurl.createObjectURL(new Blob([svg], { type: 'image/svg+xml;charset-utf-16'}));
|
90
91
|
}
|
91
92
|
} catch (e) {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.9 (2015-10-07)
|
3
3
|
*
|
4
4
|
* (c) 2014 Highsoft AS
|
5
5
|
* Authors: Jon Arild Nygard / Oystein Moseng
|
@@ -10,6 +10,7 @@
|
|
10
10
|
/*global HighchartsAdapter */
|
11
11
|
(function (H) {
|
12
12
|
var seriesTypes = H.seriesTypes,
|
13
|
+
map = H.map,
|
13
14
|
merge = H.merge,
|
14
15
|
extend = H.extend,
|
15
16
|
extendClass = H.extendClass,
|
@@ -20,7 +21,33 @@
|
|
20
21
|
grep = HighchartsAdapter.grep,
|
21
22
|
pick = H.pick,
|
22
23
|
Series = H.Series,
|
23
|
-
Color = H.Color
|
24
|
+
Color = H.Color,
|
25
|
+
eachObject = function (list, func, context) {
|
26
|
+
var key;
|
27
|
+
context = context || this;
|
28
|
+
for (key in list) {
|
29
|
+
if (list.hasOwnProperty(key)) {
|
30
|
+
func.call(context, list[key], key, list);
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
reduce = function (arr, func, previous, context) {
|
35
|
+
context = context || this;
|
36
|
+
arr = arr || []; // @note should each be able to handle empty values automatically?
|
37
|
+
each(arr, function (current, i) {
|
38
|
+
previous = func.call(context, previous, current, i, arr);
|
39
|
+
});
|
40
|
+
return previous;
|
41
|
+
},
|
42
|
+
// @todo find correct name for this function.
|
43
|
+
recursive = function (item, func, context) {
|
44
|
+
var next;
|
45
|
+
context = context || this;
|
46
|
+
next = func.call(context, item);
|
47
|
+
if (next !== false) {
|
48
|
+
recursive(next, func, context);
|
49
|
+
}
|
50
|
+
};
|
24
51
|
|
25
52
|
// Define default options
|
26
53
|
plotOptions.treemap = merge(plotOptions.scatter, {
|
@@ -64,12 +91,7 @@
|
|
64
91
|
// Stolen from heatmap
|
65
92
|
var colorSeriesMixin = {
|
66
93
|
// mapping between SVG attributes and the corresponding options
|
67
|
-
pointAttrToOptions: {
|
68
|
-
stroke: 'borderColor',
|
69
|
-
'stroke-width': 'borderWidth',
|
70
|
-
fill: 'color',
|
71
|
-
dashstyle: 'borderDashStyle'
|
72
|
-
},
|
94
|
+
pointAttrToOptions: {},
|
73
95
|
pointArrayMap: ['value'],
|
74
96
|
axisTypes: seriesTypes.heatmap ? ['xAxis', 'yAxis', 'colorAxis'] : ['xAxis', 'yAxis'],
|
75
97
|
optionalAxis: 'colorAxis',
|
@@ -84,33 +106,35 @@
|
|
84
106
|
type: 'treemap',
|
85
107
|
trackerGroups: ['group', 'dataLabelsGroup'],
|
86
108
|
pointClass: extendClass(H.Point, {
|
87
|
-
setState: function (state, move) {
|
88
|
-
H.Point.prototype.setState.call(this, state, move);
|
89
|
-
if (state === 'hover') {
|
90
|
-
if (this.dataLabel) {
|
91
|
-
this.dataLabel.attr({ zIndex: 1002 });
|
92
|
-
}
|
93
|
-
} else {
|
94
|
-
if (this.dataLabel) {
|
95
|
-
this.dataLabel.attr({ zIndex: (this.pointAttr[''].zIndex + 1) });
|
96
|
-
}
|
97
|
-
}
|
98
|
-
},
|
99
109
|
setVisible: seriesTypes.pie.prototype.pointClass.prototype.setVisible
|
100
110
|
}),
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
/**
|
112
|
+
* Creates an object map from parent id to childrens index.
|
113
|
+
* @param {Array} data List of points set in options.
|
114
|
+
* @param {string} data[].parent Parent id of point.
|
115
|
+
* @param {Array} ids List of all point ids.
|
116
|
+
* @return {Object} Map from parent id to children index in data.
|
117
|
+
*/
|
118
|
+
getListOfParents: function (data, ids) {
|
119
|
+
var listOfParents = reduce(data, function (prev, curr, i) {
|
120
|
+
var parent = pick(curr.parent, "");
|
121
|
+
if (prev[parent] === undefined) {
|
122
|
+
prev[parent] = [];
|
123
|
+
}
|
124
|
+
prev[parent].push(i);
|
125
|
+
return prev;
|
126
|
+
}, {});
|
127
|
+
|
128
|
+
// If parent does not exist, hoist parent to root of tree.
|
129
|
+
eachObject(listOfParents, function (children, parent, list) {
|
130
|
+
if ((parent !== "") && (HighchartsAdapter.inArray(parent, ids) === -1)) {
|
131
|
+
each(children, function (child) {
|
132
|
+
list[""].push(child);
|
133
|
+
});
|
134
|
+
delete list[parent];
|
135
|
+
}
|
136
|
+
});
|
137
|
+
return listOfParents;
|
114
138
|
},
|
115
139
|
/**
|
116
140
|
* Creates a tree structured object from the series points
|
@@ -118,51 +142,42 @@
|
|
118
142
|
getTree: function () {
|
119
143
|
var tree,
|
120
144
|
series = this,
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
});
|
128
|
-
};
|
129
|
-
// Actions
|
130
|
-
this.nodeMap = [];
|
131
|
-
|
132
|
-
// Map children to index
|
133
|
-
// @todo Use data instead of points
|
134
|
-
each(this.points, function (point, index) {
|
135
|
-
var parent = "";
|
136
|
-
allIds.push(point.id);
|
137
|
-
if (point.parent !== undefined) {
|
138
|
-
parent = point.parent;
|
139
|
-
}
|
140
|
-
if (parentList[parent] === undefined) {
|
141
|
-
parentList[parent] = [];
|
142
|
-
}
|
143
|
-
parentList[parent].push(index);
|
144
|
-
});
|
145
|
-
/*
|
146
|
-
* Quality check:
|
147
|
-
* - If parent does not exist, then set parent to tree root
|
148
|
-
* - Add node id to parents children list
|
149
|
-
*/
|
150
|
-
for (key in parentList) {
|
151
|
-
if ((parentList.hasOwnProperty(key)) && (key !== "") && (HighchartsAdapter.inArray(key, allIds) === -1)) {
|
152
|
-
insertItem(key);
|
153
|
-
delete parentList[key];
|
154
|
-
}
|
155
|
-
}
|
145
|
+
allIds = map(this.data, function (d) {
|
146
|
+
return d.id;
|
147
|
+
}),
|
148
|
+
parentList = series.getListOfParents(this.data, allIds);
|
149
|
+
|
150
|
+
series.nodeMap = [];
|
156
151
|
tree = series.buildNode("", -1, 0, parentList, null);
|
157
|
-
|
152
|
+
recursive(this.nodeMap[this.rootNode], function (node) {
|
153
|
+
var next = false,
|
154
|
+
p = node.parent;
|
158
155
|
node.visible = true;
|
156
|
+
if (p || p === "") {
|
157
|
+
next = series.nodeMap[p];
|
158
|
+
}
|
159
|
+
return next;
|
159
160
|
});
|
160
|
-
|
161
|
-
|
161
|
+
recursive(this.nodeMap[this.rootNode].children, function (children) {
|
162
|
+
var next = false;
|
163
|
+
each(children, function (child) {
|
164
|
+
child.visible = true;
|
165
|
+
if (child.children.length) {
|
166
|
+
next = (next || []).concat(child.children);
|
167
|
+
}
|
168
|
+
});
|
169
|
+
return next;
|
162
170
|
});
|
163
171
|
this.setTreeValues(tree);
|
164
172
|
return tree;
|
165
173
|
},
|
174
|
+
init: function (chart, options) {
|
175
|
+
var series = this;
|
176
|
+
Series.prototype.init.call(series, chart, options);
|
177
|
+
if (series.options.allowDrillToNode) {
|
178
|
+
series.drillTo();
|
179
|
+
}
|
180
|
+
},
|
166
181
|
buildNode: function (id, i, level, list, parent) {
|
167
182
|
var series = this,
|
168
183
|
children = [],
|
@@ -191,6 +206,7 @@
|
|
191
206
|
},
|
192
207
|
setTreeValues: function (tree) {
|
193
208
|
var series = this,
|
209
|
+
options = series.options,
|
194
210
|
childrenTotal = 0,
|
195
211
|
sorted = [],
|
196
212
|
val,
|
@@ -207,12 +223,19 @@
|
|
207
223
|
childrenTotal += child.val;
|
208
224
|
} else {
|
209
225
|
// @todo Add predicate to avoid looping already ignored children
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
226
|
+
recursive(child.children, function (children) {
|
227
|
+
var next = false;
|
228
|
+
each(children, function (node) {
|
229
|
+
extend(node, {
|
230
|
+
ignore: true,
|
231
|
+
isLeaf: false,
|
232
|
+
visible: false
|
233
|
+
});
|
234
|
+
if (node.children.length) {
|
235
|
+
next = (next || []).concat(node.children);
|
236
|
+
}
|
215
237
|
});
|
238
|
+
return next;
|
216
239
|
});
|
217
240
|
}
|
218
241
|
});
|
@@ -225,28 +248,12 @@
|
|
225
248
|
// Ignore this node if point is not visible
|
226
249
|
ignore: !(pick(point && point.visible, true) && (val > 0)),
|
227
250
|
isLeaf: tree.visible && !childrenTotal,
|
251
|
+
levelDynamic: (options.levelIsConstant ? tree.level : (tree.level - series.nodeMap[series.rootNode].level)),
|
228
252
|
name: pick(point && point.name, ""),
|
229
253
|
val: val
|
230
254
|
});
|
231
255
|
return tree;
|
232
256
|
},
|
233
|
-
eachChildren: function (node, callback) {
|
234
|
-
var series = this,
|
235
|
-
children = node.children;
|
236
|
-
callback(node);
|
237
|
-
if (children.length) {
|
238
|
-
each(children, function (child) {
|
239
|
-
series.eachChildren(child, callback);
|
240
|
-
});
|
241
|
-
}
|
242
|
-
},
|
243
|
-
eachParents: function (node, callback) {
|
244
|
-
var parent = this.nodeMap[node.parent];
|
245
|
-
callback(node);
|
246
|
-
if (parent) {
|
247
|
-
this.eachParents(parent, callback);
|
248
|
-
}
|
249
|
-
},
|
250
257
|
/**
|
251
258
|
* Recursive function which calculates the area for all children of a node.
|
252
259
|
* @param {Object} node The node which is parent to the children.
|
@@ -255,13 +262,11 @@
|
|
255
262
|
calculateChildrenAreas: function (parent, area) {
|
256
263
|
var series = this,
|
257
264
|
options = series.options,
|
258
|
-
|
259
|
-
level = this.levelMap[levelNumber + 1],
|
265
|
+
level = this.levelMap[parent.levelDynamic + 1],
|
260
266
|
algorithm = pick((series[level && level.layoutAlgorithm] && level.layoutAlgorithm), options.layoutAlgorithm),
|
261
267
|
alternate = options.alternateStartingDirection,
|
262
268
|
childrenValues = [],
|
263
|
-
children
|
264
|
-
point;
|
269
|
+
children;
|
265
270
|
|
266
271
|
// Collect all children which should be included
|
267
272
|
children = grep(parent.children, function (n) {
|
@@ -273,12 +278,15 @@
|
|
273
278
|
}
|
274
279
|
childrenValues = series[algorithm](area, children);
|
275
280
|
each(children, function (child, index) {
|
276
|
-
|
277
|
-
|
278
|
-
child.values = merge(childrenValues[index], {
|
281
|
+
var values = childrenValues[index];
|
282
|
+
child.values = merge(values, {
|
279
283
|
val: child.childrenTotal,
|
280
284
|
direction: (alternate ? 1 - area.direction : area.direction)
|
281
285
|
});
|
286
|
+
child.pointValues = merge(values, {
|
287
|
+
x: (values.x / series.axisRatio),
|
288
|
+
width: (values.width / series.axisRatio)
|
289
|
+
});
|
282
290
|
// If node has children, then call method recursively
|
283
291
|
if (child.children.length) {
|
284
292
|
series.calculateChildrenAreas(child, child.values);
|
@@ -289,23 +297,15 @@
|
|
289
297
|
var series = this,
|
290
298
|
xAxis = series.xAxis,
|
291
299
|
yAxis = series.yAxis;
|
292
|
-
series.nodeMap[""].values = {
|
293
|
-
x: 0,
|
294
|
-
y: 0,
|
295
|
-
width: 100,
|
296
|
-
height: 100
|
297
|
-
};
|
298
300
|
each(series.points, function (point) {
|
299
301
|
var node = point.node,
|
300
|
-
values = node.
|
302
|
+
values = node.pointValues,
|
301
303
|
x1,
|
302
304
|
x2,
|
303
305
|
y1,
|
304
306
|
y2;
|
305
307
|
// Points which is ignored, have no values.
|
306
308
|
if (values) {
|
307
|
-
values.x = values.x / series.axisRatio;
|
308
|
-
values.width = values.width / series.axisRatio;
|
309
309
|
x1 = Math.round(xAxis.translate(values.x, 0, 0, 0, 1));
|
310
310
|
x2 = Math.round(xAxis.translate(values.x + values.width, 0, 0, 0, 1));
|
311
311
|
y1 = Math.round(yAxis.translate(values.y, 0, 0, 0, 1));
|
@@ -327,43 +327,13 @@
|
|
327
327
|
}
|
328
328
|
});
|
329
329
|
},
|
330
|
-
getSeriesArea: function (val) {
|
331
|
-
var x = 0,
|
332
|
-
y = 0,
|
333
|
-
h = 100,
|
334
|
-
r = this.axisRatio = (this.xAxis.len / this.yAxis.len),
|
335
|
-
w = 100 * r,
|
336
|
-
d = this.options.layoutStartingDirection === 'vertical' ? 0 : 1,
|
337
|
-
seriesArea = {
|
338
|
-
x: x,
|
339
|
-
y: y,
|
340
|
-
width: w,
|
341
|
-
height: h,
|
342
|
-
direction: d,
|
343
|
-
val: val
|
344
|
-
};
|
345
|
-
this.nodeMap[""].values = seriesArea;
|
346
|
-
return seriesArea;
|
347
|
-
},
|
348
|
-
getLevels: function () {
|
349
|
-
var map = [],
|
350
|
-
levels = this.options.levels;
|
351
|
-
if (levels) {
|
352
|
-
each(levels, function (level) {
|
353
|
-
if (level.level !== undefined) {
|
354
|
-
map[level.level] = level;
|
355
|
-
}
|
356
|
-
});
|
357
|
-
}
|
358
|
-
return map;
|
359
|
-
},
|
360
330
|
setColorRecursive: function (node, color) {
|
361
331
|
var series = this,
|
362
332
|
point,
|
363
333
|
level;
|
364
334
|
if (node) {
|
365
335
|
point = series.points[node.i];
|
366
|
-
level = series.levelMap[node.
|
336
|
+
level = series.levelMap[node.levelDynamic];
|
367
337
|
// Select either point color, level color or inherited color.
|
368
338
|
color = pick(point && point.options.color, level && level.color, color);
|
369
339
|
if (point) {
|
@@ -573,16 +543,51 @@
|
|
573
543
|
return this.alg_func_fill(false, parent, children);
|
574
544
|
},
|
575
545
|
translate: function () {
|
546
|
+
var pointValues,
|
547
|
+
seriesArea,
|
548
|
+
tree,
|
549
|
+
val;
|
550
|
+
|
576
551
|
// Call prototype function
|
577
552
|
Series.prototype.translate.call(this);
|
578
|
-
this.handleLayout();
|
579
553
|
|
580
|
-
|
554
|
+
if (this.points.length) {
|
555
|
+
// Assign variables
|
556
|
+
this.rootNode = pick(this.options.rootId, "");
|
557
|
+
// Create a object map from level to options
|
558
|
+
this.levelMap = reduce(this.options.levels, function (arr, item) {
|
559
|
+
arr[item.level] = item;
|
560
|
+
return arr;
|
561
|
+
}, {});
|
562
|
+
tree = this.tree = this.getTree(); // @todo Only if series.isDirtyData is true
|
563
|
+
|
564
|
+
// Calculate plotting values.
|
565
|
+
this.axisRatio = (this.xAxis.len / this.yAxis.len);
|
566
|
+
this.nodeMap[""].pointValues = pointValues = {x: 0, y: 0, width: 100, height: 100 };
|
567
|
+
this.nodeMap[""].values = seriesArea = merge(pointValues, {
|
568
|
+
width: (pointValues.width * this.axisRatio),
|
569
|
+
direction: (this.options.layoutStartingDirection === 'vertical' ? 0 : 1),
|
570
|
+
val: tree.val
|
571
|
+
});
|
572
|
+
this.calculateChildrenAreas(tree, seriesArea);
|
573
|
+
}
|
574
|
+
|
575
|
+
// Logic for point colors
|
581
576
|
if (this.colorAxis) {
|
582
577
|
this.translateColors();
|
583
578
|
} else if (!this.options.colorByPoint) {
|
584
579
|
this.setColorRecursive(this.tree, undefined);
|
585
580
|
}
|
581
|
+
|
582
|
+
// Update axis extremes according to the root node.
|
583
|
+
val = this.nodeMap[this.rootNode].pointValues;
|
584
|
+
this.xAxis.setExtremes(val.x, val.x + val.width, false);
|
585
|
+
this.yAxis.setExtremes(val.y, val.y + val.height, false);
|
586
|
+
this.xAxis.setScale();
|
587
|
+
this.yAxis.setScale();
|
588
|
+
|
589
|
+
// Assign values to points.
|
590
|
+
this.setPointValues();
|
586
591
|
},
|
587
592
|
/**
|
588
593
|
* Extend drawDataLabels with logic to handle custom options related to the treemap series:
|
@@ -592,12 +597,13 @@
|
|
592
597
|
*/
|
593
598
|
drawDataLabels: function () {
|
594
599
|
var series = this,
|
595
|
-
|
596
|
-
|
600
|
+
points = grep(series.points, function (n) {
|
601
|
+
return n.node.visible;
|
602
|
+
}),
|
597
603
|
options,
|
598
604
|
level;
|
599
605
|
each(points, function (point) {
|
600
|
-
level = series.levelMap[point.
|
606
|
+
level = series.levelMap[point.node.levelDynamic];
|
601
607
|
// Set options to new object to avoid problems with scope
|
602
608
|
options = {style: {}};
|
603
609
|
|
@@ -620,82 +626,88 @@
|
|
620
626
|
// Merge custom options with point options
|
621
627
|
point.dlOptions = merge(options, point.options.dataLabels);
|
622
628
|
});
|
623
|
-
|
624
|
-
this.dataLabelsGroup = this.group; // Draw dataLabels in same group as points, because of z-index on hover
|
625
629
|
Series.prototype.drawDataLabels.call(this);
|
626
|
-
this.dataLabelsGroup = dataLabelsGroup;
|
627
630
|
},
|
628
631
|
alignDataLabel: seriesTypes.column.prototype.alignDataLabel,
|
632
|
+
|
633
|
+
/**
|
634
|
+
* Get presentational attributes
|
635
|
+
*/
|
636
|
+
pointAttribs: function (point, state) {
|
637
|
+
var level = this.levelMap[point.node.levelDynamic] || {},
|
638
|
+
options = this.options,
|
639
|
+
attr,
|
640
|
+
stateOptions = (state && options.states[state]) || {};
|
641
|
+
|
642
|
+
// Set attributes by precedence. Point trumps level trumps series. Stroke width uses pick
|
643
|
+
// because it can be 0.
|
644
|
+
attr = {
|
645
|
+
'stroke': point.borderColor || level.borderColor || stateOptions.borderColor || options.borderColor,
|
646
|
+
'stroke-width': pick(point.borderWidth, level.borderWidth, stateOptions.borderWidth, options.borderWidth),
|
647
|
+
'dashstyle': point.borderDashStyle || level.borderDashStyle || stateOptions.borderDashStyle || options.borderDashStyle,
|
648
|
+
'fill': point.color || this.color
|
649
|
+
};
|
650
|
+
|
651
|
+
if (state === 'hover') {
|
652
|
+
attr.zIndex = 1;
|
653
|
+
}
|
654
|
+
|
655
|
+
if (point.node.level <= this.nodeMap[this.rootNode].level) {
|
656
|
+
// Hide levels above the current view
|
657
|
+
attr.fill = 'none';
|
658
|
+
attr["stroke-width"] = 0;
|
659
|
+
} else if (!point.node.isLeaf) {
|
660
|
+
// If not a leaf, then remove fill
|
661
|
+
// @todo let users set the opacity
|
662
|
+
attr.fill = pick(options.interactByLeaf, !options.allowDrillToNode) ? 'none' : Color(attr.fill).setOpacity(state === 'hover' ? 0.75 : 0.15).get();
|
663
|
+
} else if (state) {
|
664
|
+
// Brighten and hoist the hover nodes
|
665
|
+
attr.fill = Color(attr.fill).brighten(stateOptions.brightness).get();
|
666
|
+
}
|
667
|
+
|
668
|
+
return attr;
|
669
|
+
},
|
670
|
+
|
629
671
|
/**
|
630
672
|
* Extending ColumnSeries drawPoints
|
631
673
|
*/
|
632
674
|
drawPoints: function () {
|
633
675
|
var series = this,
|
634
|
-
points = series.points,
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
level;
|
676
|
+
points = grep(series.points, function (n) {
|
677
|
+
return n.node.visible;
|
678
|
+
});
|
679
|
+
|
639
680
|
each(points, function (point) {
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
};
|
648
|
-
// Overwrite standard series options with level options
|
649
|
-
if (level) {
|
650
|
-
attr.stroke = level.borderColor || attr.stroke;
|
651
|
-
attr['stroke-width'] = level.borderWidth || attr['stroke-width'];
|
652
|
-
attr.dashstyle = level.borderDashStyle || attr.dashstyle;
|
653
|
-
}
|
654
|
-
// Merge with point attributes
|
655
|
-
attr.stroke = point.borderColor || attr.stroke;
|
656
|
-
attr['stroke-width'] = point.borderWidth || attr['stroke-width'];
|
657
|
-
attr.dashstyle = point.borderDashStyle || attr.dashstyle;
|
658
|
-
attr.zIndex = (1000 - (point.level * 2));
|
659
|
-
|
660
|
-
// Make a copy to prevent overwriting individual props
|
661
|
-
point.pointAttr = merge(point.pointAttr);
|
662
|
-
hover = point.pointAttr.hover;
|
663
|
-
hover.zIndex = 1001;
|
664
|
-
hover.fill = Color(attr.fill).brighten(seriesOptions.states.hover.brightness).get();
|
665
|
-
// If not a leaf, then remove fill
|
666
|
-
if (!point.node.isLeaf) {
|
667
|
-
if (pick(seriesOptions.interactByLeaf, !seriesOptions.allowDrillToNode)) {
|
668
|
-
attr.fill = 'none';
|
669
|
-
delete hover.fill;
|
670
|
-
} else {
|
671
|
-
// TODO: let users set the opacity
|
672
|
-
attr.fill = Color(attr.fill).setOpacity(0.15).get();
|
673
|
-
hover.fill = Color(hover.fill).setOpacity(0.75).get();
|
674
|
-
}
|
675
|
-
}
|
676
|
-
if (point.node.level <= series.nodeMap[series.rootNode].level) {
|
677
|
-
attr.fill = 'none';
|
678
|
-
attr.zIndex = 0;
|
679
|
-
delete hover.fill;
|
680
|
-
}
|
681
|
-
point.pointAttr[''] = H.extend(point.pointAttr[''], attr);
|
682
|
-
// @todo Move this to drawDataLabels
|
683
|
-
if (point.dataLabel) {
|
684
|
-
point.dataLabel.attr({ zIndex: (point.pointAttr[''].zIndex + 1) });
|
681
|
+
var groupKey = "levelGroup-" + point.node.levelDynamic;
|
682
|
+
if (!series[groupKey]) {
|
683
|
+
series[groupKey] = series.chart.renderer.g(groupKey)
|
684
|
+
.attr({
|
685
|
+
zIndex: 1000 - point.node.levelDynamic // @todo Set the zIndex based upon the number of levels, instead of using 1000
|
686
|
+
})
|
687
|
+
.add(series.group);
|
685
688
|
}
|
689
|
+
point.group = series[groupKey];
|
690
|
+
// Preliminary code in prepraration for HC5 that uses pointAttribs for all series
|
691
|
+
point.pointAttr = {
|
692
|
+
'': series.pointAttribs(point),
|
693
|
+
'hover': series.pointAttribs(point, 'hover'),
|
694
|
+
'select': {}
|
695
|
+
};
|
686
696
|
});
|
687
697
|
// Call standard drawPoints
|
688
698
|
seriesTypes.column.prototype.drawPoints.call(this);
|
689
699
|
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
700
|
+
// If drillToNode is allowed, set a point cursor on clickables & add drillId to point
|
701
|
+
if (series.options.allowDrillToNode) {
|
702
|
+
each(points, function (point) {
|
703
|
+
var cursor,
|
704
|
+
drillId;
|
705
|
+
if (point.graphic) {
|
706
|
+
drillId = point.drillId = series.options.interactByLeaf ? series.drillToByLeaf(point) : series.drillToByGroup(point);
|
707
|
+
cursor = drillId ? "pointer" : "default";
|
708
|
+
point.graphic.css({ cursor: cursor });
|
709
|
+
}
|
710
|
+
});
|
699
711
|
}
|
700
712
|
},
|
701
713
|
/**
|
@@ -725,34 +737,17 @@
|
|
725
737
|
* Add drilling on the suitable points
|
726
738
|
*/
|
727
739
|
drillTo: function () {
|
728
|
-
var series = this
|
729
|
-
|
730
|
-
|
731
|
-
|
740
|
+
var series = this;
|
741
|
+
H.addEvent(series, 'click', function (event) {
|
742
|
+
var point = event.point,
|
743
|
+
drillId = point.drillId,
|
732
744
|
drillName;
|
733
|
-
H.removeEvent(point, 'click.drillTo');
|
734
|
-
if (point.graphic) {
|
735
|
-
point.graphic.css({ cursor: 'default' });
|
736
|
-
}
|
737
|
-
|
738
|
-
// Get the drill to id
|
739
|
-
if (series.options.interactByLeaf) {
|
740
|
-
drillId = series.drillToByLeaf(point);
|
741
|
-
} else {
|
742
|
-
drillId = series.drillToByGroup(point);
|
743
|
-
}
|
744
|
-
|
745
745
|
// If a drill id is returned, add click event and cursor.
|
746
746
|
if (drillId) {
|
747
747
|
drillName = series.nodeMap[series.rootNode].name || series.rootNode;
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
H.addEvent(point, 'click.drillTo', function () {
|
752
|
-
point.setState(''); // Remove hover
|
753
|
-
series.drillToNode(drillId);
|
754
|
-
series.showDrillUpButton(drillName);
|
755
|
-
});
|
748
|
+
point.setState(''); // Remove hover
|
749
|
+
series.drillToNode(drillId);
|
750
|
+
series.showDrillUpButton(drillName);
|
756
751
|
}
|
757
752
|
});
|
758
753
|
},
|
@@ -815,11 +810,7 @@
|
|
815
810
|
}
|
816
811
|
},
|
817
812
|
drillToNode: function (id) {
|
818
|
-
|
819
|
-
val = node.values;
|
820
|
-
this.rootNode = id;
|
821
|
-
this.xAxis.setExtremes(val.x, val.x + val.width, false);
|
822
|
-
this.yAxis.setExtremes(val.y, val.y + val.height, false);
|
813
|
+
this.options.rootId = id;
|
823
814
|
this.isDirty = true; // Force redraw
|
824
815
|
this.chart.redraw();
|
825
816
|
},
|