highcharts-rails 2.3.5 → 3.0.0
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.
- data.tar.gz.asc +18 -0
- data/CHANGELOG.markdown +13 -9
- data/README.markdown +2 -1
- data/lib/highcharts/version.rb +1 -1
- data/vendor/assets/javascripts/highcharts.js +2662 -1704
- data/vendor/assets/javascripts/highcharts/adapters/mootools.js +15 -30
- data/vendor/assets/javascripts/highcharts/adapters/prototype.js +10 -79
- data/vendor/assets/javascripts/highcharts/highcharts-more.js +50 -1581
- data/vendor/assets/javascripts/highcharts/modules/canvas-tools.js +2792 -2792
- data/vendor/assets/javascripts/highcharts/modules/data.js +38 -22
- data/vendor/assets/javascripts/highcharts/modules/exporting.js +182 -230
- data/vendor/assets/javascripts/highcharts/modules/funnel.js +284 -0
- data/vendor/assets/javascripts/highcharts/themes/dark-blue.js +11 -20
- data/vendor/assets/javascripts/highcharts/themes/dark-green.js +12 -20
- data/vendor/assets/javascripts/highcharts/themes/gray.js +15 -20
- data/vendor/assets/javascripts/highcharts/themes/grid.js +8 -0
- metadata +17 -16
- metadata.gz.asc +18 -0
@@ -1,8 +1,8 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v3.0.0 (2013-03-22)
|
3
3
|
* MooTools adapter
|
4
4
|
*
|
5
|
-
* (c) 2010-
|
5
|
+
* (c) 2010-2013 Torstein Hønsi
|
6
6
|
*
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
@@ -190,36 +190,11 @@ win.HighchartsAdapter = {
|
|
190
190
|
return arr.indexOf(item, from);
|
191
191
|
},
|
192
192
|
|
193
|
-
/**
|
194
|
-
* Deep merge two objects and return a third
|
195
|
-
*/
|
196
|
-
merge: function () {
|
197
|
-
var args = arguments,
|
198
|
-
args13 = [{}], // MooTools 1.3+
|
199
|
-
i = args.length,
|
200
|
-
ret;
|
201
|
-
|
202
|
-
if (legacy) {
|
203
|
-
ret = $merge.apply(null, args);
|
204
|
-
} else {
|
205
|
-
while (i--) {
|
206
|
-
// Boolean argumens should not be merged.
|
207
|
-
// JQuery explicitly skips this, so we do it here as well.
|
208
|
-
if (typeof args[i] !== 'boolean') {
|
209
|
-
args13[i + 1] = args[i];
|
210
|
-
}
|
211
|
-
}
|
212
|
-
ret = Object.merge.apply(Object, args13);
|
213
|
-
}
|
214
|
-
|
215
|
-
return ret;
|
216
|
-
},
|
217
|
-
|
218
193
|
/**
|
219
194
|
* Get the offset of an element relative to the top left corner of the web page
|
220
195
|
*/
|
221
196
|
offset: function (el) {
|
222
|
-
var offsets =
|
197
|
+
var offsets = el.getPosition(); // #1496
|
223
198
|
return {
|
224
199
|
left: offsets.x,
|
225
200
|
top: offsets.y
|
@@ -291,6 +266,12 @@ win.HighchartsAdapter = {
|
|
291
266
|
// create an event object that keeps all functions
|
292
267
|
event = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs);
|
293
268
|
event = $extend(event, eventArguments);
|
269
|
+
|
270
|
+
// When running an event on the Chart.prototype, MooTools nests the target in event.event
|
271
|
+
if (!event.target && event.event) {
|
272
|
+
event.target = event.event.target;
|
273
|
+
}
|
274
|
+
|
294
275
|
// override the preventDefault function to be able to use
|
295
276
|
// this for custom events
|
296
277
|
event.preventDefault = function () {
|
@@ -309,10 +290,14 @@ win.HighchartsAdapter = {
|
|
309
290
|
},
|
310
291
|
|
311
292
|
/**
|
312
|
-
* Set back e.pageX and e.pageY that MooTools has abstracted away
|
293
|
+
* Set back e.pageX and e.pageY that MooTools has abstracted away. #1165, #1346.
|
313
294
|
*/
|
314
295
|
washMouseEvent: function (e) {
|
315
|
-
|
296
|
+
if (e.page) {
|
297
|
+
e.pageX = e.page.x;
|
298
|
+
e.pageY = e.page.y;
|
299
|
+
}
|
300
|
+
return e;
|
316
301
|
},
|
317
302
|
|
318
303
|
/**
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v3.0.0 (2013-03-22)
|
3
3
|
* Prototype adapter
|
4
4
|
*
|
5
5
|
* @author Michael Nelson, Torstein Hønsi.
|
@@ -83,7 +83,10 @@ return {
|
|
83
83
|
}
|
84
84
|
|
85
85
|
if (element.attr) { // SVGElement
|
86
|
-
|
86
|
+
|
87
|
+
if (element.element) { // If not, it has been destroyed (#1405)
|
88
|
+
element.attr(this.options.attribute, position);
|
89
|
+
}
|
87
90
|
|
88
91
|
} else { // HTML, #409
|
89
92
|
obj = {};
|
@@ -95,7 +98,9 @@ return {
|
|
95
98
|
finish: function () {
|
96
99
|
// Delete the property that holds this animation now that it is finished.
|
97
100
|
// Both canceled animations and complete ones gets a 'finish' call.
|
98
|
-
|
101
|
+
if (this.element && this.element._highchart_animation) { // #1405
|
102
|
+
delete this.element._highchart_animation[this.key];
|
103
|
+
}
|
99
104
|
}
|
100
105
|
});
|
101
106
|
}
|
@@ -261,82 +266,6 @@ return {
|
|
261
266
|
return arr.map(fn);
|
262
267
|
},
|
263
268
|
|
264
|
-
// deep merge. merge({a : 'a', b : {b1 : 'b1', b2 : 'b2'}}, {b : {b2 : 'b2_prime'}, c : 'c'}) => {a : 'a', b : {b1 : 'b1', b2 : 'b2_prime'}, c : 'c'}
|
265
|
-
/*merge: function(){
|
266
|
-
function doCopy(copy, original) {
|
267
|
-
var value,
|
268
|
-
key,
|
269
|
-
undef,
|
270
|
-
nil,
|
271
|
-
same,
|
272
|
-
obj,
|
273
|
-
arr,
|
274
|
-
node;
|
275
|
-
|
276
|
-
for (key in original) {
|
277
|
-
value = original[key];
|
278
|
-
undef = typeof(value) === 'undefined';
|
279
|
-
nil = value === null;
|
280
|
-
same = original === copy[key];
|
281
|
-
|
282
|
-
if (undef || nil || same) {
|
283
|
-
continue;
|
284
|
-
}
|
285
|
-
|
286
|
-
obj = typeof(value) === 'object';
|
287
|
-
arr = value && obj && value.constructor == Array;
|
288
|
-
node = !!value.nodeType;
|
289
|
-
|
290
|
-
if (obj && !arr && !node) {
|
291
|
-
copy[key] = doCopy(typeof copy[key] == 'object' ? copy[key] : {}, value);
|
292
|
-
}
|
293
|
-
else {
|
294
|
-
copy[key] = original[key];
|
295
|
-
}
|
296
|
-
}
|
297
|
-
return copy;
|
298
|
-
}
|
299
|
-
|
300
|
-
var args = arguments, retVal = {};
|
301
|
-
|
302
|
-
for (var i = 0; i < args.length; i++) {
|
303
|
-
retVal = doCopy(retVal, args[i]);
|
304
|
-
}
|
305
|
-
|
306
|
-
return retVal;
|
307
|
-
},*/
|
308
|
-
merge: function () { // the built-in prototype merge function doesn't do deep copy
|
309
|
-
function doCopy(copy, original) {
|
310
|
-
var value, key;
|
311
|
-
|
312
|
-
for (key in original) {
|
313
|
-
value = original[key];
|
314
|
-
if (value && typeof value === 'object' && value.constructor !== Array &&
|
315
|
-
typeof value.nodeType !== 'number') {
|
316
|
-
copy[key] = doCopy(copy[key] || {}, value); // copy
|
317
|
-
|
318
|
-
} else {
|
319
|
-
copy[key] = original[key];
|
320
|
-
}
|
321
|
-
}
|
322
|
-
return copy;
|
323
|
-
}
|
324
|
-
|
325
|
-
function merge() {
|
326
|
-
var args = arguments,
|
327
|
-
i,
|
328
|
-
retVal = {};
|
329
|
-
|
330
|
-
for (i = 0; i < args.length; i++) {
|
331
|
-
retVal = doCopy(retVal, args[i]);
|
332
|
-
|
333
|
-
}
|
334
|
-
return retVal;
|
335
|
-
}
|
336
|
-
|
337
|
-
return merge.apply(this, arguments);
|
338
|
-
},
|
339
|
-
|
340
269
|
// extend an object to handle highchart events (highchart objects, not svg elements).
|
341
270
|
// this is a very simple way of handling events but whatever, it works (i think)
|
342
271
|
_extend: function (object) {
|
@@ -360,6 +289,7 @@ return {
|
|
360
289
|
}
|
361
290
|
},
|
362
291
|
_highcharts_fire: function (name, args) {
|
292
|
+
var target = this;
|
363
293
|
(this._highchart_events[name] || []).each(function (fn) {
|
364
294
|
// args is never null here
|
365
295
|
if (args.stopped) {
|
@@ -370,6 +300,7 @@ return {
|
|
370
300
|
args.preventDefault = function () {
|
371
301
|
args.defaultPrevented = true;
|
372
302
|
};
|
303
|
+
args.target = target;
|
373
304
|
|
374
305
|
// If the event handler return false, prevent the default handler from executing
|
375
306
|
if (fn.bind(this)(args) === false) {
|
@@ -1,1581 +1,50 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
(function (
|
16
|
-
var
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
function
|
37
|
-
|
38
|
-
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
pane.chart = chart;
|
52
|
-
|
53
|
-
// Set options
|
54
|
-
if (chart.angular) { // gauges
|
55
|
-
defaultOptions.background = {}; // gets extended by this.defaultBackgroundOptions
|
56
|
-
}
|
57
|
-
pane.options = options = merge(defaultOptions, options);
|
58
|
-
|
59
|
-
backgroundOption = options.background;
|
60
|
-
|
61
|
-
// To avoid having weighty logic to place, update and remove the backgrounds,
|
62
|
-
// push them to the first axis' plot bands and borrow the existing logic there.
|
63
|
-
if (backgroundOption) {
|
64
|
-
each([].concat(splat(backgroundOption)).reverse(), function (config) {
|
65
|
-
var backgroundColor = config.backgroundColor; // if defined, replace the old one (specific for gradients)
|
66
|
-
config = merge(pane.defaultBackgroundOptions, config);
|
67
|
-
if (backgroundColor) {
|
68
|
-
config.backgroundColor = backgroundColor;
|
69
|
-
}
|
70
|
-
config.color = config.backgroundColor; // due to naming in plotBands
|
71
|
-
firstAxis.options.plotBands.unshift(config);
|
72
|
-
});
|
73
|
-
}
|
74
|
-
},
|
75
|
-
|
76
|
-
/**
|
77
|
-
* The default options object
|
78
|
-
*/
|
79
|
-
defaultOptions: {
|
80
|
-
// background: {conditional},
|
81
|
-
center: ['50%', '50%'],
|
82
|
-
size: '85%',
|
83
|
-
startAngle: 0
|
84
|
-
//endAngle: startAngle + 360
|
85
|
-
},
|
86
|
-
|
87
|
-
/**
|
88
|
-
* The default background options
|
89
|
-
*/
|
90
|
-
defaultBackgroundOptions: {
|
91
|
-
shape: 'circle',
|
92
|
-
borderWidth: 1,
|
93
|
-
borderColor: 'silver',
|
94
|
-
backgroundColor: {
|
95
|
-
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
|
96
|
-
stops: [
|
97
|
-
[0, '#FFF'],
|
98
|
-
[1, '#DDD']
|
99
|
-
]
|
100
|
-
},
|
101
|
-
from: Number.MIN_VALUE, // corrected to axis min
|
102
|
-
innerRadius: 0,
|
103
|
-
to: Number.MAX_VALUE, // corrected to axis max
|
104
|
-
outerRadius: '105%'
|
105
|
-
}
|
106
|
-
|
107
|
-
});
|
108
|
-
var axisProto = Axis.prototype,
|
109
|
-
tickProto = Tick.prototype;
|
110
|
-
|
111
|
-
/**
|
112
|
-
* Augmented methods for the x axis in order to hide it completely, used for the X axis in gauges
|
113
|
-
*/
|
114
|
-
var hiddenAxisMixin = {
|
115
|
-
getOffset: noop,
|
116
|
-
redraw: function () {
|
117
|
-
this.isDirty = false; // prevent setting Y axis dirty
|
118
|
-
},
|
119
|
-
render: function () {
|
120
|
-
this.isDirty = false; // prevent setting Y axis dirty
|
121
|
-
},
|
122
|
-
setScale: noop,
|
123
|
-
setCategories: noop,
|
124
|
-
setTitle: noop
|
125
|
-
};
|
126
|
-
|
127
|
-
/**
|
128
|
-
* Augmented methods for the value axis
|
129
|
-
*/
|
130
|
-
/*jslint unparam: true*/
|
131
|
-
var radialAxisMixin = {
|
132
|
-
isRadial: true,
|
133
|
-
|
134
|
-
/**
|
135
|
-
* The default options extend defaultYAxisOptions
|
136
|
-
*/
|
137
|
-
defaultRadialGaugeOptions: {
|
138
|
-
labels: {
|
139
|
-
align: 'center',
|
140
|
-
x: 0,
|
141
|
-
y: null // auto
|
142
|
-
},
|
143
|
-
minorGridLineWidth: 0,
|
144
|
-
minorTickInterval: 'auto',
|
145
|
-
minorTickLength: 10,
|
146
|
-
minorTickPosition: 'inside',
|
147
|
-
minorTickWidth: 1,
|
148
|
-
plotBands: [],
|
149
|
-
tickLength: 10,
|
150
|
-
tickPosition: 'inside',
|
151
|
-
tickWidth: 2,
|
152
|
-
title: {
|
153
|
-
rotation: 0
|
154
|
-
},
|
155
|
-
zIndex: 2 // behind dials, points in the series group
|
156
|
-
},
|
157
|
-
|
158
|
-
// Circular axis around the perimeter of a polar chart
|
159
|
-
defaultRadialXOptions: {
|
160
|
-
gridLineWidth: 1, // spokes
|
161
|
-
labels: {
|
162
|
-
align: null, // auto
|
163
|
-
distance: 15,
|
164
|
-
x: 0,
|
165
|
-
y: null // auto
|
166
|
-
},
|
167
|
-
maxPadding: 0,
|
168
|
-
minPadding: 0,
|
169
|
-
plotBands: [],
|
170
|
-
showLastLabel: false,
|
171
|
-
tickLength: 0
|
172
|
-
},
|
173
|
-
|
174
|
-
// Radial axis, like a spoke in a polar chart
|
175
|
-
defaultRadialYOptions: {
|
176
|
-
gridLineInterpolation: 'circle',
|
177
|
-
labels: {
|
178
|
-
align: 'right',
|
179
|
-
x: -3,
|
180
|
-
y: -2
|
181
|
-
},
|
182
|
-
plotBands: [],
|
183
|
-
showLastLabel: false,
|
184
|
-
title: {
|
185
|
-
x: 4,
|
186
|
-
text: null,
|
187
|
-
rotation: 90
|
188
|
-
}
|
189
|
-
},
|
190
|
-
|
191
|
-
/**
|
192
|
-
* Merge and set options
|
193
|
-
*/
|
194
|
-
setOptions: function (userOptions) {
|
195
|
-
|
196
|
-
this.options = merge(
|
197
|
-
this.defaultOptions,
|
198
|
-
this.defaultRadialOptions,
|
199
|
-
userOptions
|
200
|
-
);
|
201
|
-
|
202
|
-
},
|
203
|
-
|
204
|
-
/**
|
205
|
-
* Wrap the getOffset method to return zero offset for title or labels in a radial
|
206
|
-
* axis
|
207
|
-
*/
|
208
|
-
getOffset: function () {
|
209
|
-
// Call the Axis prototype method (the method we're in now is on the instance)
|
210
|
-
axisProto.getOffset.call(this);
|
211
|
-
|
212
|
-
// Title or label offsets are not counted
|
213
|
-
this.chart.axisOffset[this.side] = 0;
|
214
|
-
|
215
|
-
// Set the center array
|
216
|
-
this.center = this.pane.center = seriesTypes.pie.prototype.getCenter.call(this.pane);
|
217
|
-
},
|
218
|
-
|
219
|
-
|
220
|
-
/**
|
221
|
-
* Get the path for the axis line. This method is also referenced in the getPlotLinePath
|
222
|
-
* method.
|
223
|
-
*/
|
224
|
-
getLinePath: function (lineWidth, radius) {
|
225
|
-
var center = this.center;
|
226
|
-
radius = pick(radius, center[2] / 2 - this.offset);
|
227
|
-
|
228
|
-
return this.chart.renderer.symbols.arc(
|
229
|
-
this.left + center[0],
|
230
|
-
this.top + center[1],
|
231
|
-
radius,
|
232
|
-
radius,
|
233
|
-
{
|
234
|
-
start: this.startAngleRad,
|
235
|
-
end: this.endAngleRad,
|
236
|
-
open: true,
|
237
|
-
innerR: 0
|
238
|
-
}
|
239
|
-
);
|
240
|
-
},
|
241
|
-
|
242
|
-
/**
|
243
|
-
* Override setAxisTranslation by setting the translation to the difference
|
244
|
-
* in rotation. This allows the translate method to return angle for
|
245
|
-
* any given value.
|
246
|
-
*/
|
247
|
-
setAxisTranslation: function () {
|
248
|
-
|
249
|
-
// Call uber method
|
250
|
-
axisProto.setAxisTranslation.call(this);
|
251
|
-
|
252
|
-
// Set transA and minPixelPadding
|
253
|
-
if (this.center) { // it's not defined the first time
|
254
|
-
if (this.isCircular) {
|
255
|
-
|
256
|
-
this.transA = (this.endAngleRad - this.startAngleRad) /
|
257
|
-
((this.max - this.min) || 1);
|
258
|
-
|
259
|
-
|
260
|
-
} else {
|
261
|
-
this.transA = (this.center[2] / 2) / ((this.max - this.min) || 1);
|
262
|
-
}
|
263
|
-
|
264
|
-
if (this.isXAxis) {
|
265
|
-
this.minPixelPadding = this.transA * this.minPointOffset +
|
266
|
-
(this.reversed ? (this.endAngleRad - this.startAngleRad) / 4 : 0); // ???
|
267
|
-
}
|
268
|
-
}
|
269
|
-
},
|
270
|
-
|
271
|
-
/**
|
272
|
-
* In case of auto connect, add one closestPointRange to the max value right before
|
273
|
-
* tickPositions are computed, so that ticks will extend passed the real max.
|
274
|
-
*/
|
275
|
-
beforeSetTickPositions: function () {
|
276
|
-
if (this.autoConnect) {
|
277
|
-
this.max += (this.categories && 1) || this.pointRange || this.closestPointRange; // #1197
|
278
|
-
}
|
279
|
-
},
|
280
|
-
|
281
|
-
/**
|
282
|
-
* Override the setAxisSize method to use the arc's circumference as length. This
|
283
|
-
* allows tickPixelInterval to apply to pixel lengths along the perimeter
|
284
|
-
*/
|
285
|
-
setAxisSize: function () {
|
286
|
-
|
287
|
-
axisProto.setAxisSize.call(this);
|
288
|
-
|
289
|
-
if (this.center) { // it's not defined the first time
|
290
|
-
this.len = this.width = this.height = this.isCircular ?
|
291
|
-
this.center[2] * (this.endAngleRad - this.startAngleRad) / 2 :
|
292
|
-
this.center[2] / 2;
|
293
|
-
}
|
294
|
-
},
|
295
|
-
|
296
|
-
/**
|
297
|
-
* Returns the x, y coordinate of a point given by a value and a pixel distance
|
298
|
-
* from center
|
299
|
-
*/
|
300
|
-
getPosition: function (value, length) {
|
301
|
-
if (!this.isCircular) {
|
302
|
-
length = this.translate(value);
|
303
|
-
value = this.min;
|
304
|
-
}
|
305
|
-
|
306
|
-
return this.postTranslate(
|
307
|
-
this.translate(value),
|
308
|
-
pick(length, this.center[2] / 2) - this.offset
|
309
|
-
);
|
310
|
-
},
|
311
|
-
|
312
|
-
/**
|
313
|
-
* Translate from intermediate plotX (angle), plotY (axis.len - radius) to final chart coordinates.
|
314
|
-
*/
|
315
|
-
postTranslate: function (angle, radius) {
|
316
|
-
|
317
|
-
var chart = this.chart,
|
318
|
-
center = this.center;
|
319
|
-
|
320
|
-
angle = this.startAngleRad + angle;
|
321
|
-
|
322
|
-
return {
|
323
|
-
x: chart.plotLeft + center[0] + Math.cos(angle) * radius,
|
324
|
-
y: chart.plotTop + center[1] + Math.sin(angle) * radius
|
325
|
-
};
|
326
|
-
|
327
|
-
},
|
328
|
-
|
329
|
-
/**
|
330
|
-
* Find the path for plot bands along the radial axis
|
331
|
-
*/
|
332
|
-
getPlotBandPath: function (from, to, options) {
|
333
|
-
var center = this.center,
|
334
|
-
startAngleRad = this.startAngleRad,
|
335
|
-
fullRadius = center[2] / 2,
|
336
|
-
radii = [
|
337
|
-
pick(options.outerRadius, '100%'),
|
338
|
-
options.innerRadius,
|
339
|
-
pick(options.thickness, 10)
|
340
|
-
],
|
341
|
-
percentRegex = /%$/,
|
342
|
-
start,
|
343
|
-
end,
|
344
|
-
open,
|
345
|
-
isCircular = this.isCircular, // X axis in a polar chart
|
346
|
-
ret;
|
347
|
-
|
348
|
-
// Polygonal plot bands
|
349
|
-
if (this.options.gridLineInterpolation === 'polygon') {
|
350
|
-
ret = this.getPlotLinePath(from).concat(this.getPlotLinePath(to, true));
|
351
|
-
|
352
|
-
// Circular grid bands
|
353
|
-
} else {
|
354
|
-
|
355
|
-
// Plot bands on Y axis (radial axis) - inner and outer radius depend on to and from
|
356
|
-
if (!isCircular) {
|
357
|
-
radii[0] = this.translate(from);
|
358
|
-
radii[1] = this.translate(to);
|
359
|
-
}
|
360
|
-
|
361
|
-
// Convert percentages to pixel values
|
362
|
-
radii = map(radii, function (radius) {
|
363
|
-
if (percentRegex.test(radius)) {
|
364
|
-
radius = (pInt(radius, 10) * fullRadius) / 100;
|
365
|
-
}
|
366
|
-
return radius;
|
367
|
-
});
|
368
|
-
|
369
|
-
// Handle full circle
|
370
|
-
if (options.shape === 'circle' || !isCircular) {
|
371
|
-
start = -Math.PI / 2;
|
372
|
-
end = Math.PI * 1.5;
|
373
|
-
open = true;
|
374
|
-
} else {
|
375
|
-
start = startAngleRad + this.translate(from);
|
376
|
-
end = startAngleRad + this.translate(to);
|
377
|
-
}
|
378
|
-
|
379
|
-
|
380
|
-
ret = this.chart.renderer.symbols.arc(
|
381
|
-
this.left + center[0],
|
382
|
-
this.top + center[1],
|
383
|
-
radii[0],
|
384
|
-
radii[0],
|
385
|
-
{
|
386
|
-
start: start,
|
387
|
-
end: end,
|
388
|
-
innerR: pick(radii[1], radii[0] - radii[2]),
|
389
|
-
open: open
|
390
|
-
}
|
391
|
-
);
|
392
|
-
}
|
393
|
-
|
394
|
-
return ret;
|
395
|
-
},
|
396
|
-
|
397
|
-
/**
|
398
|
-
* Find the path for plot lines perpendicular to the radial axis.
|
399
|
-
*/
|
400
|
-
getPlotLinePath: function (value, reverse) {
|
401
|
-
var axis = this,
|
402
|
-
center = axis.center,
|
403
|
-
chart = axis.chart,
|
404
|
-
end = axis.getPosition(value),
|
405
|
-
xAxis,
|
406
|
-
xy,
|
407
|
-
tickPositions,
|
408
|
-
ret;
|
409
|
-
|
410
|
-
// Spokes
|
411
|
-
if (axis.isCircular) {
|
412
|
-
ret = ['M', center[0] + chart.plotLeft, center[1] + chart.plotTop, 'L', end.x, end.y];
|
413
|
-
|
414
|
-
// Concentric circles
|
415
|
-
} else if (axis.options.gridLineInterpolation === 'circle') {
|
416
|
-
value = axis.translate(value);
|
417
|
-
if (value) { // a value of 0 is in the center
|
418
|
-
ret = axis.getLinePath(0, value);
|
419
|
-
}
|
420
|
-
// Concentric polygons
|
421
|
-
} else {
|
422
|
-
xAxis = chart.xAxis[0];
|
423
|
-
ret = [];
|
424
|
-
value = axis.translate(value);
|
425
|
-
tickPositions = xAxis.tickPositions;
|
426
|
-
if (xAxis.autoConnect) {
|
427
|
-
tickPositions = tickPositions.concat([tickPositions[0]]);
|
428
|
-
}
|
429
|
-
// Reverse the positions for concatenation of polygonal plot bands
|
430
|
-
if (reverse) {
|
431
|
-
tickPositions = [].concat(tickPositions).reverse();
|
432
|
-
}
|
433
|
-
|
434
|
-
each(tickPositions, function (pos, i) {
|
435
|
-
xy = xAxis.getPosition(pos, value);
|
436
|
-
ret.push(i ? 'L' : 'M', xy.x, xy.y);
|
437
|
-
});
|
438
|
-
|
439
|
-
}
|
440
|
-
return ret;
|
441
|
-
},
|
442
|
-
|
443
|
-
/**
|
444
|
-
* Find the position for the axis title, by default inside the gauge
|
445
|
-
*/
|
446
|
-
getTitlePosition: function () {
|
447
|
-
var center = this.center,
|
448
|
-
chart = this.chart,
|
449
|
-
titleOptions = this.options.title;
|
450
|
-
|
451
|
-
return {
|
452
|
-
x: chart.plotLeft + center[0] + (titleOptions.x || 0),
|
453
|
-
y: chart.plotTop + center[1] - ({ high: 0.5, middle: 0.25, low: 0 }[titleOptions.align] *
|
454
|
-
center[2]) + (titleOptions.y || 0)
|
455
|
-
};
|
456
|
-
}
|
457
|
-
|
458
|
-
};
|
459
|
-
/*jslint unparam: false*/
|
460
|
-
|
461
|
-
/**
|
462
|
-
* Override axisProto.init to mix in special axis instance functions and function overrides
|
463
|
-
*/
|
464
|
-
wrap(axisProto, 'init', function (proceed, chart, userOptions) {
|
465
|
-
var axis = this,
|
466
|
-
angular = chart.angular,
|
467
|
-
polar = chart.polar,
|
468
|
-
isX = userOptions.isX,
|
469
|
-
isHidden = angular && isX,
|
470
|
-
isCircular,
|
471
|
-
startAngleRad,
|
472
|
-
endAngleRad,
|
473
|
-
options,
|
474
|
-
chartOptions = chart.options,
|
475
|
-
paneIndex = userOptions.pane || 0,
|
476
|
-
pane,
|
477
|
-
paneOptions;
|
478
|
-
|
479
|
-
// Before prototype.init
|
480
|
-
if (angular) {
|
481
|
-
extend(this, isHidden ? hiddenAxisMixin : radialAxisMixin);
|
482
|
-
isCircular = !isX;
|
483
|
-
if (isCircular) {
|
484
|
-
this.defaultRadialOptions = this.defaultRadialGaugeOptions;
|
485
|
-
}
|
486
|
-
|
487
|
-
} else if (polar) {
|
488
|
-
//extend(this, userOptions.isX ? radialAxisMixin : radialAxisMixin);
|
489
|
-
extend(this, radialAxisMixin);
|
490
|
-
isCircular = isX;
|
491
|
-
this.defaultRadialOptions = isX ? this.defaultRadialXOptions : merge(this.defaultYAxisOptions, this.defaultRadialYOptions);
|
492
|
-
|
493
|
-
}
|
494
|
-
|
495
|
-
// Run prototype.init
|
496
|
-
proceed.call(this, chart, userOptions);
|
497
|
-
|
498
|
-
if (!isHidden && (angular || polar)) {
|
499
|
-
options = this.options;
|
500
|
-
|
501
|
-
// Create the pane and set the pane options.
|
502
|
-
if (!chart.panes) {
|
503
|
-
chart.panes = [];
|
504
|
-
}
|
505
|
-
this.pane = chart.panes[paneIndex] = pane = new Pane(
|
506
|
-
splat(chartOptions.pane)[paneIndex],
|
507
|
-
chart,
|
508
|
-
axis
|
509
|
-
);
|
510
|
-
paneOptions = pane.options;
|
511
|
-
|
512
|
-
|
513
|
-
// Disable certain features on angular and polar axes
|
514
|
-
chart.inverted = false;
|
515
|
-
chartOptions.chart.zoomType = null;
|
516
|
-
|
517
|
-
// Start and end angle options are
|
518
|
-
// given in degrees relative to top, while internal computations are
|
519
|
-
// in radians relative to right (like SVG).
|
520
|
-
this.startAngleRad = startAngleRad = (paneOptions.startAngle - 90) * Math.PI / 180;
|
521
|
-
this.endAngleRad = endAngleRad = (pick(paneOptions.endAngle, paneOptions.startAngle + 360) - 90) * Math.PI / 180;
|
522
|
-
this.offset = options.offset || 0;
|
523
|
-
|
524
|
-
this.isCircular = isCircular;
|
525
|
-
|
526
|
-
// Automatically connect grid lines?
|
527
|
-
if (isCircular && userOptions.max === UNDEFINED && endAngleRad - startAngleRad === 2 * Math.PI) {
|
528
|
-
this.autoConnect = true;
|
529
|
-
}
|
530
|
-
}
|
531
|
-
|
532
|
-
});
|
533
|
-
|
534
|
-
/**
|
535
|
-
* Add special cases within the Tick class' methods for radial axes.
|
536
|
-
*/
|
537
|
-
wrap(tickProto, 'getPosition', function (proceed, horiz, pos, tickmarkOffset, old) {
|
538
|
-
var axis = this.axis;
|
539
|
-
|
540
|
-
return axis.getPosition ?
|
541
|
-
axis.getPosition(pos) :
|
542
|
-
proceed.call(this, horiz, pos, tickmarkOffset, old);
|
543
|
-
});
|
544
|
-
|
545
|
-
/**
|
546
|
-
* Wrap the getLabelPosition function to find the center position of the label
|
547
|
-
* based on the distance option
|
548
|
-
*/
|
549
|
-
wrap(tickProto, 'getLabelPosition', function (proceed, x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {
|
550
|
-
var axis = this.axis,
|
551
|
-
optionsY = labelOptions.y,
|
552
|
-
ret,
|
553
|
-
align = labelOptions.align,
|
554
|
-
angle = (axis.translate(this.pos) + axis.startAngleRad + Math.PI / 2) / Math.PI * 180;
|
555
|
-
|
556
|
-
if (axis.isRadial) {
|
557
|
-
ret = axis.getPosition(this.pos, (axis.center[2] / 2) + pick(labelOptions.distance, -25));
|
558
|
-
|
559
|
-
// Automatically rotated
|
560
|
-
if (labelOptions.rotation === 'auto') {
|
561
|
-
label.attr({
|
562
|
-
rotation: angle
|
563
|
-
});
|
564
|
-
|
565
|
-
// Vertically centered
|
566
|
-
} else if (optionsY === null) {
|
567
|
-
optionsY = pInt(label.styles.lineHeight) * 0.9 - label.getBBox().height / 2;
|
568
|
-
|
569
|
-
}
|
570
|
-
|
571
|
-
// Automatic alignment
|
572
|
-
if (align === null) {
|
573
|
-
if (axis.isCircular) {
|
574
|
-
if (angle > 20 && angle < 160) {
|
575
|
-
align = 'left'; // right hemisphere
|
576
|
-
} else if (angle > 200 && angle < 340) {
|
577
|
-
align = 'right'; // left hemisphere
|
578
|
-
} else {
|
579
|
-
align = 'center'; // top or bottom
|
580
|
-
}
|
581
|
-
} else {
|
582
|
-
align = 'center';
|
583
|
-
}
|
584
|
-
label.attr({
|
585
|
-
align: align
|
586
|
-
});
|
587
|
-
}
|
588
|
-
|
589
|
-
ret.x += labelOptions.x;
|
590
|
-
ret.y += optionsY;
|
591
|
-
|
592
|
-
} else {
|
593
|
-
ret = proceed.call(this, x, y, label, horiz, labelOptions, tickmarkOffset, index, step);
|
594
|
-
}
|
595
|
-
return ret;
|
596
|
-
});
|
597
|
-
|
598
|
-
/**
|
599
|
-
* Wrap the getMarkPath function to return the path of the radial marker
|
600
|
-
*/
|
601
|
-
wrap(tickProto, 'getMarkPath', function (proceed, x, y, tickLength, tickWidth, horiz, renderer) {
|
602
|
-
var axis = this.axis,
|
603
|
-
endPoint,
|
604
|
-
ret;
|
605
|
-
|
606
|
-
if (axis.isRadial) {
|
607
|
-
endPoint = axis.getPosition(this.pos, axis.center[2] / 2 + tickLength);
|
608
|
-
ret = [
|
609
|
-
'M',
|
610
|
-
x,
|
611
|
-
y,
|
612
|
-
'L',
|
613
|
-
endPoint.x,
|
614
|
-
endPoint.y
|
615
|
-
];
|
616
|
-
} else {
|
617
|
-
ret = proceed.call(this, x, y, tickLength, tickWidth, horiz, renderer);
|
618
|
-
}
|
619
|
-
return ret;
|
620
|
-
});/*
|
621
|
-
* The AreaRangeSeries class
|
622
|
-
*
|
623
|
-
*/
|
624
|
-
|
625
|
-
/**
|
626
|
-
* Extend the default options with map options
|
627
|
-
*/
|
628
|
-
defaultPlotOptions.arearange = merge(defaultPlotOptions.area, {
|
629
|
-
lineWidth: 1,
|
630
|
-
marker: null,
|
631
|
-
threshold: null,
|
632
|
-
tooltip: {
|
633
|
-
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>'
|
634
|
-
},
|
635
|
-
trackByArea: true,
|
636
|
-
dataLabels: {
|
637
|
-
verticalAlign: null,
|
638
|
-
xLow: 0,
|
639
|
-
xHigh: 0,
|
640
|
-
yLow: 0,
|
641
|
-
yHigh: 0
|
642
|
-
},
|
643
|
-
shadow: false
|
644
|
-
});
|
645
|
-
|
646
|
-
/**
|
647
|
-
* Extend the point object
|
648
|
-
*/
|
649
|
-
var RangePoint = Highcharts.extendClass(Highcharts.Point, {
|
650
|
-
/**
|
651
|
-
* Apply the options containing the x and low/high data and possible some extra properties.
|
652
|
-
* This is called on point init or from point.update. Extends base Point by adding
|
653
|
-
* multiple y-like values.
|
654
|
-
*
|
655
|
-
* @param {Object} options
|
656
|
-
*/
|
657
|
-
applyOptions: function (options, x) {
|
658
|
-
var point = this,
|
659
|
-
series = point.series,
|
660
|
-
pointArrayMap = series.pointArrayMap,
|
661
|
-
i = 0,
|
662
|
-
j = 0,
|
663
|
-
valueCount = pointArrayMap.length;
|
664
|
-
|
665
|
-
|
666
|
-
// object input
|
667
|
-
if (typeof options === 'object' && typeof options.length !== 'number') {
|
668
|
-
|
669
|
-
// copy options directly to point
|
670
|
-
extend(point, options);
|
671
|
-
|
672
|
-
point.options = options;
|
673
|
-
|
674
|
-
} else if (options.length) { // array
|
675
|
-
// with leading x value
|
676
|
-
if (options.length > valueCount) {
|
677
|
-
if (typeof options[0] === 'string') {
|
678
|
-
point.name = options[0];
|
679
|
-
} else if (typeof options[0] === 'number') {
|
680
|
-
point.x = options[0];
|
681
|
-
}
|
682
|
-
i++;
|
683
|
-
}
|
684
|
-
while (j < valueCount) {
|
685
|
-
point[pointArrayMap[j++]] = options[i++];
|
686
|
-
}
|
687
|
-
}
|
688
|
-
|
689
|
-
// Handle null and make low alias y
|
690
|
-
/*if (point.high === null) {
|
691
|
-
point.low = null;
|
692
|
-
}*/
|
693
|
-
point.y = point[series.pointValKey];
|
694
|
-
|
695
|
-
// If no x is set by now, get auto incremented value. All points must have an
|
696
|
-
// x value, however the y value can be null to create a gap in the series
|
697
|
-
if (point.x === UNDEFINED && series) {
|
698
|
-
point.x = x === UNDEFINED ? series.autoIncrement() : x;
|
699
|
-
}
|
700
|
-
|
701
|
-
return point;
|
702
|
-
},
|
703
|
-
|
704
|
-
/**
|
705
|
-
* Return a plain array for speedy calculation
|
706
|
-
*/
|
707
|
-
toYData: function () {
|
708
|
-
return [this.low, this.high];
|
709
|
-
}
|
710
|
-
});
|
711
|
-
|
712
|
-
/**
|
713
|
-
* Add the series type
|
714
|
-
*/
|
715
|
-
seriesTypes.arearange = Highcharts.extendClass(seriesTypes.area, {
|
716
|
-
type: 'arearange',
|
717
|
-
pointArrayMap: ['low', 'high'],
|
718
|
-
pointClass: RangePoint,
|
719
|
-
pointValKey: 'low',
|
720
|
-
|
721
|
-
/**
|
722
|
-
* Translate data points from raw values x and y to plotX and plotY
|
723
|
-
*/
|
724
|
-
translate: function () {
|
725
|
-
var series = this,
|
726
|
-
yAxis = series.yAxis;
|
727
|
-
|
728
|
-
seriesTypes.area.prototype.translate.apply(series);
|
729
|
-
|
730
|
-
// Set plotLow and plotHigh
|
731
|
-
each(series.points, function (point) {
|
732
|
-
|
733
|
-
if (point.y !== null) {
|
734
|
-
point.plotLow = point.plotY;
|
735
|
-
point.plotHigh = yAxis.translate(point.high, 0, 1, 0, 1);
|
736
|
-
}
|
737
|
-
});
|
738
|
-
},
|
739
|
-
|
740
|
-
/**
|
741
|
-
* Extend the line series' getSegmentPath method by applying the segment
|
742
|
-
* path to both lower and higher values of the range
|
743
|
-
*/
|
744
|
-
getSegmentPath: function (segment) {
|
745
|
-
|
746
|
-
var highSegment = [],
|
747
|
-
i = segment.length,
|
748
|
-
baseGetSegmentPath = Series.prototype.getSegmentPath,
|
749
|
-
point,
|
750
|
-
linePath,
|
751
|
-
lowerPath,
|
752
|
-
options = this.options,
|
753
|
-
step = options.step,
|
754
|
-
higherPath;
|
755
|
-
|
756
|
-
// Make a segment with plotX and plotY for the top values
|
757
|
-
while (i--) {
|
758
|
-
point = segment[i];
|
759
|
-
highSegment.push({
|
760
|
-
plotX: point.plotX,
|
761
|
-
plotY: point.plotHigh
|
762
|
-
});
|
763
|
-
}
|
764
|
-
|
765
|
-
// Get the paths
|
766
|
-
lowerPath = baseGetSegmentPath.call(this, segment);
|
767
|
-
if (step) {
|
768
|
-
if (step === true) {
|
769
|
-
step = 'left';
|
770
|
-
}
|
771
|
-
options.step = { left: 'right', center: 'center', right: 'left' }[step]; // swap for reading in getSegmentPath
|
772
|
-
}
|
773
|
-
higherPath = baseGetSegmentPath.call(this, highSegment);
|
774
|
-
options.step = step;
|
775
|
-
|
776
|
-
// Create a line on both top and bottom of the range
|
777
|
-
linePath = [].concat(lowerPath, higherPath);
|
778
|
-
|
779
|
-
// For the area path, we need to change the 'move' statement into 'lineTo' or 'curveTo'
|
780
|
-
higherPath[0] = 'L'; // this probably doesn't work for spline
|
781
|
-
this.areaPath = this.areaPath.concat(lowerPath, higherPath);
|
782
|
-
|
783
|
-
return linePath;
|
784
|
-
},
|
785
|
-
|
786
|
-
/**
|
787
|
-
* Extend the basic drawDataLabels method by running it for both lower and higher
|
788
|
-
* values.
|
789
|
-
*/
|
790
|
-
drawDataLabels: function () {
|
791
|
-
|
792
|
-
var data = this.data,
|
793
|
-
length = data.length,
|
794
|
-
i,
|
795
|
-
originalDataLabels = [],
|
796
|
-
seriesProto = Series.prototype,
|
797
|
-
dataLabelOptions = this.options.dataLabels,
|
798
|
-
point,
|
799
|
-
inverted = this.chart.inverted;
|
800
|
-
|
801
|
-
if (dataLabelOptions.enabled || this._hasPointLabels) {
|
802
|
-
|
803
|
-
// Step 1: set preliminary values for plotY and dataLabel and draw the upper labels
|
804
|
-
i = length;
|
805
|
-
while (i--) {
|
806
|
-
point = data[i];
|
807
|
-
|
808
|
-
// Set preliminary values
|
809
|
-
point.y = point.high;
|
810
|
-
point.plotY = point.plotHigh;
|
811
|
-
|
812
|
-
// Store original data labels and set preliminary label objects to be picked up
|
813
|
-
// in the uber method
|
814
|
-
originalDataLabels[i] = point.dataLabel;
|
815
|
-
point.dataLabel = point.dataLabelUpper;
|
816
|
-
|
817
|
-
// Set the default offset
|
818
|
-
point.below = false;
|
819
|
-
if (inverted) {
|
820
|
-
dataLabelOptions.align = 'left';
|
821
|
-
dataLabelOptions.x = dataLabelOptions.xHigh;
|
822
|
-
} else {
|
823
|
-
dataLabelOptions.y = dataLabelOptions.yHigh;
|
824
|
-
}
|
825
|
-
}
|
826
|
-
seriesProto.drawDataLabels.apply(this, arguments); // #1209
|
827
|
-
|
828
|
-
// Step 2: reorganize and handle data labels for the lower values
|
829
|
-
i = length;
|
830
|
-
while (i--) {
|
831
|
-
point = data[i];
|
832
|
-
|
833
|
-
// Move the generated labels from step 1, and reassign the original data labels
|
834
|
-
point.dataLabelUpper = point.dataLabel;
|
835
|
-
point.dataLabel = originalDataLabels[i];
|
836
|
-
|
837
|
-
// Reset values
|
838
|
-
point.y = point.low;
|
839
|
-
point.plotY = point.plotLow;
|
840
|
-
|
841
|
-
// Set the default offset
|
842
|
-
point.below = true;
|
843
|
-
if (inverted) {
|
844
|
-
dataLabelOptions.align = 'right';
|
845
|
-
dataLabelOptions.x = dataLabelOptions.xLow;
|
846
|
-
} else {
|
847
|
-
dataLabelOptions.y = dataLabelOptions.yLow;
|
848
|
-
}
|
849
|
-
}
|
850
|
-
seriesProto.drawDataLabels.apply(this, arguments);
|
851
|
-
}
|
852
|
-
|
853
|
-
},
|
854
|
-
|
855
|
-
alignDataLabel: seriesTypes.column.prototype.alignDataLabel,
|
856
|
-
|
857
|
-
getSymbol: seriesTypes.column.prototype.getSymbol,
|
858
|
-
|
859
|
-
drawPoints: noop
|
860
|
-
});/**
|
861
|
-
* The AreaSplineRangeSeries class
|
862
|
-
*/
|
863
|
-
|
864
|
-
defaultPlotOptions.areasplinerange = merge(defaultPlotOptions.arearange);
|
865
|
-
|
866
|
-
/**
|
867
|
-
* AreaSplineRangeSeries object
|
868
|
-
*/
|
869
|
-
seriesTypes.areasplinerange = extendClass(seriesTypes.arearange, {
|
870
|
-
type: 'areasplinerange',
|
871
|
-
getPointSpline: seriesTypes.spline.prototype.getPointSpline
|
872
|
-
});/**
|
873
|
-
* The ColumnRangeSeries class
|
874
|
-
*/
|
875
|
-
defaultPlotOptions.columnrange = merge(defaultPlotOptions.column, defaultPlotOptions.arearange, {
|
876
|
-
lineWidth: 1,
|
877
|
-
pointRange: null
|
878
|
-
});
|
879
|
-
|
880
|
-
/**
|
881
|
-
* ColumnRangeSeries object
|
882
|
-
*/
|
883
|
-
seriesTypes.columnrange = extendClass(seriesTypes.arearange, {
|
884
|
-
type: 'columnrange',
|
885
|
-
/**
|
886
|
-
* Translate data points from raw values x and y to plotX and plotY
|
887
|
-
*/
|
888
|
-
translate: function () {
|
889
|
-
var series = this,
|
890
|
-
yAxis = series.yAxis,
|
891
|
-
plotHigh;
|
892
|
-
|
893
|
-
colProto.translate.apply(series);
|
894
|
-
|
895
|
-
// Set plotLow and plotHigh
|
896
|
-
each(series.points, function (point) {
|
897
|
-
var shapeArgs = point.shapeArgs;
|
898
|
-
|
899
|
-
point.plotHigh = plotHigh = yAxis.translate(point.high, 0, 1, 0, 1);
|
900
|
-
point.plotLow = point.plotY;
|
901
|
-
|
902
|
-
// adjust shape
|
903
|
-
shapeArgs.y = plotHigh;
|
904
|
-
shapeArgs.height = point.plotY - plotHigh;
|
905
|
-
|
906
|
-
point.trackerArgs = shapeArgs;
|
907
|
-
});
|
908
|
-
},
|
909
|
-
drawGraph: noop,
|
910
|
-
pointAttrToOptions: colProto.pointAttrToOptions,
|
911
|
-
drawPoints: colProto.drawPoints,
|
912
|
-
drawTracker: colProto.drawTracker,
|
913
|
-
animate: colProto.animate
|
914
|
-
});/*
|
915
|
-
* The GaugeSeries class
|
916
|
-
*/
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
/**
|
921
|
-
* Extend the default options
|
922
|
-
*/
|
923
|
-
defaultPlotOptions.gauge = merge(defaultPlotOptions.line, {
|
924
|
-
dataLabels: {
|
925
|
-
enabled: true,
|
926
|
-
y: 15,
|
927
|
-
borderWidth: 1,
|
928
|
-
borderColor: 'silver',
|
929
|
-
borderRadius: 3,
|
930
|
-
style: {
|
931
|
-
fontWeight: 'bold'
|
932
|
-
},
|
933
|
-
verticalAlign: 'top',
|
934
|
-
zIndex: 2
|
935
|
-
},
|
936
|
-
dial: {
|
937
|
-
// radius: '80%',
|
938
|
-
// backgroundColor: 'black',
|
939
|
-
// borderColor: 'silver',
|
940
|
-
// borderWidth: 0,
|
941
|
-
// baseWidth: 3,
|
942
|
-
// topWidth: 1,
|
943
|
-
// baseLength: '70%' // of radius
|
944
|
-
// rearLength: '10%'
|
945
|
-
},
|
946
|
-
pivot: {
|
947
|
-
//radius: 5,
|
948
|
-
//borderWidth: 0
|
949
|
-
//borderColor: 'silver',
|
950
|
-
//backgroundColor: 'black'
|
951
|
-
},
|
952
|
-
tooltip: {
|
953
|
-
headerFormat: ''
|
954
|
-
},
|
955
|
-
showInLegend: false
|
956
|
-
});
|
957
|
-
|
958
|
-
/**
|
959
|
-
* Extend the point object
|
960
|
-
*/
|
961
|
-
var GaugePoint = Highcharts.extendClass(Highcharts.Point, {
|
962
|
-
/**
|
963
|
-
* Don't do any hover colors or anything
|
964
|
-
*/
|
965
|
-
setState: function (state) {
|
966
|
-
this.state = state;
|
967
|
-
}
|
968
|
-
});
|
969
|
-
|
970
|
-
|
971
|
-
/**
|
972
|
-
* Add the series type
|
973
|
-
*/
|
974
|
-
var GaugeSeries = {
|
975
|
-
type: 'gauge',
|
976
|
-
pointClass: GaugePoint,
|
977
|
-
|
978
|
-
// chart.angular will be set to true when a gauge series is present, and this will
|
979
|
-
// be used on the axes
|
980
|
-
angular: true,
|
981
|
-
|
982
|
-
/* *
|
983
|
-
* Extend the bindAxes method by adding radial features to the axes
|
984
|
-
* /
|
985
|
-
_bindAxes: function () {
|
986
|
-
Series.prototype.bindAxes.call(this);
|
987
|
-
|
988
|
-
extend(this.xAxis, gaugeXAxisMixin);
|
989
|
-
extend(this.yAxis, radialAxisMixin);
|
990
|
-
this.yAxis.onBind();
|
991
|
-
},*/
|
992
|
-
|
993
|
-
/**
|
994
|
-
* Calculate paths etc
|
995
|
-
*/
|
996
|
-
translate: function () {
|
997
|
-
|
998
|
-
var series = this,
|
999
|
-
yAxis = series.yAxis,
|
1000
|
-
center = yAxis.center;
|
1001
|
-
|
1002
|
-
series.generatePoints();
|
1003
|
-
|
1004
|
-
each(series.points, function (point) {
|
1005
|
-
|
1006
|
-
var dialOptions = merge(series.options.dial, point.dial),
|
1007
|
-
radius = (pInt(pick(dialOptions.radius, 80)) * center[2]) / 200,
|
1008
|
-
baseLength = (pInt(pick(dialOptions.baseLength, 70)) * radius) / 100,
|
1009
|
-
rearLength = (pInt(pick(dialOptions.rearLength, 10)) * radius) / 100,
|
1010
|
-
baseWidth = dialOptions.baseWidth || 3,
|
1011
|
-
topWidth = dialOptions.topWidth || 1;
|
1012
|
-
|
1013
|
-
point.shapeType = 'path';
|
1014
|
-
point.shapeArgs = {
|
1015
|
-
d: dialOptions.path || [
|
1016
|
-
'M',
|
1017
|
-
-rearLength, -baseWidth / 2,
|
1018
|
-
'L',
|
1019
|
-
baseLength, -baseWidth / 2,
|
1020
|
-
radius, -topWidth / 2,
|
1021
|
-
radius, topWidth / 2,
|
1022
|
-
baseLength, baseWidth / 2,
|
1023
|
-
-rearLength, baseWidth / 2,
|
1024
|
-
'z'
|
1025
|
-
],
|
1026
|
-
translateX: center[0],
|
1027
|
-
translateY: center[1],
|
1028
|
-
rotation: (yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true)) * 180 / Math.PI
|
1029
|
-
};
|
1030
|
-
|
1031
|
-
// Positions for data label
|
1032
|
-
point.plotX = center[0];
|
1033
|
-
point.plotY = center[1];
|
1034
|
-
});
|
1035
|
-
},
|
1036
|
-
|
1037
|
-
/**
|
1038
|
-
* Draw the points where each point is one needle
|
1039
|
-
*/
|
1040
|
-
drawPoints: function () {
|
1041
|
-
|
1042
|
-
var series = this,
|
1043
|
-
center = series.yAxis.center,
|
1044
|
-
pivot = series.pivot,
|
1045
|
-
options = series.options,
|
1046
|
-
pivotOptions = options.pivot,
|
1047
|
-
renderer = series.chart.renderer;
|
1048
|
-
|
1049
|
-
each(series.points, function (point) {
|
1050
|
-
|
1051
|
-
var graphic = point.graphic,
|
1052
|
-
shapeArgs = point.shapeArgs,
|
1053
|
-
d = shapeArgs.d,
|
1054
|
-
dialOptions = merge(options.dial, point.dial); // #1233
|
1055
|
-
|
1056
|
-
if (graphic) {
|
1057
|
-
graphic.animate(shapeArgs);
|
1058
|
-
shapeArgs.d = d; // animate alters it
|
1059
|
-
} else {
|
1060
|
-
point.graphic = renderer[point.shapeType](shapeArgs)
|
1061
|
-
.attr({
|
1062
|
-
stroke: dialOptions.borderColor || 'none',
|
1063
|
-
'stroke-width': dialOptions.borderWidth || 0,
|
1064
|
-
fill: dialOptions.backgroundColor || 'black',
|
1065
|
-
rotation: shapeArgs.rotation // required by VML when animation is false
|
1066
|
-
})
|
1067
|
-
.add(series.group);
|
1068
|
-
}
|
1069
|
-
});
|
1070
|
-
|
1071
|
-
// Add or move the pivot
|
1072
|
-
if (pivot) {
|
1073
|
-
pivot.animate({ // #1235
|
1074
|
-
translateX: center[0],
|
1075
|
-
translateY: center[1]
|
1076
|
-
});
|
1077
|
-
} else {
|
1078
|
-
series.pivot = renderer.circle(0, 0, pick(pivotOptions.radius, 5))
|
1079
|
-
.attr({
|
1080
|
-
'stroke-width': pivotOptions.borderWidth || 0,
|
1081
|
-
stroke: pivotOptions.borderColor || 'silver',
|
1082
|
-
fill: pivotOptions.backgroundColor || 'black'
|
1083
|
-
})
|
1084
|
-
.translate(center[0], center[1])
|
1085
|
-
.add(series.group);
|
1086
|
-
}
|
1087
|
-
},
|
1088
|
-
|
1089
|
-
/**
|
1090
|
-
* Animate the arrow up from startAngle
|
1091
|
-
*/
|
1092
|
-
animate: function () {
|
1093
|
-
var series = this;
|
1094
|
-
|
1095
|
-
each(series.points, function (point) {
|
1096
|
-
var graphic = point.graphic;
|
1097
|
-
|
1098
|
-
if (graphic) {
|
1099
|
-
// start value
|
1100
|
-
graphic.attr({
|
1101
|
-
rotation: series.yAxis.startAngleRad * 180 / Math.PI
|
1102
|
-
});
|
1103
|
-
|
1104
|
-
// animate
|
1105
|
-
graphic.animate({
|
1106
|
-
rotation: point.shapeArgs.rotation
|
1107
|
-
}, series.options.animation);
|
1108
|
-
}
|
1109
|
-
});
|
1110
|
-
|
1111
|
-
// delete this function to allow it only once
|
1112
|
-
series.animate = null;
|
1113
|
-
},
|
1114
|
-
|
1115
|
-
render: function () {
|
1116
|
-
this.group = this.plotGroup(
|
1117
|
-
'group',
|
1118
|
-
'series',
|
1119
|
-
this.visible ? 'visible' : 'hidden',
|
1120
|
-
this.options.zIndex,
|
1121
|
-
this.chart.seriesGroup
|
1122
|
-
);
|
1123
|
-
seriesTypes.pie.prototype.render.call(this);
|
1124
|
-
this.group.clip(this.chart.clipRect);
|
1125
|
-
},
|
1126
|
-
|
1127
|
-
setData: seriesTypes.pie.prototype.setData,
|
1128
|
-
drawTracker: seriesTypes.column.prototype.drawTracker
|
1129
|
-
};
|
1130
|
-
seriesTypes.gauge = Highcharts.extendClass(seriesTypes.line, GaugeSeries);/**
|
1131
|
-
* Extensions for polar charts. Additionally, much of the geometry required for polar charts is
|
1132
|
-
* gathered in RadialAxes.js.
|
1133
|
-
*
|
1134
|
-
*/
|
1135
|
-
|
1136
|
-
var seriesProto = Series.prototype,
|
1137
|
-
mouseTrackerProto = Highcharts.MouseTracker.prototype;
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
/**
|
1142
|
-
* Translate a point's plotX and plotY from the internal angle and radius measures to
|
1143
|
-
* true plotX, plotY coordinates
|
1144
|
-
*/
|
1145
|
-
seriesProto.toXY = function (point) {
|
1146
|
-
var xy,
|
1147
|
-
chart = this.chart,
|
1148
|
-
plotX = point.plotX,
|
1149
|
-
plotY = point.plotY;
|
1150
|
-
|
1151
|
-
// Save rectangular plotX, plotY for later computation
|
1152
|
-
point.rectPlotX = plotX;
|
1153
|
-
point.rectPlotY = plotY;
|
1154
|
-
|
1155
|
-
// Record the angle in degrees for use in tooltip
|
1156
|
-
point.deg = plotX / Math.PI * 180;
|
1157
|
-
|
1158
|
-
// Find the polar plotX and plotY
|
1159
|
-
xy = this.xAxis.postTranslate(point.plotX, this.yAxis.len - plotY);
|
1160
|
-
point.plotX = point.polarPlotX = xy.x - chart.plotLeft;
|
1161
|
-
point.plotY = point.polarPlotY = xy.y - chart.plotTop;
|
1162
|
-
};
|
1163
|
-
|
1164
|
-
|
1165
|
-
/**
|
1166
|
-
* Add some special init logic to areas and areasplines
|
1167
|
-
*/
|
1168
|
-
function initArea(proceed, chart, options) {
|
1169
|
-
proceed.call(this, chart, options);
|
1170
|
-
if (this.chart.polar) {
|
1171
|
-
|
1172
|
-
/**
|
1173
|
-
* Overridden method to close a segment path. While in a cartesian plane the area
|
1174
|
-
* goes down to the threshold, in the polar chart it goes to the center.
|
1175
|
-
*/
|
1176
|
-
this.closeSegment = function (path) {
|
1177
|
-
var center = this.xAxis.center;
|
1178
|
-
path.push(
|
1179
|
-
'L',
|
1180
|
-
center[0],
|
1181
|
-
center[1]
|
1182
|
-
);
|
1183
|
-
};
|
1184
|
-
|
1185
|
-
// Instead of complicated logic to draw an area around the inner area in a stack,
|
1186
|
-
// just draw it behind
|
1187
|
-
this.closedStacks = true;
|
1188
|
-
}
|
1189
|
-
}
|
1190
|
-
wrap(seriesTypes.area.prototype, 'init', initArea);
|
1191
|
-
wrap(seriesTypes.areaspline.prototype, 'init', initArea);
|
1192
|
-
|
1193
|
-
|
1194
|
-
/**
|
1195
|
-
* Overridden method for calculating a spline from one point to the next
|
1196
|
-
*/
|
1197
|
-
wrap(seriesTypes.spline.prototype, 'getPointSpline', function (proceed, segment, point, i) {
|
1198
|
-
|
1199
|
-
var ret,
|
1200
|
-
smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc;
|
1201
|
-
denom = smoothing + 1,
|
1202
|
-
plotX,
|
1203
|
-
plotY,
|
1204
|
-
lastPoint,
|
1205
|
-
nextPoint,
|
1206
|
-
lastX,
|
1207
|
-
lastY,
|
1208
|
-
nextX,
|
1209
|
-
nextY,
|
1210
|
-
leftContX,
|
1211
|
-
leftContY,
|
1212
|
-
rightContX,
|
1213
|
-
rightContY,
|
1214
|
-
distanceLeftControlPoint,
|
1215
|
-
distanceRightControlPoint,
|
1216
|
-
leftContAngle,
|
1217
|
-
rightContAngle,
|
1218
|
-
jointAngle;
|
1219
|
-
|
1220
|
-
|
1221
|
-
if (this.chart.polar) {
|
1222
|
-
|
1223
|
-
plotX = point.plotX;
|
1224
|
-
plotY = point.plotY;
|
1225
|
-
lastPoint = segment[i - 1];
|
1226
|
-
nextPoint = segment[i + 1];
|
1227
|
-
|
1228
|
-
// Connect ends
|
1229
|
-
if (this.connectEnds) {
|
1230
|
-
if (!lastPoint) {
|
1231
|
-
lastPoint = segment[segment.length - 2]; // not the last but the second last, because the segment is already connected
|
1232
|
-
}
|
1233
|
-
if (!nextPoint) {
|
1234
|
-
nextPoint = segment[1];
|
1235
|
-
}
|
1236
|
-
}
|
1237
|
-
|
1238
|
-
// find control points
|
1239
|
-
if (lastPoint && nextPoint) {
|
1240
|
-
|
1241
|
-
lastX = lastPoint.plotX;
|
1242
|
-
lastY = lastPoint.plotY;
|
1243
|
-
nextX = nextPoint.plotX;
|
1244
|
-
nextY = nextPoint.plotY;
|
1245
|
-
leftContX = (smoothing * plotX + lastX) / denom;
|
1246
|
-
leftContY = (smoothing * plotY + lastY) / denom;
|
1247
|
-
rightContX = (smoothing * plotX + nextX) / denom;
|
1248
|
-
rightContY = (smoothing * plotY + nextY) / denom;
|
1249
|
-
distanceLeftControlPoint = Math.sqrt(Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2));
|
1250
|
-
distanceRightControlPoint = Math.sqrt(Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2));
|
1251
|
-
leftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);
|
1252
|
-
rightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);
|
1253
|
-
jointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);
|
1254
|
-
|
1255
|
-
|
1256
|
-
// Ensure the right direction, jointAngle should be in the same quadrant as leftContAngle
|
1257
|
-
if (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {
|
1258
|
-
jointAngle -= Math.PI;
|
1259
|
-
}
|
1260
|
-
|
1261
|
-
// Find the corrected control points for a spline straight through the point
|
1262
|
-
leftContX = plotX + Math.cos(jointAngle) * distanceLeftControlPoint;
|
1263
|
-
leftContY = plotY + Math.sin(jointAngle) * distanceLeftControlPoint;
|
1264
|
-
rightContX = plotX + Math.cos(Math.PI + jointAngle) * distanceRightControlPoint;
|
1265
|
-
rightContY = plotY + Math.sin(Math.PI + jointAngle) * distanceRightControlPoint;
|
1266
|
-
|
1267
|
-
// Record for drawing in next point
|
1268
|
-
point.rightContX = rightContX;
|
1269
|
-
point.rightContY = rightContY;
|
1270
|
-
|
1271
|
-
}
|
1272
|
-
|
1273
|
-
|
1274
|
-
// moveTo or lineTo
|
1275
|
-
if (!i) {
|
1276
|
-
ret = ['M', plotX, plotY];
|
1277
|
-
} else { // curve from last point to this
|
1278
|
-
ret = [
|
1279
|
-
'C',
|
1280
|
-
lastPoint.rightContX || lastPoint.plotX,
|
1281
|
-
lastPoint.rightContY || lastPoint.plotY,
|
1282
|
-
leftContX || plotX,
|
1283
|
-
leftContY || plotY,
|
1284
|
-
plotX,
|
1285
|
-
plotY
|
1286
|
-
];
|
1287
|
-
lastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later
|
1288
|
-
}
|
1289
|
-
|
1290
|
-
|
1291
|
-
} else {
|
1292
|
-
ret = proceed.call(this, segment, point, i);
|
1293
|
-
}
|
1294
|
-
return ret;
|
1295
|
-
});
|
1296
|
-
|
1297
|
-
/**
|
1298
|
-
* Extend translate. The plotX and plotY values are computed as if the polar chart were a
|
1299
|
-
* cartesian plane, where plotX denotes the angle in radians and (yAxis.len - plotY) is the pixel distance from
|
1300
|
-
* center.
|
1301
|
-
*/
|
1302
|
-
wrap(seriesProto, 'translate', function (proceed) {
|
1303
|
-
|
1304
|
-
// Run uber method
|
1305
|
-
proceed.call(this);
|
1306
|
-
|
1307
|
-
// Postprocess plot coordinates
|
1308
|
-
if (this.chart.polar && !this.preventPostTranslate) {
|
1309
|
-
var points = this.points,
|
1310
|
-
i = points.length;
|
1311
|
-
while (i--) {
|
1312
|
-
// Translate plotX, plotY from angle and radius to true plot coordinates
|
1313
|
-
this.toXY(points[i]);
|
1314
|
-
}
|
1315
|
-
}
|
1316
|
-
});
|
1317
|
-
|
1318
|
-
/**
|
1319
|
-
* Extend getSegmentPath to allow connecting ends across 0 to provide a closed circle in
|
1320
|
-
* line-like series.
|
1321
|
-
*/
|
1322
|
-
wrap(seriesProto, 'getSegmentPath', function (proceed, segment) {
|
1323
|
-
|
1324
|
-
var points = this.points;
|
1325
|
-
|
1326
|
-
// Connect the path
|
1327
|
-
if (this.chart.polar && this.options.connectEnds !== false &&
|
1328
|
-
segment[segment.length - 1] === points[points.length - 1] && points[0].y !== null) {
|
1329
|
-
this.connectEnds = true; // re-used in splines
|
1330
|
-
segment = [].concat(segment, [points[0]]);
|
1331
|
-
}
|
1332
|
-
|
1333
|
-
// Run uber method
|
1334
|
-
return proceed.call(this, segment);
|
1335
|
-
|
1336
|
-
});
|
1337
|
-
|
1338
|
-
|
1339
|
-
function polarAnimate(proceed, init) {
|
1340
|
-
var chart = this.chart,
|
1341
|
-
animation = this.options.animation,
|
1342
|
-
group = this.group,
|
1343
|
-
markerGroup = this.markerGroup,
|
1344
|
-
center = this.xAxis.center,
|
1345
|
-
plotLeft = chart.plotLeft,
|
1346
|
-
plotTop = chart.plotTop,
|
1347
|
-
attribs;
|
1348
|
-
|
1349
|
-
// Specific animation for polar charts
|
1350
|
-
if (chart.polar) {
|
1351
|
-
|
1352
|
-
// Enable animation on polar charts only in SVG. In VML, the scaling is different, plus animation
|
1353
|
-
// would be so slow it would't matter.
|
1354
|
-
if (chart.renderer.isSVG) {
|
1355
|
-
|
1356
|
-
if (animation === true) {
|
1357
|
-
animation = {};
|
1358
|
-
}
|
1359
|
-
|
1360
|
-
// Initialize the animation
|
1361
|
-
if (init) {
|
1362
|
-
|
1363
|
-
// Create an SVG specific attribute setter for scaleX and scaleY
|
1364
|
-
group.attrSetters.scaleX = group.attrSetters.scaleY = function (value, key) {
|
1365
|
-
this[key] = value;
|
1366
|
-
if (this.scaleX !== UNDEFINED && this.scaleY !== UNDEFINED) {
|
1367
|
-
this.element.setAttribute('transform', 'translate(' + this.translateX + ',' + this.translateY + ') scale(' +
|
1368
|
-
this.scaleX + ',' + this.scaleY + ')');
|
1369
|
-
}
|
1370
|
-
return false;
|
1371
|
-
};
|
1372
|
-
|
1373
|
-
// Scale down the group and place it in the center
|
1374
|
-
attribs = {
|
1375
|
-
translateX: center[0] + plotLeft,
|
1376
|
-
translateY: center[1] + plotTop,
|
1377
|
-
scaleX: 0,
|
1378
|
-
scaleY: 0
|
1379
|
-
};
|
1380
|
-
|
1381
|
-
group.attr(attribs);
|
1382
|
-
if (markerGroup) {
|
1383
|
-
markerGroup.attrSetters = group.attrSetters;
|
1384
|
-
markerGroup.attr(attribs);
|
1385
|
-
}
|
1386
|
-
|
1387
|
-
// Run the animation
|
1388
|
-
} else {
|
1389
|
-
attribs = {
|
1390
|
-
translateX: plotLeft,
|
1391
|
-
translateY: plotTop,
|
1392
|
-
scaleX: 1,
|
1393
|
-
scaleY: 1
|
1394
|
-
};
|
1395
|
-
group.animate(attribs, animation);
|
1396
|
-
if (markerGroup) {
|
1397
|
-
markerGroup.animate(attribs, animation);
|
1398
|
-
}
|
1399
|
-
|
1400
|
-
// Delete this function to allow it only once
|
1401
|
-
this.animate = null;
|
1402
|
-
}
|
1403
|
-
}
|
1404
|
-
|
1405
|
-
// For non-polar charts, revert to the basic animation
|
1406
|
-
} else {
|
1407
|
-
proceed.call(this, init);
|
1408
|
-
}
|
1409
|
-
}
|
1410
|
-
|
1411
|
-
// Define the animate method for both regular series and column series and their derivatives
|
1412
|
-
wrap(seriesProto, 'animate', polarAnimate);
|
1413
|
-
wrap(colProto, 'animate', polarAnimate);
|
1414
|
-
|
1415
|
-
|
1416
|
-
/**
|
1417
|
-
* Throw in a couple of properties to let setTooltipPoints know we're indexing the points
|
1418
|
-
* in degrees (0-360), not plot pixel width.
|
1419
|
-
*/
|
1420
|
-
wrap(seriesProto, 'setTooltipPoints', function (proceed, renew) {
|
1421
|
-
|
1422
|
-
if (this.chart.polar) {
|
1423
|
-
extend(this.xAxis, {
|
1424
|
-
tooltipLen: 360, // degrees are the resolution unit of the tooltipPoints array
|
1425
|
-
tooltipPosName: 'deg'
|
1426
|
-
});
|
1427
|
-
}
|
1428
|
-
|
1429
|
-
// Run uber method
|
1430
|
-
return proceed.call(this, renew);
|
1431
|
-
});
|
1432
|
-
|
1433
|
-
|
1434
|
-
/**
|
1435
|
-
* Extend the column prototype's translate method
|
1436
|
-
*/
|
1437
|
-
wrap(colProto, 'translate', function (proceed) {
|
1438
|
-
|
1439
|
-
var xAxis = this.xAxis,
|
1440
|
-
len = this.yAxis.len,
|
1441
|
-
center = xAxis.center,
|
1442
|
-
startAngleRad = xAxis.startAngleRad,
|
1443
|
-
renderer = this.chart.renderer,
|
1444
|
-
start,
|
1445
|
-
points,
|
1446
|
-
point,
|
1447
|
-
i;
|
1448
|
-
|
1449
|
-
this.preventPostTranslate = true;
|
1450
|
-
|
1451
|
-
// Run uber method
|
1452
|
-
proceed.call(this);
|
1453
|
-
|
1454
|
-
// Postprocess plot coordinates
|
1455
|
-
if (xAxis.isRadial) {
|
1456
|
-
points = this.points;
|
1457
|
-
i = points.length;
|
1458
|
-
while (i--) {
|
1459
|
-
point = points[i];
|
1460
|
-
start = point.barX + startAngleRad;
|
1461
|
-
point.shapeType = 'path';
|
1462
|
-
point.shapeArgs = {
|
1463
|
-
d: renderer.symbols.arc(
|
1464
|
-
center[0],
|
1465
|
-
center[1],
|
1466
|
-
len - point.plotY,
|
1467
|
-
null,
|
1468
|
-
{
|
1469
|
-
start: start,
|
1470
|
-
end: start + point.pointWidth,
|
1471
|
-
innerR: len - pick(point.yBottom, len)
|
1472
|
-
}
|
1473
|
-
)
|
1474
|
-
};
|
1475
|
-
this.toXY(point); // provide correct plotX, plotY for tooltip
|
1476
|
-
}
|
1477
|
-
}
|
1478
|
-
});
|
1479
|
-
|
1480
|
-
|
1481
|
-
/**
|
1482
|
-
* Align column data labels outside the columns. #1199.
|
1483
|
-
*/
|
1484
|
-
wrap(colProto, 'alignDataLabel', function (proceed, point, dataLabel, options, alignTo, isNew) {
|
1485
|
-
|
1486
|
-
if (this.chart.polar) {
|
1487
|
-
var angle = point.rectPlotX / Math.PI * 180,
|
1488
|
-
align,
|
1489
|
-
verticalAlign;
|
1490
|
-
|
1491
|
-
// Align nicely outside the perimeter of the columns
|
1492
|
-
if (options.align === null) {
|
1493
|
-
if (angle > 20 && angle < 160) {
|
1494
|
-
align = 'left'; // right hemisphere
|
1495
|
-
} else if (angle > 200 && angle < 340) {
|
1496
|
-
align = 'right'; // left hemisphere
|
1497
|
-
} else {
|
1498
|
-
align = 'center'; // top or bottom
|
1499
|
-
}
|
1500
|
-
options.align = align;
|
1501
|
-
}
|
1502
|
-
if (options.verticalAlign === null) {
|
1503
|
-
if (angle < 45 || angle > 315) {
|
1504
|
-
verticalAlign = 'bottom'; // top part
|
1505
|
-
} else if (angle > 135 && angle < 225) {
|
1506
|
-
verticalAlign = 'top'; // bottom part
|
1507
|
-
} else {
|
1508
|
-
verticalAlign = 'middle'; // left or right
|
1509
|
-
}
|
1510
|
-
options.verticalAlign = verticalAlign;
|
1511
|
-
}
|
1512
|
-
|
1513
|
-
seriesProto.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
|
1514
|
-
} else {
|
1515
|
-
proceed.call(this, point, dataLabel, options, alignTo, isNew);
|
1516
|
-
}
|
1517
|
-
|
1518
|
-
});
|
1519
|
-
|
1520
|
-
/**
|
1521
|
-
* Extend the mouse tracker to return the tooltip position index in terms of
|
1522
|
-
* degrees rather than pixels
|
1523
|
-
*/
|
1524
|
-
wrap(mouseTrackerProto, 'getIndex', function (proceed, e) {
|
1525
|
-
var ret,
|
1526
|
-
chart = this.chart,
|
1527
|
-
center,
|
1528
|
-
x,
|
1529
|
-
y;
|
1530
|
-
|
1531
|
-
if (chart.polar) {
|
1532
|
-
center = chart.xAxis[0].center;
|
1533
|
-
x = e.chartX - center[0] - chart.plotLeft;
|
1534
|
-
y = e.chartY - center[1] - chart.plotTop;
|
1535
|
-
|
1536
|
-
ret = 180 - Math.round(Math.atan2(x, y) / Math.PI * 180);
|
1537
|
-
|
1538
|
-
} else {
|
1539
|
-
|
1540
|
-
// Run uber method
|
1541
|
-
ret = proceed.call(this, e);
|
1542
|
-
}
|
1543
|
-
return ret;
|
1544
|
-
});
|
1545
|
-
|
1546
|
-
/**
|
1547
|
-
* Extend getMouseCoordinates to prepare for polar axis values
|
1548
|
-
*/
|
1549
|
-
wrap(mouseTrackerProto, 'getMouseCoordinates', function (proceed, e) {
|
1550
|
-
var chart = this.chart,
|
1551
|
-
ret = {
|
1552
|
-
xAxis: [],
|
1553
|
-
yAxis: []
|
1554
|
-
};
|
1555
|
-
|
1556
|
-
if (chart.polar) {
|
1557
|
-
|
1558
|
-
each(chart.axes, function (axis) {
|
1559
|
-
var isXAxis = axis.isXAxis,
|
1560
|
-
center = axis.center,
|
1561
|
-
x = e.chartX - center[0] - chart.plotLeft,
|
1562
|
-
y = e.chartY - center[1] - chart.plotTop;
|
1563
|
-
|
1564
|
-
ret[isXAxis ? 'xAxis' : 'yAxis'].push({
|
1565
|
-
axis: axis,
|
1566
|
-
value: axis.translate(
|
1567
|
-
isXAxis ?
|
1568
|
-
Math.PI - Math.atan2(x, y) : // angle
|
1569
|
-
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), // distance from center
|
1570
|
-
true
|
1571
|
-
)
|
1572
|
-
});
|
1573
|
-
});
|
1574
|
-
|
1575
|
-
} else {
|
1576
|
-
ret = proceed.call(this, e);
|
1577
|
-
}
|
1578
|
-
|
1579
|
-
return ret;
|
1580
|
-
});
|
1581
|
-
}(Highcharts));
|
1
|
+
/*
|
2
|
+
Highcharts JS v3.0.0 (2013-03-22)
|
3
|
+
|
4
|
+
(c) 2009-2013 Torstein Hønsi
|
5
|
+
|
6
|
+
License: www.highcharts.com/license
|
7
|
+
*/
|
8
|
+
(function(m,H){function K(a,b,c){this.init.call(this,a,b,c)}function L(a,b,c){a.call(this,b,c);if(this.chart.polar)this.closeSegment=function(a){var c=this.xAxis.center;a.push("L",c[0],c[1])},this.closedStacks=!0}function M(a,b){var c=this.chart,d=this.options.animation,e=this.group,g=this.markerGroup,f=this.xAxis.center,k=c.plotLeft,l=c.plotTop;if(c.polar){if(c.renderer.isSVG)if(d===!0&&(d={}),b){if(c={translateX:f[0]+k,translateY:f[1]+l,scaleX:0.001,scaleY:0.001},e.attr(c),g)g.attrSetters=e.attrSetters,
|
9
|
+
g.attr(c)}else c={translateX:k,translateY:l,scaleX:1,scaleY:1},e.animate(c,d),g&&g.animate(c,d),this.animate=null}else a.call(this,b)}var Q=m.arrayMin,R=m.arrayMax,s=m.each,G=m.extend,p=m.merge,S=m.map,r=m.pick,u=m.pInt,n=m.getOptions().plotOptions,h=m.seriesTypes,A=m.extendClass,N=m.splat,o=m.wrap,O=m.Axis,B=m.Tick,z=m.Series,q=h.column.prototype,v=Math,I=v.round,C=v.floor,J=v.ceil,T=v.min,U=v.max,w=function(){};G(K.prototype,{init:function(a,b,c){var d=this,e=d.defaultOptions;d.chart=b;if(b.angular)e.background=
|
10
|
+
{};d.options=a=p(e,a);(a=a.background)&&s([].concat(N(a)).reverse(),function(a){var b=a.backgroundColor,a=p(d.defaultBackgroundOptions,a);if(b)a.backgroundColor=b;a.color=a.backgroundColor;c.options.plotBands.unshift(a)})},defaultOptions:{center:["50%","50%"],size:"85%",startAngle:0},defaultBackgroundOptions:{shape:"circle",borderWidth:1,borderColor:"silver",backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,"#FFF"],[1,"#DDD"]]},from:Number.MIN_VALUE,innerRadius:0,to:Number.MAX_VALUE,
|
11
|
+
outerRadius:"105%"}});var F=O.prototype,B=B.prototype,V={getOffset:w,redraw:function(){this.isDirty=!1},render:function(){this.isDirty=!1},setScale:w,setCategories:w,setTitle:w},P={isRadial:!0,defaultRadialGaugeOptions:{labels:{align:"center",x:0,y:null},minorGridLineWidth:0,minorTickInterval:"auto",minorTickLength:10,minorTickPosition:"inside",minorTickWidth:1,plotBands:[],tickLength:10,tickPosition:"inside",tickWidth:2,title:{rotation:0},zIndex:2},defaultRadialXOptions:{gridLineWidth:1,labels:{align:null,
|
12
|
+
distance:15,x:0,y:null},maxPadding:0,minPadding:0,plotBands:[],showLastLabel:!1,tickLength:0},defaultRadialYOptions:{gridLineInterpolation:"circle",labels:{align:"right",x:-3,y:-2},plotBands:[],showLastLabel:!1,title:{x:4,text:null,rotation:90}},setOptions:function(a){this.options=p(this.defaultOptions,this.defaultRadialOptions,a)},getOffset:function(){F.getOffset.call(this);this.chart.axisOffset[this.side]=0;this.center=this.pane.center=h.pie.prototype.getCenter.call(this.pane)},getLinePath:function(a,
|
13
|
+
b){var c=this.center,b=r(b,c[2]/2-this.offset);return this.chart.renderer.symbols.arc(this.left+c[0],this.top+c[1],b,b,{start:this.startAngleRad,end:this.endAngleRad,open:!0,innerR:0})},setAxisTranslation:function(){F.setAxisTranslation.call(this);if(this.center&&(this.transA=this.isCircular?(this.endAngleRad-this.startAngleRad)/(this.max-this.min||1):this.center[2]/2/(this.max-this.min||1),this.isXAxis))this.minPixelPadding=this.transA*this.minPointOffset+(this.reversed?(this.endAngleRad-this.startAngleRad)/
|
14
|
+
4:0)},beforeSetTickPositions:function(){this.autoConnect&&(this.max+=this.categories&&1||this.pointRange||this.closestPointRange)},setAxisSize:function(){F.setAxisSize.call(this);if(this.center)this.len=this.width=this.height=this.isCircular?this.center[2]*(this.endAngleRad-this.startAngleRad)/2:this.center[2]/2},getPosition:function(a,b){if(!this.isCircular)b=this.translate(a),a=this.min;return this.postTranslate(this.translate(a),r(b,this.center[2]/2)-this.offset)},postTranslate:function(a,b){var c=
|
15
|
+
this.chart,d=this.center,a=this.startAngleRad+a;return{x:c.plotLeft+d[0]+Math.cos(a)*b,y:c.plotTop+d[1]+Math.sin(a)*b}},getPlotBandPath:function(a,b,c){var d=this.center,e=this.startAngleRad,g=d[2]/2,f=[r(c.outerRadius,"100%"),c.innerRadius,r(c.thickness,10)],k=/%$/,l,j=this.isCircular;this.options.gridLineInterpolation==="polygon"?d=this.getPlotLinePath(a).concat(this.getPlotLinePath(b,!0)):(j||(f[0]=this.translate(a),f[1]=this.translate(b)),f=S(f,function(a){k.test(a)&&(a=u(a,10)*g/100);return a}),
|
16
|
+
c.shape==="circle"||!j?(a=-Math.PI/2,b=Math.PI*1.5,l=!0):(a=e+this.translate(a),b=e+this.translate(b)),d=this.chart.renderer.symbols.arc(this.left+d[0],this.top+d[1],f[0],f[0],{start:a,end:b,innerR:r(f[1],f[0]-f[2]),open:l}));return d},getPlotLinePath:function(a,b){var c=this.center,d=this.chart,e=this.getPosition(a),g,f,k;this.isCircular?k=["M",c[0]+d.plotLeft,c[1]+d.plotTop,"L",e.x,e.y]:this.options.gridLineInterpolation==="circle"?(a=this.translate(a))&&(k=this.getLinePath(0,a)):(g=d.xAxis[0],
|
17
|
+
k=[],a=this.translate(a),c=g.tickPositions,g.autoConnect&&(c=c.concat([c[0]])),b&&(c=[].concat(c).reverse()),s(c,function(c,b){f=g.getPosition(c,a);k.push(b?"L":"M",f.x,f.y)}));return k},getTitlePosition:function(){var a=this.center,b=this.chart,c=this.options.title;return{x:b.plotLeft+a[0]+(c.x||0),y:b.plotTop+a[1]-{high:0.5,middle:0.25,low:0}[c.align]*a[2]+(c.y||0)}}};o(F,"init",function(a,b,c){var i;var d=b.angular,e=b.polar,g=c.isX,f=d&&g,k,l;l=b.options;var j=c.pane||0;if(d){if(G(this,f?V:P),
|
18
|
+
k=!g)this.defaultRadialOptions=this.defaultRadialGaugeOptions}else if(e)G(this,P),this.defaultRadialOptions=(k=g)?this.defaultRadialXOptions:p(this.defaultYAxisOptions,this.defaultRadialYOptions);a.call(this,b,c);if(!f&&(d||e)){a=this.options;if(!b.panes)b.panes=[];this.pane=(i=b.panes[j]=b.panes[j]||new K(N(l.pane)[j],b,this),j=i);j=j.options;b.inverted=!1;l.chart.zoomType=null;this.startAngleRad=b=(j.startAngle-90)*Math.PI/180;this.endAngleRad=l=(r(j.endAngle,j.startAngle+360)-90)*Math.PI/180;this.offset=
|
19
|
+
a.offset||0;if((this.isCircular=k)&&c.max===H&&l-b===2*Math.PI)this.autoConnect=!0}});o(B,"getPosition",function(a,b,c,d,e){var g=this.axis;return g.getPosition?g.getPosition(c):a.call(this,b,c,d,e)});o(B,"getLabelPosition",function(a,b,c,d,e,g,f,k,l){var j=this.axis,i=g.y,h=g.align,y=(j.translate(this.pos)+j.startAngleRad+Math.PI/2)/Math.PI*180;j.isRadial?(a=j.getPosition(this.pos,j.center[2]/2+r(g.distance,-25)),g.rotation==="auto"?d.attr({rotation:y}):i===null&&(i=u(d.styles.lineHeight)*0.9-d.getBBox().height/
|
20
|
+
2),h===null&&(h=j.isCircular?y>20&&y<160?"left":y>200&&y<340?"right":"center":"center",d.attr({align:h})),a.x+=g.x,a.y+=i):a=a.call(this,b,c,d,e,g,f,k,l);return a});o(B,"getMarkPath",function(a,b,c,d,e,g,f){var k=this.axis;k.isRadial?(a=k.getPosition(this.pos,k.center[2]/2+d),b=["M",b,c,"L",a.x,a.y]):b=a.call(this,b,c,d,e,g,f);return b});n.arearange=p(n.area,{lineWidth:1,marker:null,threshold:null,tooltip:{pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>'},
|
21
|
+
trackByArea:!0,dataLabels:{verticalAlign:null,xLow:0,xHigh:0,yLow:0,yHigh:0}});h.arearange=m.extendClass(h.area,{type:"arearange",pointArrayMap:["low","high"],toYData:function(a){return[a.low,a.high]},pointValKey:"low",translate:function(){var a=this.yAxis;h.area.prototype.translate.apply(this);s(this.points,function(b){if(b.y!==null)b.plotLow=b.plotY,b.plotHigh=a.translate(b.high,0,1,0,1)})},getSegmentPath:function(a){var b=[],c=a.length,d=z.prototype.getSegmentPath,e,g;g=this.options;for(var f=
|
22
|
+
g.step;c--;)e=a[c],b.push({plotX:e.plotX,plotY:e.plotHigh});a=d.call(this,a);if(f)f===!0&&(f="left"),g.step={left:"right",center:"center",right:"left"}[f];b=d.call(this,b);g.step=f;g=[].concat(a,b);b[0]="L";this.areaPath=this.areaPath.concat(a,b);return g},drawDataLabels:function(){var a=this.data,b=a.length,c,d=[],e=z.prototype,g=this.options.dataLabels,f,k=this.chart.inverted;if(g.enabled||this._hasPointLabels){for(c=b;c--;)f=a[c],f.y=f.high,f.plotY=f.plotHigh,d[c]=f.dataLabel,f.dataLabel=f.dataLabelUpper,
|
23
|
+
f.below=!1,k?(g.align="left",g.x=g.xHigh):g.y=g.yHigh;e.drawDataLabels.apply(this,arguments);for(c=b;c--;)f=a[c],f.dataLabelUpper=f.dataLabel,f.dataLabel=d[c],f.y=f.low,f.plotY=f.plotLow,f.below=!0,k?(g.align="right",g.x=g.xLow):g.y=g.yLow;e.drawDataLabels.apply(this,arguments)}},alignDataLabel:h.column.prototype.alignDataLabel,getSymbol:h.column.prototype.getSymbol,drawPoints:w});n.areasplinerange=p(n.arearange);h.areasplinerange=A(h.arearange,{type:"areasplinerange",getPointSpline:h.spline.prototype.getPointSpline});
|
24
|
+
n.columnrange=p(n.column,n.arearange,{lineWidth:1,pointRange:null});h.columnrange=A(h.arearange,{type:"columnrange",translate:function(){var a=this.yAxis,b;q.translate.apply(this);s(this.points,function(c){var d=c.shapeArgs;c.plotHigh=b=a.translate(c.high,0,1,0,1);c.plotLow=c.plotY;d.y=b;d.height=c.plotY-b})},trackerGroups:["group","dataLabels"],drawGraph:w,pointAttrToOptions:q.pointAttrToOptions,drawPoints:q.drawPoints,drawTracker:q.drawTracker,animate:q.animate,getColumnMetrics:q.getColumnMetrics});
|
25
|
+
n.gauge=p(n.line,{dataLabels:{enabled:!0,y:15,borderWidth:1,borderColor:"silver",borderRadius:3,style:{fontWeight:"bold"},verticalAlign:"top",zIndex:2},dial:{},pivot:{},tooltip:{headerFormat:""},showInLegend:!1});B={type:"gauge",pointClass:m.extendClass(m.Point,{setState:function(a){this.state=a}}),angular:!0,drawGraph:w,trackerGroups:["group","dataLabels"],translate:function(){var a=this.yAxis,b=this.options,c=a.center;this.generatePoints();s(this.points,function(d){var e=p(b.dial,d.dial),g=u(r(e.radius,
|
26
|
+
80))*c[2]/200,f=u(r(e.baseLength,70))*g/100,k=u(r(e.rearLength,10))*g/100,l=e.baseWidth||3,j=e.topWidth||1,i=a.startAngleRad+a.translate(d.y,null,null,null,!0);b.wrap===!1&&(i=Math.max(a.startAngleRad,Math.min(a.endAngleRad,i)));i=i*180/Math.PI;d.shapeType="path";d.shapeArgs={d:e.path||["M",-k,-l/2,"L",f,-l/2,g,-j/2,g,j/2,f,l/2,-k,l/2,"z"],translateX:c[0],translateY:c[1],rotation:i};d.plotX=c[0];d.plotY=c[1]})},drawPoints:function(){var a=this,b=a.yAxis.center,c=a.pivot,d=a.options,e=d.pivot,g=a.chart.renderer;
|
27
|
+
s(a.points,function(c){var b=c.graphic,e=c.shapeArgs,j=e.d,i=p(d.dial,c.dial);b?(b.animate(e),e.d=j):c.graphic=g[c.shapeType](e).attr({stroke:i.borderColor||"none","stroke-width":i.borderWidth||0,fill:i.backgroundColor||"black",rotation:e.rotation}).add(a.group)});c?c.animate({translateX:b[0],translateY:b[1]}):a.pivot=g.circle(0,0,r(e.radius,5)).attr({"stroke-width":e.borderWidth||0,stroke:e.borderColor||"silver",fill:e.backgroundColor||"black"}).translate(b[0],b[1]).add(a.group)},animate:function(a){var b=
|
28
|
+
this;if(!a)s(b.points,function(a){var d=a.graphic;d&&(d.attr({rotation:b.yAxis.startAngleRad*180/Math.PI}),d.animate({rotation:a.shapeArgs.rotation},b.options.animation))}),b.animate=null},render:function(){this.group=this.plotGroup("group","series",this.visible?"visible":"hidden",this.options.zIndex,this.chart.seriesGroup);h.pie.prototype.render.call(this);this.group.clip(this.chart.clipRect)},setData:h.pie.prototype.setData,drawTracker:h.column.prototype.drawTracker};h.gauge=m.extendClass(h.line,
|
29
|
+
B);n.boxplot=p(n.column,{fillColor:"#FFFFFF",lineWidth:1,medianWidth:2,states:{hover:{brightness:-0.3}},threshold:null,tooltip:{pointFormat:'<span style="color:{series.color};font-weight:bold">{series.name}</span><br/>Minimum: {point.low}<br/>Lower quartile: {point.q1}<br/>Median: {point.median}<br/>Higher quartile: {point.q3}<br/>Maximum: {point.high}<br/>'},whiskerLength:"50%",whiskerWidth:2});h.boxplot=A(h.column,{type:"boxplot",pointArrayMap:["low","q1","median","q3","high"],toYData:function(a){return[a.low,
|
30
|
+
a.q1,a.median,a.q3,a.high]},pointValKey:"high",pointAttrToOptions:{fill:"fillColor",stroke:"color","stroke-width":"lineWidth"},drawDataLabels:w,translate:function(){var a=this.yAxis,b=this.pointArrayMap;h.column.prototype.translate.apply(this);s(this.points,function(c){s(b,function(b){c[b]!==null&&(c[b+"Plot"]=a.translate(c[b],0,1,0,1))})})},drawPoints:function(){var a=this,b=a.points,c=a.options,d=a.chart.renderer,e,g,f,k,l,j,i,h,y,m,t,n,o,x,r,p,v,q,w,u,B,A,z=a.doQuartiles!==!1,D=parseInt(a.options.whiskerLength,
|
31
|
+
10)/100;s(b,function(b){y=b.graphic;B=b.shapeArgs;t={};x={};p={};A=b.color||a.color;if(b.plotY!==H)if(e=b.pointAttr[b.selected?"selected":""],v=B.width,q=C(B.x),w=q+v,u=I(v/2),g=C(z?b.q1Plot:b.lowPlot),f=C(z?b.q3Plot:b.lowPlot),k=C(b.highPlot),l=C(b.lowPlot),t.stroke=b.stemColor||c.stemColor||A,t["stroke-width"]=b.stemWidth||c.stemWidth||c.lineWidth,t.dashstyle=b.stemDashStyle||c.stemDashStyle,x.stroke=b.whiskerColor||c.whiskerColor||A,x["stroke-width"]=b.whiskerWidth||c.whiskerWidth||c.lineWidth,
|
32
|
+
p.stroke=b.medianColor||c.medianColor||A,p["stroke-width"]=b.medianWidth||c.medianWidth||c.lineWidth,i=t["stroke-width"]%2/2,h=q+u+i,m=["M",h,f,"L",h,k,"M",h,g,"L",h,l,"z"],z&&(i=e["stroke-width"]%2/2,h=C(h)+i,g=C(g)+i,f=C(f)+i,q+=i,w+=i,n=["M",q,f,"L",q,g,"L",w,g,"L",w,f,"L",q,f,"z"]),D&&(i=x["stroke-width"]%2/2,k+=i,l+=i,o=["M",h-u*D,k,"L",h+u*D,k,"M",h-u*D,l,"L",h+u*D,l]),i=p["stroke-width"]%2/2,j=I(b.medianPlot)+i,r=["M",q,j,w,j,"z"],y)b.stem.animate({d:m}),D&&b.whiskers.animate({d:o}),z&&b.box.animate({d:n}),
|
33
|
+
b.medianShape.animate({d:r});else{b.graphic=y=d.g().add(a.group);b.stem=d.path(m).attr(t).add(y);if(D)b.whiskers=d.path(o).attr(x).add(y);if(z)b.box=d.path(n).attr(e).add(y);b.medianShape=d.path(r).attr(p).add(y)}})}});n.errorbar=p(n.boxplot,{color:"#000000",grouping:!1,linkedTo:":previous",tooltip:{pointFormat:n.arearange.tooltip.pointFormat},whiskerWidth:null});h.errorbar=A(h.boxplot,{type:"errorbar",pointArrayMap:["low","high"],toYData:function(a){return[a.low,a.high]},pointValKey:"high",doQuartiles:!1,
|
34
|
+
getColumnMetrics:function(){return this.linkedParent&&this.linkedParent.columnMetrics||h.column.prototype.getColumnMetrics.call(this)}});o(F,"getSeriesExtremes",function(a,b){a.call(this,b);if(!this.isXAxis){var c=this,d=[],e=!0;s(c.series,function(a){if(a.visible&&a.stackKey&&!(a.type!=="waterfall"||HighchartsAdapter.inArray(a.stackKey)!==-1)){if(e)c.dataMin=c.dataMax=null,e=!1;var b=a.processedYData,k=b.length,h=b[0],j=b[0],i=a.options.threshold,m=c.stacks,n=a.stackKey,p="-"+n,t,o,q,x;for(x=0;x<
|
35
|
+
k;x++){q=b[x]<i?p:n;t=m[q][x].total;if(x>i)t+=o,m[q][x].setTotal(t),m[q][x]._cum=null;t<h&&(h=t);t>j&&(j=t);o=t}a.dataMin=h;a.dataMax=j;c.dataMin=T(r(c.dataMin,h),h,i);c.dataMax=U(r(c.dataMax,j),j,i);d.push(a.stackKey);if(typeof i==="number")if(c.dataMin>=i)c.dataMin=i,c.ignoreMinPadding=!0;else if(c.dataMax<i)c.dataMax=i,c.ignoreMaxPadding=!0}})}});n.waterfall=p(n.column,{lineWidth:1,lineColor:"#333",dashStyle:"dot",borderColor:"#333"});h.waterfall=A(h.column,{type:"waterfall",upColorProp:"fill",
|
36
|
+
pointArrayMap:["y","low"],pointValKey:"y",init:function(a,b){b.stacking=!0;h.column.prototype.init.call(this,a,b)},translate:function(){var a=this.yAxis,b,c,d,e,g,f,k,l,j,i,m,n,o=this.options.borderWidth%2/2;h.column.prototype.translate.apply(this);d=this.points;j=k=d[0];f=l=d[0].y;for(c=1,b=d.length;c<b;c++)e=d[c],g=e.shapeArgs,i=this.getStack(c),m=this.getStack(c-1),n=this.getStackY(m),j===null&&(j=e,l=0),e.y&&!e.isSum&&!e.isIntermediateSum&&(f+=e.y,l+=e.y),e.isSum||e.isIntermediateSum?(e.isIntermediateSum?
|
37
|
+
(i=this.getSumEdges(j,d[c-1]),e.y=l,j=null):(i=this.getSumEdges(k,d[c-1]),e.y=f),g.y=e.plotY=i[1],g.height=i[0]-i[1]):e.y<0?(m=i._cum===null?m.total:i._cum,i._cum=m+e.y,e=J(a.translate(m,0,1))-o,i=a.translate(i._cum,0,1),g.y=e,g.height=J(i-e)):g.height=C(n-g.y)},processData:function(a){z.prototype.processData.call(this,a);var a=this.yData,b=a.length,c,d;for(d=0;d<b;d++)c=a[d],c!==null&&typeof c!=="number"&&(a[d]=c==="sum"?null:c==="intermediateSum"?null:c[0])},toYData:function(a){if(a.isSum)return"sum";
|
38
|
+
else if(a.isIntermediateSum)return"intermediateSum";return[a.y]},getAttribs:function(){h.column.prototype.getAttribs.apply(this,arguments);var a=this.options,b=a.states,c=a.upColor||this.color,a=m.Color(c).brighten(0.1).get(),d=p(this.pointAttr),e=this.upColorProp;d[""][e]=c;d.hover[e]=b.hover.upColor||a;d.select[e]=b.select.upColor||c;s(this.points,function(a){if(a.y>0&&!a.color)a.pointAttr=d,a.color=c})},getGraphPath:function(){var a=this.data,b=a.length,c=I(this.options.lineWidth+this.options.borderWidth)%
|
39
|
+
2/2,d=[],e,g,f;for(f=1;f<b;f++)g=a[f].shapeArgs,e=a[f-1].shapeArgs,g=["M",e.x+e.width,e.y+c,"L",g.x,e.y+c],a[f-1].y<0&&(g[2]+=e.height,g[5]+=e.height),d=d.concat(g);return d},getStack:function(a){var b=this.yAxis.stacks,c=this.stackKey;this.processedYData[a]<this.options.threshold&&(c="-"+c);return b[c][a]},getStackY:function(a){return J(this.yAxis.translate(a.total,null,!0))},getSumEdges:function(a,b){var c,d,e;d=this.options.threshold;c=a.y>=d?a.shapeArgs.y+a.shapeArgs.height:a.shapeArgs.y;d=b.y>=
|
40
|
+
d?b.shapeArgs.y:b.shapeArgs.y+b.shapeArgs.height;d>c&&(e=c,c=d,d=e);return[c,d]},drawGraph:z.prototype.drawGraph});n.bubble=p(n.scatter,{dataLabels:{inside:!0,style:{color:"white",textShadow:"0px 0px 3px black"},verticalAlign:"middle"},marker:{lineColor:null,lineWidth:1},minSize:8,maxSize:"20%",tooltip:{pointFormat:"({point.x}, {point.y}), Size: {point.z}"},zThreshold:0});h.bubble=A(h.scatter,{type:"bubble",pointArrayMap:["y","z"],trackerGroups:["group","dataLabelsGroup"],pointAttrToOptions:{stroke:"lineColor",
|
41
|
+
"stroke-width":"lineWidth",fill:"fillColor"},applyOpacity:function(a){var b=this.options.marker,c=r(b.fillOpacity,0.5),a=a||b.fillColor||this.color;c!==1&&(a=m.Color(a).setOpacity(c).get("rgba"));return a},convertAttribs:function(){var a=z.prototype.convertAttribs.apply(this,arguments);a.fill=this.applyOpacity(a.fill);return a},getRadii:function(a,b,c,d){var e,g,f,k=this.zData,h=[];for(g=0,e=k.length;g<e;g++)f=b-a,f=f>0?(k[g]-a)/(b-a):0.5,h.push(v.round(c+f*(d-c))/2);this.radii=h},animate:function(a){var b=
|
42
|
+
this.options.animation;if(!a)s(this.points,function(a){var d=a.graphic,a=a.shapeArgs;d&&a&&(d.attr("r",1),d.animate({r:a.r},b))}),this.animate=null},translate:function(){var a,b=this.data,c,d,e=this.radii;h.scatter.prototype.translate.call(this);for(a=b.length;a--;)c=b[a],d=e[a],c.negative=c.z<(this.options.zThreshold||0),d>=this.minPxSize/2?(c.shapeType="circle",c.shapeArgs={x:c.plotX,y:c.plotY,r:d},c.dlBox={x:c.plotX-d,y:c.plotY-d,width:2*d,height:2*d}):c.shapeArgs=c.plotY=c.dlBox=null},drawLegendSymbol:function(a,
|
43
|
+
b){var c=u(a.itemStyle.fontSize)/2;b.legendSymbol=this.chart.renderer.circle(c,a.baseline-c,c).attr({zIndex:3}).add(b.legendGroup)},drawPoints:h.column.prototype.drawPoints,alignDataLabel:h.column.prototype.alignDataLabel});O.prototype.beforePadding=function(){var a=this.len,b=this.chart,c=0,d=a,e=this.isXAxis,g=e?"xData":"yData",f=this.min,k={},h=v.min(b.plotWidth,b.plotHeight),j=Number.MAX_VALUE,i=-Number.MAX_VALUE,m=this.max-f,n=a/m,o=[];this.tickPositions&&(s(this.series,function(a){var b=a.options;
|
44
|
+
if(a.type==="bubble"&&a.visible&&(o.push(a),e))s(["minSize","maxSize"],function(a){var c=b[a],d=/%$/.test(c),c=u(c);k[a]=d?h*c/100:c}),a.minPxSize=k.minSize,a=a.zData,j=v.min(j,v.max(Q(a),b.displayNegative===!1?b.zThreshold:-Number.MAX_VALUE)),i=v.max(i,R(a))}),s(o,function(a){var b=a[g],h=b.length,l;e&&a.getRadii(j,i,k.minSize,k.maxSize);if(m>0)for(;h--;)l=a.radii[h],c=Math.min((b[h]-f)*n-l,c),d=Math.max((b[h]-f)*n+l,d)}),m>0&&r(this.options.min,this.userMin)===H&&(d-=a,n*=(a+c-d)/a,this.min+=c/
|
45
|
+
n,this.max+=d/n))};var E=z.prototype,n=m.Pointer.prototype;E.toXY=function(a){var b,c=this.chart;b=a.plotX;var d=a.plotY;a.rectPlotX=b;a.rectPlotY=d;a.clientX=b/Math.PI*180;b=this.xAxis.postTranslate(a.plotX,this.yAxis.len-d);a.plotX=a.polarPlotX=b.x-c.plotLeft;a.plotY=a.polarPlotY=b.y-c.plotTop};o(h.area.prototype,"init",L);o(h.areaspline.prototype,"init",L);o(h.spline.prototype,"getPointSpline",function(a,b,c,d){var e,g,f,h,l,j,i;if(this.chart.polar){e=c.plotX;g=c.plotY;a=b[d-1];f=b[d+1];this.connectEnds&&
|
46
|
+
(a||(a=b[b.length-2]),f||(f=b[1]));if(a&&f)h=a.plotX,l=a.plotY,b=f.plotX,j=f.plotY,h=(1.5*e+h)/2.5,l=(1.5*g+l)/2.5,f=(1.5*e+b)/2.5,i=(1.5*g+j)/2.5,b=Math.sqrt(Math.pow(h-e,2)+Math.pow(l-g,2)),j=Math.sqrt(Math.pow(f-e,2)+Math.pow(i-g,2)),h=Math.atan2(l-g,h-e),l=Math.atan2(i-g,f-e),i=Math.PI/2+(h+l)/2,Math.abs(h-i)>Math.PI/2&&(i-=Math.PI),h=e+Math.cos(i)*b,l=g+Math.sin(i)*b,f=e+Math.cos(Math.PI+i)*j,i=g+Math.sin(Math.PI+i)*j,c.rightContX=f,c.rightContY=i;d?(c=["C",a.rightContX||a.plotX,a.rightContY||
|
47
|
+
a.plotY,h||e,l||g,e,g],a.rightContX=a.rightContY=null):c=["M",e,g]}else c=a.call(this,b,c,d);return c});o(E,"translate",function(a){a.call(this);if(this.chart.polar&&!this.preventPostTranslate)for(var a=this.points,b=a.length;b--;)this.toXY(a[b])});o(E,"getSegmentPath",function(a,b){var c=this.points;if(this.chart.polar&&this.options.connectEnds!==!1&&b[b.length-1]===c[c.length-1]&&c[0].y!==null)this.connectEnds=!0,b=[].concat(b,[c[0]]);return a.call(this,b)});o(E,"animate",M);o(q,"animate",M);o(E,
|
48
|
+
"setTooltipPoints",function(a,b){this.chart.polar&&G(this.xAxis,{tooltipLen:360});return a.call(this,b)});o(q,"translate",function(a){var b=this.xAxis,c=this.yAxis.len,d=b.center,e=b.startAngleRad,g=this.chart.renderer,f,h;this.preventPostTranslate=!0;a.call(this);if(b.isRadial){b=this.points;for(h=b.length;h--;)f=b[h],a=f.barX+e,f.shapeType="path",f.shapeArgs={d:g.symbols.arc(d[0],d[1],c-f.plotY,null,{start:a,end:a+f.pointWidth,innerR:c-r(f.yBottom,c)})},this.toXY(f)}});o(q,"alignDataLabel",function(a,
|
49
|
+
b,c,d,e,g){if(this.chart.polar){a=b.rectPlotX/Math.PI*180;if(d.align===null)d.align=a>20&&a<160?"left":a>200&&a<340?"right":"center";if(d.verticalAlign===null)d.verticalAlign=a<45||a>315?"bottom":a>135&&a<225?"top":"middle";E.alignDataLabel.call(this,b,c,d,e,g)}else a.call(this,b,c,d,e,g)});o(n,"getIndex",function(a,b){var c,d=this.chart,e;d.polar?(e=d.xAxis[0].center,c=b.chartX-e[0]-d.plotLeft,d=b.chartY-e[1]-d.plotTop,c=180-Math.round(Math.atan2(c,d)/Math.PI*180)):c=a.call(this,b);return c});o(n,
|
50
|
+
"getCoordinates",function(a,b){var c=this.chart,d={xAxis:[],yAxis:[]};c.polar?s(c.axes,function(a){var g=a.isXAxis,f=a.center,h=b.chartX-f[0]-c.plotLeft,f=b.chartY-f[1]-c.plotTop;d[g?"xAxis":"yAxis"].push({axis:a,value:a.translate(g?Math.PI-Math.atan2(h,f):Math.sqrt(Math.pow(h,2)+Math.pow(f,2)),!0)})}):d=a.call(this,b);return d})})(Highcharts);
|