highcharts-rails 5.0.0 → 5.0.3
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/.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);
|