highcharts-rails 5.0.0 → 5.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.markdown +99 -0
- data/Gemfile +1 -1
- data/README.markdown +2 -1
- data/Rakefile +28 -2
- data/app/assets/javascripts/highcharts.js +3935 -2584
- data/app/assets/javascripts/highcharts/highcharts-3d.js +44 -10
- data/app/assets/javascripts/highcharts/highcharts-more.js +32 -12
- data/app/assets/javascripts/highcharts/modules/accessibility.js +85 -18
- data/app/assets/javascripts/highcharts/modules/annotations.js +1 -1
- data/app/assets/javascripts/highcharts/modules/boost.js +34 -19
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +1 -1
- data/app/assets/javascripts/highcharts/modules/data.js +2 -2
- data/app/assets/javascripts/highcharts/modules/drilldown.js +4 -3
- data/app/assets/javascripts/highcharts/modules/exporting.js +15 -14
- data/app/assets/javascripts/highcharts/modules/funnel.js +1 -1
- data/app/assets/javascripts/highcharts/modules/grid-axis.js +547 -0
- data/app/assets/javascripts/highcharts/modules/heatmap.js +17 -2
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +115 -73
- data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
- data/app/assets/javascripts/highcharts/modules/series-label.js +210 -148
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +30 -10
- data/app/assets/javascripts/highcharts/modules/treemap.js +6 -1
- data/app/assets/javascripts/highcharts/modules/xrange-series.js +278 -0
- data/lib/highcharts/version.rb +1 -1
- metadata +3 -1
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v5.0.
|
2
|
+
* @license Highcharts JS v5.0.3 (2016-11-18)
|
3
3
|
*
|
4
4
|
* (c) 2009-2016 Torstein Honsi
|
5
5
|
*
|
@@ -67,6 +67,14 @@
|
|
67
67
|
tickLength: 5,
|
68
68
|
showInLegend: true
|
69
69
|
},
|
70
|
+
|
71
|
+
// Properties to preserve after destroy, for Axis.update (#5881)
|
72
|
+
keepProps: ['legendGroup', 'legendItem', 'legendSymbol']
|
73
|
+
.concat(Axis.prototype.keepProps),
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Initialize the color axis
|
77
|
+
*/
|
70
78
|
init: function(chart, userOptions) {
|
71
79
|
var horiz = chart.options.legend.layout !== 'vertical',
|
72
80
|
options;
|
@@ -584,6 +592,13 @@
|
|
584
592
|
* Mixin for maps and heatmaps
|
585
593
|
*/
|
586
594
|
H.colorPointMixin = {
|
595
|
+
/**
|
596
|
+
* Color points have a value option that determines whether or not it is a null point
|
597
|
+
*/
|
598
|
+
isValid: function() {
|
599
|
+
return this.value !== null;
|
600
|
+
},
|
601
|
+
|
587
602
|
/**
|
588
603
|
* Set the visibility of a single point
|
589
604
|
*/
|
@@ -627,7 +642,7 @@
|
|
627
642
|
color;
|
628
643
|
|
629
644
|
color = point.options.color ||
|
630
|
-
(
|
645
|
+
(point.isNull ? nullColor : (colorAxis && value !== undefined) ? colorAxis.toColor(value, point) : point.color || series.color);
|
631
646
|
|
632
647
|
if (color) {
|
633
648
|
point.color = color;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v5.0.
|
2
|
+
* @license Highcharts JS v5.0.3 (2016-11-18)
|
3
3
|
* Client side exporting module
|
4
4
|
*
|
5
5
|
* (c) 2015 Torstein Honsi / Oystein Moseng
|
@@ -29,6 +29,7 @@
|
|
29
29
|
win = Highcharts.win,
|
30
30
|
nav = win.navigator,
|
31
31
|
doc = win.document,
|
32
|
+
each = Highcharts.each,
|
32
33
|
domurl = win.URL || win.webkitURL || win,
|
33
34
|
isMSBrowser = /Edge\/|Trident\/|MSIE /.test(nav.userAgent),
|
34
35
|
loadEventDeferDelay = isMSBrowser ? 150 : 0; // Milliseconds to defer image load event handlers to offset IE bug
|
@@ -49,6 +50,9 @@
|
|
49
50
|
script.type = 'text/javascript';
|
50
51
|
script.src = scriptLocation;
|
51
52
|
script.onload = callback;
|
53
|
+
script.onerror = function() {
|
54
|
+
console.error('Error loading script', scriptLocation); // eslint-disable-line no-console
|
55
|
+
};
|
52
56
|
|
53
57
|
head.appendChild(script);
|
54
58
|
}
|
@@ -161,23 +165,57 @@
|
|
161
165
|
img.src = imageURL;
|
162
166
|
};
|
163
167
|
|
164
|
-
|
165
|
-
|
168
|
+
/**
|
169
|
+
* Get data URL to an image of an SVG and call download on it
|
170
|
+
*
|
171
|
+
* options object:
|
172
|
+
* filename: Name of resulting downloaded file without extension
|
173
|
+
* type: File type of resulting download
|
174
|
+
* scale: Scaling factor of downloaded image compared to source
|
175
|
+
* libURL: URL pointing to location of dependency scripts to download on demand
|
176
|
+
*/
|
177
|
+
Highcharts.downloadSVGLocal = function(svg, options, failCallback, successCallback) {
|
166
178
|
var svgurl,
|
167
179
|
blob,
|
168
180
|
objectURLRevoke = true,
|
169
181
|
finallyHandler,
|
170
|
-
libURL = Highcharts.getOptions().exporting.libURL
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
182
|
+
libURL = options.libURL || Highcharts.getOptions().exporting.libURL,
|
183
|
+
dummySVGContainer = doc.createElement('div'),
|
184
|
+
imageType = options.type || 'image/png',
|
185
|
+
filename = (options.filename || 'chart') + '.' + (imageType === 'image/svg+xml' ? 'svg' : imageType.split('/')[1]),
|
186
|
+
scale = options.scale || 1;
|
187
|
+
|
188
|
+
libURL = libURL.slice(-1) !== '/' ? libURL + '/' : libURL; // Allow libURL to end with or without fordward slash
|
189
|
+
|
190
|
+
function svgToPdf(svgElement, margin) {
|
191
|
+
var width = svgElement.width.baseVal.value + 2 * margin,
|
192
|
+
height = svgElement.height.baseVal.value + 2 * margin,
|
193
|
+
pdf = new win.jsPDF('l', 'pt', [width, height]); // eslint-disable-line new-cap
|
194
|
+
win.svgElementToPdf(svgElement, pdf, {
|
195
|
+
removeInvalid: true
|
196
|
+
});
|
197
|
+
return pdf.output('datauristring');
|
198
|
+
}
|
199
|
+
|
200
|
+
function downloadPDF() {
|
201
|
+
dummySVGContainer.innerHTML = svg;
|
202
|
+
var textElements = dummySVGContainer.getElementsByTagName('text'),
|
203
|
+
svgElementStyle = dummySVGContainer.getElementsByTagName('svg')[0].style;
|
204
|
+
// Workaround for the text styling. Making sure it does pick up the root element
|
205
|
+
each(textElements, function(el) {
|
206
|
+
each(['font-family', 'font-size'], function(property) {
|
207
|
+
if (!el.style[property] && svgElementStyle[property]) {
|
208
|
+
el.style[property] = svgElementStyle[property];
|
209
|
+
}
|
210
|
+
});
|
211
|
+
el.style['font-family'] = el.style['font-family'] && el.style['font-family'].split(' ').splice(-1);
|
212
|
+
});
|
213
|
+
var svgData = svgToPdf(dummySVGContainer.firstChild, 0);
|
214
|
+
Highcharts.downloadURL(svgData, filename);
|
215
|
+
if (successCallback) {
|
216
|
+
successCallback();
|
217
|
+
}
|
218
|
+
}
|
181
219
|
|
182
220
|
// Initiate download depending on file type
|
183
221
|
if (imageType === 'image/svg+xml') {
|
@@ -197,20 +235,20 @@
|
|
197
235
|
} catch (e) {
|
198
236
|
failCallback();
|
199
237
|
}
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
238
|
+
} else if (imageType === 'application/pdf') {
|
239
|
+
if (win.jsPDF && win.svgElementToPdf) {
|
240
|
+
downloadPDF();
|
241
|
+
} else {
|
242
|
+
// Must load pdf libraries first
|
243
|
+
objectURLRevoke = true; // Don't destroy the object URL yet since we are doing things asynchronously. A cleaner solution would be nice, but this will do for now.
|
244
|
+
getScript(libURL + 'jspdf.js', function() {
|
245
|
+
getScript(libURL + 'rgbcolor.js', function() {
|
246
|
+
getScript(libURL + 'svg2pdf.js', function() {
|
247
|
+
downloadPDF();
|
248
|
+
});
|
249
|
+
});
|
250
|
+
});
|
251
|
+
}
|
214
252
|
} else {
|
215
253
|
// PNG/JPEG download - create bitmap from SVG
|
216
254
|
|
@@ -262,7 +300,6 @@
|
|
262
300
|
} else {
|
263
301
|
// Must load canVG first
|
264
302
|
objectURLRevoke = true; // Don't destroy the object URL yet since we are doing things asynchronously. A cleaner solution would be nice, but this will do for now.
|
265
|
-
libURL = libURL.substr[-1] !== '/' ? libURL + '/' : libURL; // Allow libURL to end with or without fordward slash
|
266
303
|
getScript(libURL + 'rgbcolor.js', function() { // Get RGBColor.js first
|
267
304
|
getScript(libURL + 'canvg.js', function() {
|
268
305
|
downloadWithCanVG();
|
@@ -307,10 +344,18 @@
|
|
307
344
|
};
|
308
345
|
|
309
346
|
// Hook into getSVG to get a copy of the chart copy's container
|
310
|
-
Highcharts.wrap(
|
311
|
-
|
312
|
-
|
313
|
-
|
347
|
+
Highcharts.wrap(
|
348
|
+
Highcharts.Chart.prototype,
|
349
|
+
'getChartHTML',
|
350
|
+
function(proceed) {
|
351
|
+
var ret = proceed.apply(
|
352
|
+
this,
|
353
|
+
Array.prototype.slice.call(arguments, 1)
|
354
|
+
);
|
355
|
+
chartCopyContainer = this.container.cloneNode(true);
|
356
|
+
return ret;
|
357
|
+
}
|
358
|
+
);
|
314
359
|
|
315
360
|
// Trigger hook to get chart copy
|
316
361
|
chart.getSVGForExport(options, chartOptions);
|
@@ -349,7 +394,6 @@
|
|
349
394
|
Highcharts.Chart.prototype.exportChartLocal = function(exportingOptions, chartOptions) {
|
350
395
|
var chart = this,
|
351
396
|
options = Highcharts.merge(chart.options.exporting, exportingOptions),
|
352
|
-
imageType = options && options.type || 'image/png',
|
353
397
|
fallbackToExportServer = function() {
|
354
398
|
if (options.fallbackToExportServer === false) {
|
355
399
|
if (options.error) {
|
@@ -362,12 +406,12 @@
|
|
362
406
|
}
|
363
407
|
},
|
364
408
|
svgSuccess = function(svg) {
|
365
|
-
|
366
|
-
Highcharts.downloadSVGLocal(svg, filename, imageType, options.scale, fallbackToExportServer);
|
409
|
+
Highcharts.downloadSVGLocal(svg, options, fallbackToExportServer);
|
367
410
|
};
|
368
411
|
|
369
|
-
// If we have embedded images and are exporting to JPEG/PNG, Microsoft browsers won't handle it, so fall back
|
370
|
-
|
412
|
+
// If we have embedded images and are exporting to JPEG/PNG, Microsoft browsers won't handle it, so fall back.
|
413
|
+
// Also fall back for embedded images with PDF.
|
414
|
+
if ((isMSBrowser && options.type !== 'image/svg+xml' || options.type === 'application/pdf') && chart.container.getElementsByTagName('image').length) {
|
371
415
|
fallbackToExportServer();
|
372
416
|
return;
|
373
417
|
}
|
@@ -377,45 +421,43 @@
|
|
377
421
|
|
378
422
|
// Extend the default options to use the local exporter logic
|
379
423
|
merge(true, Highcharts.getOptions().exporting, {
|
380
|
-
libURL: '
|
424
|
+
libURL: 'https://code.highcharts.com/5.0.3/lib/',
|
381
425
|
buttons: {
|
382
426
|
contextButton: {
|
383
427
|
menuItems: [{
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
428
|
+
textKey: 'printChart',
|
429
|
+
onclick: function() {
|
430
|
+
this.print();
|
431
|
+
}
|
432
|
+
}, {
|
433
|
+
separator: true
|
434
|
+
}, {
|
435
|
+
textKey: 'downloadPNG',
|
436
|
+
onclick: function() {
|
437
|
+
this.exportChartLocal();
|
438
|
+
}
|
439
|
+
}, {
|
440
|
+
textKey: 'downloadJPEG',
|
441
|
+
onclick: function() {
|
442
|
+
this.exportChartLocal({
|
443
|
+
type: 'image/jpeg'
|
444
|
+
});
|
445
|
+
}
|
446
|
+
}, {
|
447
|
+
textKey: 'downloadSVG',
|
448
|
+
onclick: function() {
|
449
|
+
this.exportChartLocal({
|
450
|
+
type: 'image/svg+xml'
|
451
|
+
});
|
452
|
+
}
|
453
|
+
}, {
|
454
|
+
textKey: 'downloadPDF',
|
455
|
+
onclick: function() {
|
456
|
+
this.exportChartLocal({
|
457
|
+
type: 'application/pdf'
|
458
|
+
});
|
409
459
|
}
|
410
|
-
|
411
|
-
textKey: 'downloadPDF',
|
412
|
-
onclick: function () {
|
413
|
-
this.exportChartLocal({
|
414
|
-
type: 'application/pdf'
|
415
|
-
});
|
416
|
-
}
|
417
|
-
}*/
|
418
|
-
]
|
460
|
+
}]
|
419
461
|
}
|
420
462
|
}
|
421
463
|
});
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v5.0.
|
2
|
+
* @license Highcharts JS v5.0.3 (2016-11-18)
|
3
3
|
*
|
4
4
|
* (c) 2009-2016 Torstein Honsi
|
5
5
|
*
|
@@ -352,189 +352,251 @@
|
|
352
352
|
|
353
353
|
};
|
354
354
|
|
355
|
-
|
356
355
|
/**
|
357
356
|
* The main initiator method that runs on chart level after initiation and redraw. It runs in
|
358
357
|
* a timeout to prevent locking, and loops over all series, taking all series and labels into
|
359
358
|
* account when placing the labels.
|
360
359
|
*/
|
361
|
-
function
|
360
|
+
Chart.prototype.drawSeriesLabels = function() {
|
361
|
+
var chart = this,
|
362
|
+
labelSeries = this.labelSeries;
|
362
363
|
|
363
|
-
|
364
|
+
chart.boxesToAvoid = [];
|
364
365
|
|
365
|
-
|
366
|
+
// Build the interpolated points
|
367
|
+
each(labelSeries, function(series) {
|
368
|
+
series.interpolatedPoints = series.getPointsOnGraph();
|
366
369
|
|
367
|
-
|
370
|
+
each(series.options.label.boxesToAvoid || [], function(box) {
|
371
|
+
chart.boxesToAvoid.push(box);
|
372
|
+
});
|
373
|
+
});
|
374
|
+
|
375
|
+
each(chart.series, function(series) {
|
376
|
+
var bBox,
|
377
|
+
x,
|
378
|
+
y,
|
379
|
+
results = [],
|
380
|
+
clearPoint,
|
381
|
+
i,
|
382
|
+
best,
|
383
|
+
inverted = chart.inverted,
|
384
|
+
paneLeft = inverted ? series.yAxis.pos : series.xAxis.pos,
|
385
|
+
paneTop = inverted ? series.xAxis.pos : series.yAxis.pos,
|
386
|
+
paneWidth = chart.inverted ? series.yAxis.len : series.xAxis.len,
|
387
|
+
paneHeight = chart.inverted ? series.xAxis.len : series.yAxis.len,
|
388
|
+
points = series.interpolatedPoints,
|
389
|
+
label = series.labelBySeries;
|
390
|
+
|
391
|
+
function insidePane(x, y, bBox) {
|
392
|
+
return x > paneLeft && x <= paneLeft + paneWidth - bBox.width &&
|
393
|
+
y >= paneTop && y <= paneTop + paneHeight - bBox.height;
|
394
|
+
}
|
368
395
|
|
369
|
-
|
396
|
+
if (series.visible && points) {
|
397
|
+
if (!label) {
|
398
|
+
series.labelBySeries = label = chart.renderer
|
399
|
+
.label(series.name, 0, -9999, 'connector')
|
400
|
+
.css(extend({
|
401
|
+
color: series.color
|
402
|
+
}, series.options.label.styles))
|
403
|
+
.attr({
|
404
|
+
padding: 0,
|
405
|
+
opacity: 0,
|
406
|
+
stroke: series.color,
|
407
|
+
'stroke-width': 1
|
408
|
+
})
|
409
|
+
.add(series.group)
|
410
|
+
.animate({
|
411
|
+
opacity: 1
|
412
|
+
}, {
|
413
|
+
duration: 200
|
414
|
+
});
|
415
|
+
}
|
370
416
|
|
371
|
-
|
417
|
+
bBox = label.getBBox();
|
418
|
+
bBox.width = Math.round(bBox.width);
|
372
419
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
420
|
+
// Ideal positions are centered above or below a point on right side
|
421
|
+
// of chart
|
422
|
+
for (i = points.length - 1; i > 0; i -= 1) {
|
423
|
+
|
424
|
+
// Right - up
|
425
|
+
x = points[i].chartX + labelDistance;
|
426
|
+
y = points[i].chartY - bBox.height - labelDistance;
|
427
|
+
if (insidePane(x, y, bBox)) {
|
428
|
+
best = series.checkClearPoint(
|
429
|
+
x,
|
430
|
+
y,
|
431
|
+
bBox
|
432
|
+
);
|
433
|
+
}
|
434
|
+
if (best) {
|
435
|
+
results.push(best);
|
436
|
+
}
|
437
|
+
|
438
|
+
// Right - down
|
439
|
+
x = points[i].chartX + labelDistance;
|
440
|
+
y = points[i].chartY + labelDistance;
|
441
|
+
if (insidePane(x, y, bBox)) {
|
442
|
+
best = series.checkClearPoint(
|
443
|
+
x,
|
444
|
+
y,
|
445
|
+
bBox
|
446
|
+
);
|
447
|
+
}
|
448
|
+
if (best) {
|
449
|
+
results.push(best);
|
450
|
+
}
|
451
|
+
|
452
|
+
// Left - down
|
453
|
+
x = points[i].chartX - bBox.width - labelDistance;
|
454
|
+
y = points[i].chartY + labelDistance;
|
455
|
+
if (insidePane(x, y, bBox)) {
|
456
|
+
best = series.checkClearPoint(
|
457
|
+
x,
|
458
|
+
y,
|
459
|
+
bBox
|
460
|
+
);
|
461
|
+
}
|
462
|
+
if (best) {
|
463
|
+
results.push(best);
|
464
|
+
}
|
465
|
+
|
466
|
+
// Left - up
|
467
|
+
x = points[i].chartX - bBox.width - labelDistance;
|
468
|
+
y = points[i].chartY - bBox.height - labelDistance;
|
469
|
+
if (insidePane(x, y, bBox)) {
|
470
|
+
best = series.checkClearPoint(
|
471
|
+
x,
|
472
|
+
y,
|
473
|
+
bBox
|
474
|
+
);
|
475
|
+
}
|
476
|
+
if (best) {
|
477
|
+
results.push(best);
|
478
|
+
}
|
378
479
|
|
379
|
-
each(options.boxesToAvoid || [], function(box) {
|
380
|
-
chart.boxesToAvoid.push(box);
|
381
|
-
});
|
382
480
|
}
|
383
|
-
});
|
384
481
|
|
385
|
-
|
386
|
-
|
387
|
-
x
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
paneTop = inverted ? series.xAxis.pos : series.yAxis.pos,
|
396
|
-
paneWidth = chart.inverted ? series.yAxis.len : series.xAxis.len,
|
397
|
-
paneHeight = chart.inverted ? series.xAxis.len : series.yAxis.len,
|
398
|
-
points = series.interpolatedPoints;
|
399
|
-
|
400
|
-
function insidePane(x, y, bBox) {
|
401
|
-
return x > paneLeft && x <= paneLeft + paneWidth - bBox.width &&
|
402
|
-
y >= paneTop && y <= paneTop + paneHeight - bBox.height;
|
482
|
+
// Brute force, try all positions on the chart in a 16x16 grid
|
483
|
+
if (!results.length) {
|
484
|
+
for (x = paneLeft + paneWidth - bBox.width; x >= paneLeft; x -= 16) {
|
485
|
+
for (y = paneTop; y < paneTop + paneHeight - bBox.height; y += 16) {
|
486
|
+
clearPoint = series.checkClearPoint(x, y, bBox, true);
|
487
|
+
if (clearPoint) {
|
488
|
+
results.push(clearPoint);
|
489
|
+
}
|
490
|
+
}
|
491
|
+
}
|
403
492
|
}
|
404
493
|
|
405
|
-
if (
|
494
|
+
if (results.length) {
|
495
|
+
|
496
|
+
results.sort(function(a, b) {
|
497
|
+
return b.weight - a.weight;
|
498
|
+
});
|
499
|
+
|
500
|
+
best = results[0];
|
501
|
+
|
502
|
+
chart.boxesToAvoid.push({
|
503
|
+
left: best.x,
|
504
|
+
right: best.x + bBox.width,
|
505
|
+
top: best.y,
|
506
|
+
bottom: best.y + bBox.height
|
507
|
+
});
|
406
508
|
|
407
|
-
if
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
}, series.options.label.styles))
|
509
|
+
// Move it if needed
|
510
|
+
if (Math.round(best.x) !== Math.round(label.x) ||
|
511
|
+
Math.round(best.y) !== Math.round(label.y)) {
|
512
|
+
series.labelBySeries
|
412
513
|
.attr({
|
413
|
-
padding: 0,
|
414
514
|
opacity: 0,
|
415
|
-
|
416
|
-
|
515
|
+
x: best.x - paneLeft,
|
516
|
+
y: best.y - paneTop,
|
517
|
+
anchorX: best.connectorPoint && best.connectorPoint.plotX,
|
518
|
+
anchorY: best.connectorPoint && best.connectorPoint.plotY
|
417
519
|
})
|
418
|
-
.add(series.group)
|
419
520
|
.animate({
|
420
521
|
opacity: 1
|
421
|
-
}, {
|
422
|
-
duration: 200
|
423
522
|
});
|
424
|
-
}
|
425
523
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
best
|
437
|
-
|
438
|
-
y,
|
439
|
-
bBox
|
440
|
-
);
|
441
|
-
}
|
442
|
-
if (best) {
|
443
|
-
results.push(best);
|
444
|
-
}
|
524
|
+
// Record closest point to stick to for sync redraw
|
525
|
+
series.options.kdNow = true;
|
526
|
+
series.buildKDTree();
|
527
|
+
var closest = series.searchPoint({
|
528
|
+
chartX: best.x,
|
529
|
+
chartY: best.y
|
530
|
+
}, true);
|
531
|
+
label.closest = [
|
532
|
+
closest,
|
533
|
+
best.x - paneLeft - closest.plotX,
|
534
|
+
best.y - paneTop - closest.plotY
|
535
|
+
];
|
445
536
|
|
446
|
-
|
447
|
-
x = points[i].chartX + labelDistance;
|
448
|
-
y = points[i].chartY + labelDistance;
|
449
|
-
if (insidePane(x, y, bBox)) {
|
450
|
-
best = series.checkClearPoint(
|
451
|
-
x,
|
452
|
-
y,
|
453
|
-
bBox
|
454
|
-
);
|
455
|
-
}
|
456
|
-
if (best) {
|
457
|
-
results.push(best);
|
458
|
-
}
|
537
|
+
}
|
459
538
|
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
y,
|
467
|
-
bBox
|
468
|
-
);
|
469
|
-
}
|
470
|
-
if (best) {
|
471
|
-
results.push(best);
|
472
|
-
}
|
539
|
+
} else if (label) {
|
540
|
+
series.labelBySeries = label.destroy();
|
541
|
+
}
|
542
|
+
}
|
543
|
+
});
|
544
|
+
};
|
473
545
|
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
best = series.checkClearPoint(
|
479
|
-
x,
|
480
|
-
y,
|
481
|
-
bBox
|
482
|
-
);
|
483
|
-
}
|
484
|
-
if (best) {
|
485
|
-
results.push(best);
|
486
|
-
}
|
546
|
+
/**
|
547
|
+
* Prepare drawing series labels
|
548
|
+
*/
|
549
|
+
function drawLabels(proceed) {
|
487
550
|
|
488
|
-
|
551
|
+
var chart = this,
|
552
|
+
delay = Math.max(
|
553
|
+
H.animObject(chart.renderer.globalAnimation).duration,
|
554
|
+
250
|
555
|
+
),
|
556
|
+
initial = !chart.hasRendered;
|
489
557
|
|
490
|
-
|
491
|
-
if (!results.length) {
|
492
|
-
for (x = paneLeft + paneWidth - bBox.width; x >= paneLeft; x -= 16) {
|
493
|
-
for (y = paneTop; y < paneTop + paneHeight - bBox.height; y += 16) {
|
494
|
-
clearPoint = series.checkClearPoint(x, y, bBox, true);
|
495
|
-
if (clearPoint) {
|
496
|
-
results.push(clearPoint);
|
497
|
-
}
|
498
|
-
}
|
499
|
-
}
|
500
|
-
}
|
558
|
+
proceed.apply(chart, [].slice.call(arguments, 1));
|
501
559
|
|
502
|
-
|
560
|
+
chart.labelSeries = [];
|
503
561
|
|
504
|
-
|
505
|
-
return b.weight - a.weight;
|
506
|
-
});
|
562
|
+
clearTimeout(chart.seriesLabelTimer);
|
507
563
|
|
508
|
-
|
564
|
+
// Which series should have labels
|
565
|
+
each(chart.series, function(series) {
|
566
|
+
var options = series.options.label,
|
567
|
+
label = series.labelBySeries,
|
568
|
+
closest = label && label.closest;
|
569
|
+
|
570
|
+
if (options.enabled && series.visible && (series.graph || series.area)) {
|
571
|
+
chart.labelSeries.push(series);
|
572
|
+
|
573
|
+
// The labels are processing heavy, wait until the animation is done
|
574
|
+
if (initial) {
|
575
|
+
delay = Math.max(
|
576
|
+
delay,
|
577
|
+
H.animObject(series.options.animation).duration
|
578
|
+
);
|
579
|
+
}
|
509
580
|
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
581
|
+
// Keep the position updated to the axis while redrawing
|
582
|
+
if (closest) {
|
583
|
+
if (closest[0].plotX !== undefined) {
|
584
|
+
label.animate({
|
585
|
+
x: closest[0].plotX + closest[1],
|
586
|
+
y: closest[0].plotY + closest[2]
|
587
|
+
});
|
588
|
+
} else {
|
589
|
+
label.attr({
|
590
|
+
opacity: 0
|
515
591
|
});
|
516
|
-
|
517
|
-
// Move it if needed
|
518
|
-
if (Math.round(best.x) !== Math.round(series.labelBySeries.x) || Math.round(best.y) !== Math.round(series.labelBySeries.y)) {
|
519
|
-
series.labelBySeries
|
520
|
-
.attr({
|
521
|
-
x: best.x - paneLeft,
|
522
|
-
y: best.y - paneTop,
|
523
|
-
anchorX: best.connectorPoint && best.connectorPoint.plotX,
|
524
|
-
anchorY: best.connectorPoint && best.connectorPoint.plotY,
|
525
|
-
opacity: 0
|
526
|
-
})
|
527
|
-
.animate({
|
528
|
-
opacity: 1
|
529
|
-
});
|
530
|
-
}
|
531
|
-
|
532
|
-
} else if (series.labelBySeries) {
|
533
|
-
series.labelBySeries = series.labelBySeries.destroy();
|
534
592
|
}
|
535
593
|
}
|
536
|
-
}
|
537
|
-
}
|
594
|
+
}
|
595
|
+
});
|
596
|
+
|
597
|
+
chart.seriesLabelTimer = setTimeout(function() {
|
598
|
+
chart.drawSeriesLabels();
|
599
|
+
}, delay);
|
538
600
|
|
539
601
|
}
|
540
602
|
wrap(Chart.prototype, 'render', drawLabels);
|