highcharts-rails 5.0.14 → 6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +60 -0
- data/Rakefile +54 -5
- data/app/assets/images/highcharts/earth.svg +432 -0
- data/app/assets/javascripts/highcharts.js +5103 -3147
- data/app/assets/javascripts/highcharts/highcharts-3d.js +930 -277
- data/app/assets/javascripts/highcharts/highcharts-more.js +1374 -249
- data/app/assets/javascripts/highcharts/lib/canvg.js +3073 -0
- data/app/assets/javascripts/highcharts/lib/jspdf.js +16624 -0
- data/app/assets/javascripts/highcharts/lib/rgbcolor.js +299 -0
- data/app/assets/javascripts/highcharts/lib/svg2pdf.js +3488 -0
- data/app/assets/javascripts/highcharts/modules/accessibility.js +654 -212
- data/app/assets/javascripts/highcharts/modules/annotations.js +1552 -274
- data/app/assets/javascripts/highcharts/modules/boost-canvas.js +773 -0
- data/app/assets/javascripts/highcharts/modules/boost.js +636 -210
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +2 -2
- data/app/assets/javascripts/highcharts/modules/bullet.js +364 -0
- data/app/assets/javascripts/highcharts/modules/data.js +766 -38
- data/app/assets/javascripts/highcharts/modules/drag-panes.js +588 -0
- data/app/assets/javascripts/highcharts/modules/drilldown.js +106 -36
- data/app/assets/javascripts/highcharts/modules/export-data.js +597 -0
- data/app/assets/javascripts/highcharts/modules/exporting.js +424 -162
- data/app/assets/javascripts/highcharts/modules/funnel.js +144 -22
- data/app/assets/javascripts/highcharts/modules/gantt.js +1154 -0
- data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
- data/app/assets/javascripts/highcharts/modules/heatmap.js +406 -80
- data/app/assets/javascripts/highcharts/modules/histogram-bellcurve.js +513 -0
- data/app/assets/javascripts/highcharts/modules/item-series.js +126 -0
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +31 -13
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +179 -57
- data/app/assets/javascripts/highcharts/modules/oldie.js +1378 -0
- data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +8 -6
- data/app/assets/javascripts/highcharts/modules/parallel-coordinates.js +494 -0
- data/app/assets/javascripts/highcharts/modules/pareto.js +275 -0
- data/app/assets/javascripts/highcharts/modules/sankey.js +641 -0
- data/app/assets/javascripts/highcharts/modules/series-label.js +355 -145
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +122 -1
- data/app/assets/javascripts/highcharts/modules/static-scale.js +64 -0
- data/app/assets/javascripts/highcharts/modules/stock.js +1944 -676
- data/app/assets/javascripts/highcharts/modules/streamgraph.js +139 -0
- data/app/assets/javascripts/highcharts/modules/sunburst.js +2403 -0
- data/app/assets/javascripts/highcharts/modules/tilemap.js +1199 -0
- data/app/assets/javascripts/highcharts/modules/treemap.js +538 -134
- data/app/assets/javascripts/highcharts/modules/variable-pie.js +490 -0
- data/app/assets/javascripts/highcharts/modules/variwide.js +283 -0
- data/app/assets/javascripts/highcharts/modules/vector.js +294 -0
- data/app/assets/javascripts/highcharts/modules/windbarb.js +490 -0
- data/app/assets/javascripts/highcharts/modules/wordcloud.js +681 -0
- data/app/assets/javascripts/highcharts/modules/xrange.js +615 -0
- data/app/assets/javascripts/highcharts/themes/avocado.js +54 -0
- data/app/assets/javascripts/highcharts/themes/dark-blue.js +6 -6
- data/app/assets/javascripts/highcharts/themes/dark-green.js +6 -6
- data/app/assets/javascripts/highcharts/themes/dark-unica.js +6 -6
- data/app/assets/javascripts/highcharts/themes/gray.js +14 -10
- data/app/assets/javascripts/highcharts/themes/grid-light.js +6 -6
- data/app/assets/javascripts/highcharts/themes/grid.js +7 -5
- data/app/assets/javascripts/highcharts/themes/sand-signika.js +8 -7
- data/app/assets/javascripts/highcharts/themes/skies.js +15 -9
- data/app/assets/javascripts/highcharts/themes/sunset.js +53 -0
- data/app/assets/stylesheets/highcharts/highcharts.css +802 -0
- data/app/assets/stylesheets/highcharts/highcharts.scss +665 -0
- data/lib/highcharts/version.rb +1 -1
- metadata +31 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v6.0.0 (2017-10-04)
|
3
3
|
*
|
4
4
|
* (c) 2009-2017 Torstein Honsi
|
5
5
|
*
|
@@ -20,11 +20,10 @@
|
|
20
20
|
* License: www.highcharts.com/license
|
21
21
|
*/
|
22
22
|
/**
|
23
|
-
*
|
23
|
+
* Highcharts module to place labels next to a series in a natural position.
|
24
24
|
*
|
25
25
|
* TODO:
|
26
26
|
* - add column support (box collision detection, boxesToAvoid logic)
|
27
|
-
* - other series types, area etc.
|
28
27
|
* - avoid data labels, when data labels above, show series label below.
|
29
28
|
* - add more options (connector, format, formatter)
|
30
29
|
*
|
@@ -40,41 +39,92 @@
|
|
40
39
|
each = H.each,
|
41
40
|
extend = H.extend,
|
42
41
|
isNumber = H.isNumber,
|
42
|
+
pick = H.pick,
|
43
43
|
Series = H.Series,
|
44
44
|
SVGRenderer = H.SVGRenderer,
|
45
45
|
Chart = H.Chart;
|
46
46
|
|
47
47
|
H.setOptions({
|
48
|
+
/**
|
49
|
+
* @optionparent plotOptions
|
50
|
+
*/
|
48
51
|
plotOptions: {
|
49
52
|
series: {
|
50
|
-
|
51
53
|
/**
|
54
|
+
* Series labels are placed as close to the series as possible in a
|
55
|
+
* natural way, seeking to avoid other series. The goal of this
|
56
|
+
* feature is to make the chart more easily readable, like if a
|
57
|
+
* human designer placed the labels in the optimal position.
|
58
|
+
*
|
59
|
+
* The series labels currently work with series types having a
|
60
|
+
* `graph` or an `area`.
|
61
|
+
*
|
62
|
+
* Requires the `series-label.js` module.
|
63
|
+
*
|
64
|
+
* @sample highcharts/series-label/line-chart
|
65
|
+
* Line chart
|
66
|
+
* @sample highcharts/demo/streamgraph
|
67
|
+
* Stream graph
|
68
|
+
* @sample highcharts/series-label/stock-chart
|
69
|
+
* Stock chart
|
70
|
+
* @since 6.0.0
|
71
|
+
* @product highcharts highstock
|
52
72
|
*/
|
53
73
|
label: {
|
54
|
-
|
55
74
|
/**
|
75
|
+
* Enable the series label per series.
|
56
76
|
*/
|
57
77
|
enabled: true,
|
58
|
-
// Allow labels to be placed distant to the graph if necessary, and
|
59
|
-
// draw a connector line to the graph
|
60
|
-
|
61
78
|
/**
|
79
|
+
* Allow labels to be placed distant to the graph if necessary,
|
80
|
+
* and draw a connector line to the graph.
|
62
81
|
*/
|
63
82
|
connectorAllowed: true,
|
64
|
-
|
65
83
|
/**
|
84
|
+
* If the label is closer than this to a neighbour graph, draw a
|
85
|
+
* connector.
|
66
86
|
*/
|
67
|
-
connectorNeighbourDistance: 24,
|
68
|
-
|
87
|
+
connectorNeighbourDistance: 24,
|
88
|
+
/**
|
89
|
+
* For area-like series, allow the font size to vary so that
|
90
|
+
* small areas get a smaller font size. The default applies this
|
91
|
+
* effect to area-like series but not line-like series.
|
92
|
+
*
|
93
|
+
* @type {Number}
|
94
|
+
*/
|
95
|
+
minFontSize: null,
|
96
|
+
/**
|
97
|
+
* For area-like series, allow the font size to vary so that
|
98
|
+
* small areas get a smaller font size. The default applies this
|
99
|
+
* effect to area-like series but not line-like series.
|
100
|
+
*
|
101
|
+
* @type {Number}
|
102
|
+
*/
|
103
|
+
maxFontSize: null,
|
69
104
|
/**
|
105
|
+
* Draw the label on the area of an area series. By default it
|
106
|
+
* is drawn on the area. Set it to `false` to draw it next to
|
107
|
+
* the graph instead.
|
108
|
+
*
|
109
|
+
* @type {Boolean}
|
70
110
|
*/
|
71
|
-
|
111
|
+
onArea: null,
|
72
112
|
|
73
|
-
|
74
|
-
|
113
|
+
/**
|
114
|
+
* Styles for the series label. The color defaults to the series
|
115
|
+
* color, or a contrast color if `onArea`.
|
116
|
+
*/
|
117
|
+
style: {
|
75
118
|
fontWeight: 'bold'
|
76
|
-
}
|
77
|
-
|
119
|
+
},
|
120
|
+
|
121
|
+
/**
|
122
|
+
* An array of boxes to avoid when laying out the labels. Each
|
123
|
+
* item has a `left`, `right`, `top` and `bottom` property.
|
124
|
+
*
|
125
|
+
* @type {Array.<Object>}
|
126
|
+
*/
|
127
|
+
boxesToAvoid: []
|
78
128
|
}
|
79
129
|
}
|
80
130
|
}
|
@@ -102,8 +152,8 @@
|
|
102
152
|
function boxIntersectLine(x, y, w, h, x1, y1, x2, y2) {
|
103
153
|
return (
|
104
154
|
intersectLine(x, y, x + w, y, x1, y1, x2, y2) || // top of label
|
105
|
-
intersectLine(x + w, y, x + w, y + h, x1, y1, x2, y2) || // right
|
106
|
-
intersectLine(x, y + h, x + w, y + h, x1, y1, x2, y2) || // bottom
|
155
|
+
intersectLine(x + w, y, x + w, y + h, x1, y1, x2, y2) || // right
|
156
|
+
intersectLine(x, y + h, x + w, y + h, x1, y1, x2, y2) || // bottom
|
107
157
|
intersectLine(x, y, x, y + h, x1, y1, x2, y2) // left of label
|
108
158
|
);
|
109
159
|
}
|
@@ -156,6 +206,11 @@
|
|
156
206
|
* interpolated positions.
|
157
207
|
*/
|
158
208
|
Series.prototype.getPointsOnGraph = function() {
|
209
|
+
|
210
|
+
if (!this.xAxis && !this.yAxis) {
|
211
|
+
return;
|
212
|
+
}
|
213
|
+
|
159
214
|
var distance = 16,
|
160
215
|
points = this.points,
|
161
216
|
point,
|
@@ -172,12 +227,18 @@
|
|
172
227
|
graph = this.graph || this.area,
|
173
228
|
node = graph.element,
|
174
229
|
inverted = this.chart.inverted,
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
230
|
+
xAxis = this.xAxis,
|
231
|
+
yAxis = this.yAxis,
|
232
|
+
paneLeft = inverted ? yAxis.pos : xAxis.pos,
|
233
|
+
paneTop = inverted ? xAxis.pos : yAxis.pos,
|
234
|
+
onArea = pick(this.options.label.onArea, !!this.area),
|
235
|
+
translatedThreshold = yAxis.getThreshold(this.options.threshold);
|
236
|
+
|
237
|
+
// For splines, get the point at length (possible caveat: peaks are not
|
238
|
+
// correctly detected)
|
239
|
+
if (this.getPointSpline && node.getPointAtLength && !onArea) {
|
240
|
+
// If it is animating towards a path definition, use that briefly, and
|
241
|
+
// reset
|
181
242
|
if (graph.toD) {
|
182
243
|
d = graph.attr('d');
|
183
244
|
graph.attr({
|
@@ -216,6 +277,13 @@
|
|
216
277
|
// Absolute coordinates so we can compare different panes
|
217
278
|
point.chartX = paneLeft + point.plotX;
|
218
279
|
point.chartY = paneTop + point.plotY;
|
280
|
+
if (onArea) {
|
281
|
+
// Vertically centered inside area
|
282
|
+
point.chartCenterY = paneTop + (
|
283
|
+
point.plotY +
|
284
|
+
pick(point.yBottom, translatedThreshold)
|
285
|
+
) / 2;
|
286
|
+
}
|
219
287
|
|
220
288
|
// Add interpolated points
|
221
289
|
if (i > 0) {
|
@@ -228,10 +296,17 @@
|
|
228
296
|
|
229
297
|
for (j = 1; j < n; j += 1) {
|
230
298
|
interpolated.push({
|
231
|
-
chartX: last.chartX +
|
232
|
-
|
233
|
-
|
234
|
-
|
299
|
+
chartX: last.chartX +
|
300
|
+
(point.chartX - last.chartX) * (j / n),
|
301
|
+
chartY: last.chartY +
|
302
|
+
(point.chartY - last.chartY) * (j / n),
|
303
|
+
chartCenterY: last.chartCenterY +
|
304
|
+
(point.chartCenterY - last.chartCenterY) *
|
305
|
+
(j / n),
|
306
|
+
plotX: last.plotX +
|
307
|
+
(point.plotX - last.plotX) * (j / n),
|
308
|
+
plotY: last.plotY +
|
309
|
+
(point.plotY - last.plotY) * (j / n)
|
235
310
|
});
|
236
311
|
}
|
237
312
|
}
|
@@ -243,9 +318,30 @@
|
|
243
318
|
}
|
244
319
|
}
|
245
320
|
}
|
321
|
+
|
322
|
+
// Get the bounding box so we can do a quick check first if the bounding
|
323
|
+
// boxes overlap.
|
324
|
+
/*
|
325
|
+
interpolated.bBox = node.getBBox();
|
326
|
+
interpolated.bBox.x += paneLeft;
|
327
|
+
interpolated.bBox.y += paneTop;
|
328
|
+
*/
|
329
|
+
|
246
330
|
return interpolated;
|
247
331
|
};
|
248
332
|
|
333
|
+
/**
|
334
|
+
* Overridable function to return series-specific font sizes for the labels. By
|
335
|
+
* default it returns bigger font sizes for series with the greater sum of y
|
336
|
+
* values.
|
337
|
+
*/
|
338
|
+
Series.prototype.labelFontSize = function(minFontSize, maxFontSize) {
|
339
|
+
return minFontSize + (
|
340
|
+
(this.sum / this.chart.labelSeriesMaxSum) *
|
341
|
+
(maxFontSize - minFontSize)
|
342
|
+
) + 'px';
|
343
|
+
};
|
344
|
+
|
249
345
|
/**
|
250
346
|
* Check whether a proposed label position is clear of other elements
|
251
347
|
*/
|
@@ -255,12 +351,14 @@
|
|
255
351
|
dist,
|
256
352
|
connectorPoint,
|
257
353
|
connectorEnabled = this.options.label.connectorAllowed,
|
258
|
-
|
354
|
+
onArea = pick(this.options.label.onArea, !!this.area),
|
259
355
|
chart = this.chart,
|
260
356
|
series,
|
261
357
|
points,
|
262
358
|
leastDistance = 16,
|
263
359
|
withinRange,
|
360
|
+
xDist,
|
361
|
+
yDist,
|
264
362
|
i,
|
265
363
|
j;
|
266
364
|
|
@@ -272,9 +370,9 @@
|
|
272
370
|
}
|
273
371
|
|
274
372
|
/**
|
275
|
-
* Get the weight in order to determine the ideal position. Larger distance
|
276
|
-
* other series gives more weight. Smaller distance to the actual point
|
277
|
-
* gives more weight.
|
373
|
+
* Get the weight in order to determine the ideal position. Larger distance
|
374
|
+
* to other series gives more weight. Smaller distance to the actual point
|
375
|
+
* (connector points only) gives more weight.
|
278
376
|
*/
|
279
377
|
function getWeight(distToOthersSquared, distToPointSquared) {
|
280
378
|
return distToOthersSquared - distToPointSquared;
|
@@ -292,64 +390,99 @@
|
|
292
390
|
}
|
293
391
|
}
|
294
392
|
|
295
|
-
// For each position, check if the lines around the label intersect with any
|
296
|
-
// graphs
|
393
|
+
// For each position, check if the lines around the label intersect with any
|
394
|
+
// of the graphs.
|
297
395
|
for (i = 0; i < chart.series.length; i += 1) {
|
298
396
|
series = chart.series[i];
|
299
397
|
points = series.interpolatedPoints;
|
300
398
|
if (series.visible && points) {
|
301
399
|
for (j = 1; j < points.length; j += 1) {
|
302
|
-
// If any of the box sides intersect with the line, return
|
303
|
-
if (boxIntersectLine(
|
304
|
-
x,
|
305
|
-
y,
|
306
|
-
bBox.width,
|
307
|
-
bBox.height,
|
308
|
-
points[j - 1].chartX,
|
309
|
-
points[j - 1].chartY,
|
310
|
-
points[j].chartX,
|
311
|
-
points[j].chartY
|
312
|
-
)) {
|
313
|
-
return false;
|
314
|
-
}
|
315
400
|
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
401
|
+
if (
|
402
|
+
// To avoid processing, only check intersection if the X
|
403
|
+
// values are close to the box.
|
404
|
+
points[j].chartX >= x - leastDistance &&
|
405
|
+
points[j - 1].chartX <= x + bBox.width + leastDistance
|
406
|
+
) {
|
407
|
+
// If any of the box sides intersect with the line, return.
|
408
|
+
if (boxIntersectLine(
|
409
|
+
x,
|
410
|
+
y,
|
411
|
+
bBox.width,
|
412
|
+
bBox.height,
|
413
|
+
points[j - 1].chartX,
|
414
|
+
points[j - 1].chartY,
|
415
|
+
points[j].chartX,
|
416
|
+
points[j].chartY
|
417
|
+
)) {
|
418
|
+
return false;
|
419
|
+
}
|
420
|
+
|
421
|
+
// But if it is too far away (a padded box doesn't
|
422
|
+
// intersect), also return.
|
423
|
+
if (this === series && !withinRange && checkDistance) {
|
424
|
+
withinRange = boxIntersectLine(
|
425
|
+
x - leastDistance,
|
426
|
+
y - leastDistance,
|
427
|
+
bBox.width + 2 * leastDistance,
|
428
|
+
bBox.height + 2 * leastDistance,
|
429
|
+
points[j - 1].chartX,
|
430
|
+
points[j - 1].chartY,
|
431
|
+
points[j].chartX,
|
432
|
+
points[j].chartY
|
433
|
+
);
|
434
|
+
}
|
328
435
|
}
|
329
436
|
|
330
|
-
// Find the squared distance from the center of the label
|
331
|
-
|
437
|
+
// Find the squared distance from the center of the label. On
|
438
|
+
// area series, avoid its own graph.
|
439
|
+
if (
|
440
|
+
(connectorEnabled || withinRange) &&
|
441
|
+
(this !== series || onArea)
|
442
|
+
) {
|
443
|
+
xDist = x + bBox.width / 2 - points[j].chartX;
|
444
|
+
yDist = y + bBox.height / 2 - points[j].chartY;
|
332
445
|
distToOthersSquared = Math.min(
|
333
446
|
distToOthersSquared,
|
334
|
-
|
335
|
-
Math.pow(x - points[j].chartX, 2) + Math.pow(y - points[j].chartY, 2),
|
336
|
-
Math.pow(x + bBox.width - points[j].chartX, 2) + Math.pow(y - points[j].chartY, 2),
|
337
|
-
Math.pow(x + bBox.width - points[j].chartX, 2) + Math.pow(y + bBox.height - points[j].chartY, 2),
|
338
|
-
Math.pow(x - points[j].chartX, 2) + Math.pow(y + bBox.height - points[j].chartY, 2)
|
447
|
+
xDist * xDist + yDist * yDist
|
339
448
|
);
|
340
449
|
}
|
341
450
|
}
|
342
451
|
|
343
452
|
// Do we need a connector?
|
344
|
-
if (
|
345
|
-
|
453
|
+
if (!onArea &&
|
454
|
+
connectorEnabled &&
|
455
|
+
this === series &&
|
456
|
+
(
|
457
|
+
(checkDistance && !withinRange) ||
|
458
|
+
distToOthersSquared < Math.pow(
|
459
|
+
this.options.label.connectorNeighbourDistance,
|
460
|
+
2
|
461
|
+
)
|
462
|
+
)
|
463
|
+
) {
|
346
464
|
for (j = 1; j < points.length; j += 1) {
|
347
465
|
dist = Math.min(
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
466
|
+
(
|
467
|
+
Math.pow(x + bBox.width / 2 - points[j].chartX, 2) +
|
468
|
+
Math.pow(y + bBox.height / 2 - points[j].chartY, 2)
|
469
|
+
),
|
470
|
+
(
|
471
|
+
Math.pow(x - points[j].chartX, 2) +
|
472
|
+
Math.pow(y - points[j].chartY, 2)
|
473
|
+
),
|
474
|
+
(
|
475
|
+
Math.pow(x + bBox.width - points[j].chartX, 2) +
|
476
|
+
Math.pow(y - points[j].chartY, 2)
|
477
|
+
),
|
478
|
+
(
|
479
|
+
Math.pow(x + bBox.width - points[j].chartX, 2) +
|
480
|
+
Math.pow(y + bBox.height - points[j].chartY, 2)
|
481
|
+
),
|
482
|
+
(
|
483
|
+
Math.pow(x - points[j].chartX, 2) +
|
484
|
+
Math.pow(y + bBox.height - points[j].chartY, 2)
|
485
|
+
)
|
353
486
|
);
|
354
487
|
if (dist < distToPointSquared) {
|
355
488
|
distToPointSquared = dist;
|
@@ -364,7 +497,10 @@
|
|
364
497
|
return !checkDistance || withinRange ? {
|
365
498
|
x: x,
|
366
499
|
y: y,
|
367
|
-
weight: getWeight(
|
500
|
+
weight: getWeight(
|
501
|
+
distToOthersSquared,
|
502
|
+
connectorPoint ? distToPointSquared : 0
|
503
|
+
),
|
368
504
|
connectorPoint: connectorPoint
|
369
505
|
} : false;
|
370
506
|
|
@@ -376,6 +512,9 @@
|
|
376
512
|
* account when placing the labels.
|
377
513
|
*/
|
378
514
|
Chart.prototype.drawSeriesLabels = function() {
|
515
|
+
|
516
|
+
// console.time('drawSeriesLabels');
|
517
|
+
|
379
518
|
var chart = this,
|
380
519
|
labelSeries = this.labelSeries;
|
381
520
|
|
@@ -391,6 +530,11 @@
|
|
391
530
|
});
|
392
531
|
|
393
532
|
each(chart.series, function(series) {
|
533
|
+
|
534
|
+
if (!series.xAxis && !series.yAxis) {
|
535
|
+
return;
|
536
|
+
}
|
537
|
+
|
394
538
|
var bBox,
|
395
539
|
x,
|
396
540
|
y,
|
@@ -398,13 +542,17 @@
|
|
398
542
|
clearPoint,
|
399
543
|
i,
|
400
544
|
best,
|
545
|
+
labelOptions = series.options.label,
|
401
546
|
inverted = chart.inverted,
|
402
547
|
paneLeft = inverted ? series.yAxis.pos : series.xAxis.pos,
|
403
548
|
paneTop = inverted ? series.xAxis.pos : series.yAxis.pos,
|
404
549
|
paneWidth = chart.inverted ? series.yAxis.len : series.xAxis.len,
|
405
550
|
paneHeight = chart.inverted ? series.xAxis.len : series.yAxis.len,
|
406
551
|
points = series.interpolatedPoints,
|
407
|
-
|
552
|
+
onArea = pick(labelOptions.onArea, !!series.area),
|
553
|
+
label = series.labelBySeries,
|
554
|
+
minFontSize = labelOptions.minFontSize,
|
555
|
+
maxFontSize = labelOptions.maxFontSize;
|
408
556
|
|
409
557
|
function insidePane(x, y, bBox) {
|
410
558
|
return x > paneLeft && x <= paneLeft + paneWidth - bBox.width &&
|
@@ -416,13 +564,24 @@
|
|
416
564
|
series.labelBySeries = label = chart.renderer
|
417
565
|
.label(series.name, 0, -9999, 'connector')
|
418
566
|
.css(extend({
|
419
|
-
color:
|
420
|
-
|
567
|
+
color: onArea ?
|
568
|
+
chart.renderer.getContrast(series.color) : series.color
|
569
|
+
}, series.options.label.style));
|
570
|
+
|
571
|
+
// Adapt label sizes to the sum of the data
|
572
|
+
if (minFontSize && maxFontSize) {
|
573
|
+
label.css({
|
574
|
+
fontSize: series.labelFontSize(minFontSize, maxFontSize)
|
575
|
+
});
|
576
|
+
}
|
577
|
+
|
578
|
+
label
|
421
579
|
.attr({
|
422
580
|
padding: 0,
|
423
|
-
opacity: 0,
|
581
|
+
opacity: chart.renderer.forExport ? 1 : 0,
|
424
582
|
stroke: series.color,
|
425
|
-
'stroke-width': 1
|
583
|
+
'stroke-width': 1,
|
584
|
+
zIndex: 3
|
426
585
|
})
|
427
586
|
.add(series.group)
|
428
587
|
.animate({
|
@@ -439,66 +598,85 @@
|
|
439
598
|
// of chart
|
440
599
|
for (i = points.length - 1; i > 0; i -= 1) {
|
441
600
|
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
601
|
+
if (onArea) {
|
602
|
+
|
603
|
+
// Centered
|
604
|
+
x = points[i].chartX - bBox.width / 2;
|
605
|
+
y = points[i].chartCenterY - bBox.height / 2;
|
606
|
+
if (insidePane(x, y, bBox)) {
|
607
|
+
best = series.checkClearPoint(
|
608
|
+
x,
|
609
|
+
y,
|
610
|
+
bBox
|
611
|
+
);
|
612
|
+
}
|
613
|
+
if (best) {
|
614
|
+
results.push(best);
|
615
|
+
}
|
455
616
|
|
456
|
-
// Right - down
|
457
|
-
x = points[i].chartX + labelDistance;
|
458
|
-
y = points[i].chartY + labelDistance;
|
459
|
-
if (insidePane(x, y, bBox)) {
|
460
|
-
best = series.checkClearPoint(
|
461
|
-
x,
|
462
|
-
y,
|
463
|
-
bBox
|
464
|
-
);
|
465
|
-
}
|
466
|
-
if (best) {
|
467
|
-
results.push(best);
|
468
|
-
}
|
469
617
|
|
470
|
-
|
471
|
-
x = points[i].chartX - bBox.width - labelDistance;
|
472
|
-
y = points[i].chartY + labelDistance;
|
473
|
-
if (insidePane(x, y, bBox)) {
|
474
|
-
best = series.checkClearPoint(
|
475
|
-
x,
|
476
|
-
y,
|
477
|
-
bBox
|
478
|
-
);
|
479
|
-
}
|
480
|
-
if (best) {
|
481
|
-
results.push(best);
|
482
|
-
}
|
618
|
+
} else {
|
483
619
|
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
620
|
+
// Right - up
|
621
|
+
x = points[i].chartX + labelDistance;
|
622
|
+
y = points[i].chartY - bBox.height - labelDistance;
|
623
|
+
if (insidePane(x, y, bBox)) {
|
624
|
+
best = series.checkClearPoint(
|
625
|
+
x,
|
626
|
+
y,
|
627
|
+
bBox
|
628
|
+
);
|
629
|
+
}
|
630
|
+
if (best) {
|
631
|
+
results.push(best);
|
632
|
+
}
|
633
|
+
|
634
|
+
// Right - down
|
635
|
+
x = points[i].chartX + labelDistance;
|
636
|
+
y = points[i].chartY + labelDistance;
|
637
|
+
if (insidePane(x, y, bBox)) {
|
638
|
+
best = series.checkClearPoint(
|
639
|
+
x,
|
640
|
+
y,
|
641
|
+
bBox
|
642
|
+
);
|
643
|
+
}
|
644
|
+
if (best) {
|
645
|
+
results.push(best);
|
646
|
+
}
|
647
|
+
|
648
|
+
// Left - down
|
649
|
+
x = points[i].chartX - bBox.width - labelDistance;
|
650
|
+
y = points[i].chartY + labelDistance;
|
651
|
+
if (insidePane(x, y, bBox)) {
|
652
|
+
best = series.checkClearPoint(
|
653
|
+
x,
|
654
|
+
y,
|
655
|
+
bBox
|
656
|
+
);
|
657
|
+
}
|
658
|
+
if (best) {
|
659
|
+
results.push(best);
|
660
|
+
}
|
497
661
|
|
662
|
+
// Left - up
|
663
|
+
x = points[i].chartX - bBox.width - labelDistance;
|
664
|
+
y = points[i].chartY - bBox.height - labelDistance;
|
665
|
+
if (insidePane(x, y, bBox)) {
|
666
|
+
best = series.checkClearPoint(
|
667
|
+
x,
|
668
|
+
y,
|
669
|
+
bBox
|
670
|
+
);
|
671
|
+
}
|
672
|
+
if (best) {
|
673
|
+
results.push(best);
|
674
|
+
}
|
675
|
+
}
|
498
676
|
}
|
499
677
|
|
500
678
|
// Brute force, try all positions on the chart in a 16x16 grid
|
501
|
-
if (!results.length) {
|
679
|
+
if (!results.length && !onArea) {
|
502
680
|
for (x = paneLeft + paneWidth - bBox.width; x >= paneLeft; x -= 16) {
|
503
681
|
for (y = paneTop; y < paneTop + paneHeight - bBox.height; y += 16) {
|
504
682
|
clearPoint = series.checkClearPoint(x, y, bBox, true);
|
@@ -525,19 +703,39 @@
|
|
525
703
|
});
|
526
704
|
|
527
705
|
// Move it if needed
|
528
|
-
|
529
|
-
Math.
|
530
|
-
|
531
|
-
|
532
|
-
|
706
|
+
var dist = Math.sqrt(
|
707
|
+
Math.pow(Math.abs(best.x - label.x), 2),
|
708
|
+
Math.pow(Math.abs(best.y - label.y), 2)
|
709
|
+
);
|
710
|
+
|
711
|
+
if (dist) {
|
712
|
+
|
713
|
+
// Move fast and fade in - pure animation movement is
|
714
|
+
// distractive...
|
715
|
+
var attr = {
|
716
|
+
opacity: chart.renderer.forExport ? 1 : 0,
|
533
717
|
x: best.x - paneLeft,
|
534
|
-
y: best.y - paneTop
|
535
|
-
|
536
|
-
|
537
|
-
})
|
538
|
-
.animate({
|
718
|
+
y: best.y - paneTop
|
719
|
+
},
|
720
|
+
anim = {
|
539
721
|
opacity: 1
|
540
|
-
}
|
722
|
+
};
|
723
|
+
// ... unless we're just moving a short distance
|
724
|
+
if (dist <= 10) {
|
725
|
+
anim = {
|
726
|
+
x: attr.x,
|
727
|
+
y: attr.y
|
728
|
+
};
|
729
|
+
attr = {};
|
730
|
+
}
|
731
|
+
series.labelBySeries
|
732
|
+
.attr(extend(attr, {
|
733
|
+
anchorX: best.connectorPoint &&
|
734
|
+
best.connectorPoint.plotX,
|
735
|
+
anchorY: best.connectorPoint &&
|
736
|
+
best.connectorPoint.plotY
|
737
|
+
}))
|
738
|
+
.animate(anim);
|
541
739
|
|
542
740
|
// Record closest point to stick to for sync redraw
|
543
741
|
series.options.kdNow = true;
|
@@ -559,6 +757,7 @@
|
|
559
757
|
}
|
560
758
|
}
|
561
759
|
});
|
760
|
+
// console.timeEnd('drawSeriesLabels');
|
562
761
|
};
|
563
762
|
|
564
763
|
/**
|
@@ -576,6 +775,7 @@
|
|
576
775
|
proceed.apply(chart, [].slice.call(arguments, 1));
|
577
776
|
|
578
777
|
chart.labelSeries = [];
|
778
|
+
chart.labelSeriesMaxSum = 0;
|
579
779
|
|
580
780
|
clearTimeout(chart.seriesLabelTimer);
|
581
781
|
|
@@ -588,6 +788,16 @@
|
|
588
788
|
if (options.enabled && series.visible && (series.graph || series.area)) {
|
589
789
|
chart.labelSeries.push(series);
|
590
790
|
|
791
|
+
if (options.minFontSize && options.maxFontSize) {
|
792
|
+
series.sum = H.reduce(series.yData, function(pv, cv) {
|
793
|
+
return (pv || 0) + (cv || 0);
|
794
|
+
}, 0);
|
795
|
+
chart.labelSeriesMaxSum = Math.max(
|
796
|
+
chart.labelSeriesMaxSum,
|
797
|
+
series.sum
|
798
|
+
);
|
799
|
+
}
|
800
|
+
|
591
801
|
// The labels are processing heavy, wait until the animation is done
|
592
802
|
if (initial) {
|
593
803
|
delay = Math.max(
|
@@ -612,9 +822,9 @@
|
|
612
822
|
}
|
613
823
|
});
|
614
824
|
|
615
|
-
chart.seriesLabelTimer =
|
825
|
+
chart.seriesLabelTimer = H.syncTimeout(function() {
|
616
826
|
chart.drawSeriesLabels();
|
617
|
-
}, delay);
|
827
|
+
}, chart.renderer.forExport ? 0 : delay);
|
618
828
|
|
619
829
|
}
|
620
830
|
wrap(Chart.prototype, 'render', drawLabels);
|