highcharts-rails 4.0.4.1 → 4.1.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 +92 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/highcharts.js +1865 -1219
- data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +1 -1
- data/app/assets/javascripts/highcharts/highcharts-3d.js +174 -239
- data/app/assets/javascripts/highcharts/highcharts-more.js +195 -187
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/app/assets/javascripts/highcharts/modules/data.js +125 -196
- data/app/assets/javascripts/highcharts/modules/drilldown.js +104 -80
- data/app/assets/javascripts/highcharts/modules/exporting.js +14 -4
- data/app/assets/javascripts/highcharts/modules/funnel.js +7 -7
- data/app/assets/javascripts/highcharts/modules/heatmap.js +26 -69
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +2 -2
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +32 -17
- data/app/assets/javascripts/highcharts/modules/treemap.js +806 -0
- data/app/assets/javascripts/highcharts/themes/dark-unica.js +1 -1
- data/app/assets/javascripts/highcharts/themes/grid-light.js +1 -1
- data/app/assets/javascripts/highcharts/themes/sand-signika.js +1 -1
- data/lib/highcharts/version.rb +1 -1
- metadata +13 -12
- checksums.yaml.gz.asc +0 -18
- data.tar.gz.asc +0 -18
- metadata.gz.asc +0 -18
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
|
|
2908
2908
|
});
|
2909
2909
|
}
|
2910
2910
|
}/**
|
2911
|
-
* @license Highcharts JS v4.0
|
2911
|
+
* @license Highcharts JS v4.1.0 (2015-02-16)
|
2912
2912
|
* CanVGRenderer Extension module
|
2913
2913
|
*
|
2914
2914
|
* (c) 2011-2012 Torstein Honsi, Erik Olsson
|
@@ -1,113 +1,20 @@
|
|
1
1
|
/**
|
2
|
-
* @license
|
2
|
+
* @license Highcharts JS v4.1.0 (2015-02-16)
|
3
|
+
* Data module
|
3
4
|
*
|
4
5
|
* (c) 2012-2014 Torstein Honsi
|
5
6
|
*
|
6
7
|
* License: www.highcharts.com/license
|
7
8
|
*/
|
8
9
|
|
9
|
-
/*
|
10
|
-
* The Highcharts Data plugin is a utility to ease parsing of input sources like
|
11
|
-
* CSV, HTML tables or grid views into basic configuration options for use
|
12
|
-
* directly in the Highcharts constructor.
|
13
|
-
*
|
14
|
-
* Demo: http://jsfiddle.net/highcharts/SnLFj/
|
15
|
-
*
|
16
|
-
* --- OPTIONS ---
|
17
|
-
*
|
18
|
-
* - columns : Array<Array<Mixed>>
|
19
|
-
* A two-dimensional array representing the input data on tabular form. This input can
|
20
|
-
* be used when the data is already parsed, for example from a grid view component.
|
21
|
-
* Each cell can be a string or number. If not switchRowsAndColumns is set, the columns
|
22
|
-
* are interpreted as series. See also the rows option.
|
23
|
-
*
|
24
|
-
* - complete : Function(chartOptions)
|
25
|
-
* The callback that is evaluated when the data is finished loading, optionally from an
|
26
|
-
* external source, and parsed. The first argument passed is a finished chart options
|
27
|
-
* object, containing the series. Thise options
|
28
|
-
* can be extended with additional options and passed directly to the chart constructor. This is
|
29
|
-
* related to the parsed callback, that goes in at an earlier stage.
|
30
|
-
*
|
31
|
-
* - csv : String
|
32
|
-
* A comma delimited string to be parsed. Related options are startRow, endRow, startColumn
|
33
|
-
* and endColumn to delimit what part of the table is used. The lineDelimiter and
|
34
|
-
* itemDelimiter options define the CSV delimiter formats.
|
35
|
-
*
|
36
|
-
* - dateFormat: String
|
37
|
-
* Which of the predefined date formats in Date.prototype.dateFormats to use to parse date
|
38
|
-
* columns, for example "dd/mm/YYYY" or "YYYY-mm-dd". Defaults to a best guess based on
|
39
|
-
* what format gives valid dates, and prefers ordered dates.
|
40
|
-
*
|
41
|
-
* - endColumn : Integer
|
42
|
-
* In tabular input data, the first row (indexed by 0) to use. Defaults to the last
|
43
|
-
* column containing data.
|
44
|
-
*
|
45
|
-
* - endRow : Integer
|
46
|
-
* In tabular input data, the last row (indexed by 0) to use. Defaults to the last row
|
47
|
-
* containing data.
|
48
|
-
*
|
49
|
-
* - googleSpreadsheetKey : String
|
50
|
-
* A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample
|
51
|
-
* for general information on GS.
|
52
|
-
*
|
53
|
-
* - googleSpreadsheetWorksheet : String
|
54
|
-
* The Google Spreadsheet worksheet. The available id's can be read from
|
55
|
-
* https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic
|
56
|
-
*
|
57
|
-
* - itemDelimiter : String
|
58
|
-
* Item or cell delimiter for parsing CSV. Defaults to the tab character "\t" if a tab character
|
59
|
-
* is found in the CSV string, if not it defaults to ",".
|
60
|
-
*
|
61
|
-
* - lineDelimiter : String
|
62
|
-
* Line delimiter for parsing CSV. Defaults to "\n".
|
63
|
-
*
|
64
|
-
* - parsed : Function
|
65
|
-
* A callback function to access the parsed columns, the two-dimentional input data
|
66
|
-
* array directly, before they are interpreted into series data and categories. See also
|
67
|
-
* the complete callback, that goes in on a later stage where the raw columns are interpreted
|
68
|
-
* into a Highcharts option structure. Return false to stop completion, or call this.complete()
|
69
|
-
* to continue async.
|
70
|
-
*
|
71
|
-
* - parseDate : Function
|
72
|
-
* A callback function to parse string representations of dates into JavaScript timestamps.
|
73
|
-
* Return an integer on success.
|
74
|
-
*
|
75
|
-
* - rows : Array<Array<Mixed>>
|
76
|
-
* The same as the columns input option, but defining rows intead of columns.
|
77
|
-
*
|
78
|
-
* - seriesMapping : Array<Object>
|
79
|
-
* An array containing object with Point property names along with what column id the
|
80
|
-
* property should be taken from.
|
81
|
-
*
|
82
|
-
* - startColumn : Integer
|
83
|
-
* In tabular input data, the first column (indexed by 0) to use.
|
84
|
-
*
|
85
|
-
* - startRow : Integer
|
86
|
-
* In tabular input data, the first row (indexed by 0) to use.
|
87
|
-
*
|
88
|
-
* - switchRowsAndColumns : Boolean
|
89
|
-
* Switch rows and columns of the input data, so that this.columns effectively becomes the
|
90
|
-
* rows of the data set, and the rows are interpreted as series.
|
91
|
-
*
|
92
|
-
* - table : String|HTMLElement
|
93
|
-
* A HTML table or the id of such to be parsed as input data. Related options ara startRow,
|
94
|
-
* endRow, startColumn and endColumn to delimit what part of the table is used.
|
95
|
-
*/
|
96
|
-
|
97
|
-
/*
|
98
|
-
* TODO:
|
99
|
-
* - Handle various date formats
|
100
|
-
* - http://jsfiddle.net/highcharts/114wejdx/
|
101
|
-
* - http://jsfiddle.net/highcharts/ryv67bkq/
|
102
|
-
*/
|
103
|
-
|
104
10
|
// JSLint options:
|
105
11
|
/*global jQuery, HighchartsAdapter */
|
106
12
|
|
107
|
-
(function (Highcharts) {
|
13
|
+
(function (Highcharts) {
|
108
14
|
|
109
15
|
// Utilities
|
110
16
|
var each = Highcharts.each,
|
17
|
+
pick = Highcharts.pick,
|
111
18
|
inArray = HighchartsAdapter.inArray,
|
112
19
|
splat = Highcharts.splat,
|
113
20
|
SeriesBuilder;
|
@@ -128,6 +35,8 @@
|
|
128
35
|
this.options = options;
|
129
36
|
this.chartOptions = chartOptions;
|
130
37
|
this.columns = options.columns || this.rowsToColumns(options.rows) || [];
|
38
|
+
this.firstRowAsNames = pick(options.firstRowAsNames, true);
|
39
|
+
this.decimalRegex = options.decimalPoint && new RegExp('^([0-9]+)' + options.decimalPoint + '([0-9]+)$');
|
131
40
|
|
132
41
|
// This is a two-dimensional array holding the raw, trimmed string values
|
133
42
|
// with the same organisation as the columns array. It makes it possible
|
@@ -172,7 +81,7 @@
|
|
172
81
|
globalType = chartOptions && chartOptions.chart && chartOptions.chart.type,
|
173
82
|
individualCounts = [],
|
174
83
|
seriesBuilders = [],
|
175
|
-
seriesIndex,
|
84
|
+
seriesIndex = 0,
|
176
85
|
i;
|
177
86
|
|
178
87
|
each((chartOptions && chartOptions.series) || [], function (series) {
|
@@ -253,9 +162,6 @@
|
|
253
162
|
// Interpret the values into right types
|
254
163
|
this.parseTypes();
|
255
164
|
|
256
|
-
// Use first row for series names?
|
257
|
-
this.findHeaderRow();
|
258
|
-
|
259
165
|
// Handle columns if a handleColumns callback is given
|
260
166
|
if (this.parsed() !== false) {
|
261
167
|
|
@@ -420,26 +326,23 @@
|
|
420
326
|
}
|
421
327
|
},
|
422
328
|
|
423
|
-
/**
|
424
|
-
* Find the header row. For now, we just check whether the first row contains
|
425
|
-
* numbers or strings. Later we could loop down and find the first row with
|
426
|
-
* numbers.
|
427
|
-
*/
|
428
|
-
findHeaderRow: function () {
|
429
|
-
var headerRow = 0;
|
430
|
-
each(this.columns, function (column) {
|
431
|
-
if (column.isNumeric && typeof column[0] !== 'string') {
|
432
|
-
headerRow = null;
|
433
|
-
}
|
434
|
-
});
|
435
|
-
this.headerRow = headerRow;
|
436
|
-
},
|
437
|
-
|
438
329
|
/**
|
439
330
|
* Trim a string from whitespace
|
440
331
|
*/
|
441
|
-
trim: function (str) {
|
442
|
-
|
332
|
+
trim: function (str, inside) {
|
333
|
+
if (typeof str === 'string') {
|
334
|
+
str = str.replace(/^\s+|\s+$/g, '');
|
335
|
+
|
336
|
+
// Clear white space insdie the string, like thousands separators
|
337
|
+
if (inside && /^[0-9\s]+$/.test(str)) {
|
338
|
+
str = str.replace(/\s/g, '');
|
339
|
+
}
|
340
|
+
|
341
|
+
if (this.decimalRegex) {
|
342
|
+
str = str.replace(this.decimalRegex, '$1.$2');
|
343
|
+
}
|
344
|
+
}
|
345
|
+
return str;
|
443
346
|
},
|
444
347
|
|
445
348
|
/**
|
@@ -447,97 +350,118 @@
|
|
447
350
|
*/
|
448
351
|
parseTypes: function () {
|
449
352
|
var columns = this.columns,
|
450
|
-
|
451
|
-
|
452
|
-
|
353
|
+
col = columns.length;
|
354
|
+
|
355
|
+
while (col--) {
|
356
|
+
this.parseColumn(columns[col], col);
|
357
|
+
}
|
358
|
+
|
359
|
+
},
|
360
|
+
|
361
|
+
/**
|
362
|
+
* Parse a single column. Set properties like .isDatetime and .isNumeric.
|
363
|
+
*/
|
364
|
+
parseColumn: function (column, col) {
|
365
|
+
var rawColumns = this.rawColumns,
|
366
|
+
columns = this.columns,
|
367
|
+
row = column.length,
|
453
368
|
val,
|
454
369
|
floatVal,
|
455
370
|
trimVal,
|
456
|
-
|
371
|
+
trimInsideVal,
|
372
|
+
firstRowAsNames = this.firstRowAsNames,
|
373
|
+
isXColumn = inArray(col, this.valueCount.xColumns) !== -1,
|
457
374
|
dateVal,
|
458
|
-
descending,
|
459
375
|
backup = [],
|
460
376
|
diff,
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
377
|
+
chartOptions = this.chartOptions,
|
378
|
+
descending,
|
379
|
+
columnTypes = this.options.columnTypes || [],
|
380
|
+
columnType = columnTypes[col],
|
381
|
+
forceCategory = isXColumn && ((chartOptions && chartOptions.xAxis && splat(chartOptions.xAxis)[0].type === 'category') || columnType === 'string');
|
382
|
+
|
383
|
+
if (!rawColumns[col]) {
|
467
384
|
rawColumns[col] = [];
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
columns[col].isNumeric = true;
|
489
|
-
}
|
385
|
+
}
|
386
|
+
while (row--) {
|
387
|
+
val = backup[row] || column[row];
|
388
|
+
|
389
|
+
trimVal = this.trim(val);
|
390
|
+
trimInsideVal = this.trim(val, true);
|
391
|
+
floatVal = parseFloat(trimInsideVal);
|
392
|
+
|
393
|
+
// Set it the first time
|
394
|
+
if (rawColumns[col][row] === undefined) {
|
395
|
+
rawColumns[col][row] = trimVal;
|
396
|
+
}
|
397
|
+
|
398
|
+
// Disable number or date parsing by setting the X axis type to category
|
399
|
+
if (forceCategory || (row === 0 && firstRowAsNames)) {
|
400
|
+
column[row] = trimVal;
|
401
|
+
|
402
|
+
} else if (+trimInsideVal === floatVal) { // is numeric
|
403
|
+
|
404
|
+
column[row] = floatVal;
|
490
405
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
406
|
+
// If the number is greater than milliseconds in a year, assume datetime
|
407
|
+
if (floatVal > 365 * 24 * 3600 * 1000 && columnType !== 'float') {
|
408
|
+
column.isDatetime = true;
|
409
|
+
} else {
|
410
|
+
column.isNumeric = true;
|
411
|
+
}
|
412
|
+
|
413
|
+
if (column[row + 1] !== undefined) {
|
414
|
+
descending = floatVal > column[row + 1];
|
415
|
+
}
|
416
|
+
|
417
|
+
// String, continue to determine if it is a date string or really a string
|
418
|
+
} else {
|
419
|
+
dateVal = this.parseDate(val);
|
420
|
+
// Only allow parsing of dates if this column is an x-column
|
421
|
+
if (isXColumn && typeof dateVal === 'number' && !isNaN(dateVal) && columnType !== 'float') { // is date
|
422
|
+
backup[row] = val;
|
423
|
+
column[row] = dateVal;
|
424
|
+
column.isDatetime = true;
|
425
|
+
|
426
|
+
// Check if the dates are uniformly descending or ascending. If they
|
427
|
+
// are not, chances are that they are a different time format, so check
|
428
|
+
// for alternative.
|
429
|
+
if (column[row + 1] !== undefined) {
|
430
|
+
diff = dateVal > column[row + 1];
|
431
|
+
if (diff !== descending && descending !== undefined) {
|
432
|
+
if (this.alternativeFormat) {
|
433
|
+
this.dateFormat = this.alternativeFormat;
|
434
|
+
row = column.length;
|
435
|
+
this.alternativeFormat = this.dateFormats[this.dateFormat].alternative;
|
436
|
+
} else {
|
437
|
+
column.unsorted = true;
|
512
438
|
}
|
513
|
-
descending = diff;
|
514
|
-
}
|
515
|
-
|
516
|
-
} else { // string
|
517
|
-
columns[col][row] = trimVal === '' ? null : trimVal;
|
518
|
-
if (row !== 0 && (columns[col].isDatetime || columns[col].isNumeric)) {
|
519
|
-
columns[col].mixed = true;
|
520
439
|
}
|
440
|
+
descending = diff;
|
441
|
+
}
|
442
|
+
|
443
|
+
} else { // string
|
444
|
+
column[row] = trimVal === '' ? null : trimVal;
|
445
|
+
if (row !== 0 && (column.isDatetime || column.isNumeric)) {
|
446
|
+
column.mixed = true;
|
521
447
|
}
|
522
448
|
}
|
523
449
|
}
|
450
|
+
}
|
524
451
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
}
|
452
|
+
// If strings are intermixed with numbers or dates in a parsed column, it is an indication
|
453
|
+
// that parsing went wrong or the data was not intended to display as numbers or dates and
|
454
|
+
// parsing is too aggressive. Fall back to categories. Demonstrated in the
|
455
|
+
// highcharts/demo/column-drilldown sample.
|
456
|
+
if (isXColumn && column.mixed) {
|
457
|
+
columns[col] = rawColumns[col];
|
532
458
|
}
|
533
459
|
|
534
|
-
// If the 0 column is date and descending, reverse all columns.
|
535
|
-
|
536
|
-
if (columns[0].isDatetime && descending) {
|
537
|
-
hasHeaderRow = typeof columns[0][0] !== 'number';
|
460
|
+
// If the 0 column is date or number and descending, reverse all columns.
|
461
|
+
if (isXColumn && descending && this.options.sort) {
|
538
462
|
for (col = 0; col < columns.length; col++) {
|
539
463
|
columns[col].reverse();
|
540
|
-
if (
|
464
|
+
if (firstRowAsNames) {
|
541
465
|
columns[col].unshift(columns[col].pop());
|
542
466
|
}
|
543
467
|
}
|
@@ -578,7 +502,6 @@
|
|
578
502
|
'mm/dd/YY': {
|
579
503
|
regex: /^([0-9]{1,2})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{2})$/,
|
580
504
|
parser: function (match) {
|
581
|
-
console.log(match)
|
582
505
|
return Date.UTC(+match[3] + 2000, match[1] - 1, +match[2]);
|
583
506
|
}
|
584
507
|
}
|
@@ -731,7 +654,7 @@
|
|
731
654
|
|
732
655
|
// Get the names and shift the top row
|
733
656
|
for (i = 0; i < columns.length; i++) {
|
734
|
-
if (this.
|
657
|
+
if (this.firstRowAsNames) {
|
735
658
|
columns[i].name = columns[i].shift();
|
736
659
|
}
|
737
660
|
}
|
@@ -812,17 +735,23 @@
|
|
812
735
|
if (builder.name) {
|
813
736
|
series[seriesIndex].name = builder.name;
|
814
737
|
}
|
738
|
+
if (type === 'category') {
|
739
|
+
series[seriesIndex].turboThreshold = 0;
|
740
|
+
}
|
815
741
|
}
|
816
742
|
|
817
743
|
|
818
744
|
|
819
745
|
// Do the callback
|
820
746
|
chartOptions = {
|
821
|
-
xAxis: {
|
822
|
-
type: type
|
823
|
-
},
|
824
747
|
series: series
|
825
748
|
};
|
749
|
+
if (type) {
|
750
|
+
chartOptions.xAxis = {
|
751
|
+
type: type
|
752
|
+
};
|
753
|
+
}
|
754
|
+
|
826
755
|
if (options.complete) {
|
827
756
|
options.complete(chartOptions);
|
828
757
|
}
|
@@ -7,7 +7,7 @@
|
|
7
7
|
* Demo: http://jsfiddle.net/highcharts/Vf3yT/
|
8
8
|
*/
|
9
9
|
|
10
|
-
/*global HighchartsAdapter*/
|
10
|
+
/*global Highcharts,HighchartsAdapter*/
|
11
11
|
(function (H) {
|
12
12
|
|
13
13
|
"use strict";
|
@@ -25,18 +25,39 @@
|
|
25
25
|
ColumnSeries = seriesTypes.column,
|
26
26
|
fireEvent = HighchartsAdapter.fireEvent,
|
27
27
|
inArray = HighchartsAdapter.inArray,
|
28
|
-
dupes = []
|
28
|
+
dupes = [],
|
29
|
+
ddSeriesId = 1;
|
29
30
|
|
30
31
|
// Utilities
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
/*
|
33
|
+
* Return an intermediate color between two colors, according to pos where 0
|
34
|
+
* is the from color and 1 is the to color
|
35
|
+
*/
|
36
|
+
function tweenColors(from, to, pos) {
|
37
|
+
// Check for has alpha, because rgba colors perform worse due to lack of
|
38
|
+
// support in WebKit.
|
39
|
+
var hasAlpha;
|
40
|
+
|
41
|
+
from = from.rgba;
|
42
|
+
to = to.rgba;
|
43
|
+
hasAlpha = (to[3] !== 1 || from[3] !== 1);
|
44
|
+
if (!to.length || !from.length) {
|
45
|
+
Highcharts.error(23);
|
46
|
+
}
|
47
|
+
return (hasAlpha ? 'rgba(' : 'rgb(') +
|
48
|
+
Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
|
49
|
+
Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
|
50
|
+
Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
|
51
|
+
(hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
|
39
52
|
}
|
53
|
+
/**
|
54
|
+
* Handle animation of the color attributes directly
|
55
|
+
*/
|
56
|
+
each(['fill', 'stroke'], function (prop) {
|
57
|
+
HighchartsAdapter.addAnimSetter(prop, function (fx) {
|
58
|
+
fx.elem.attr(prop, tweenColors(H.Color(fx.start), H.Color(fx.end), fx.pos));
|
59
|
+
});
|
60
|
+
});
|
40
61
|
|
41
62
|
// Add language
|
42
63
|
extend(defaultOptions.lang, {
|
@@ -101,10 +122,11 @@
|
|
101
122
|
level,
|
102
123
|
levelNumber;
|
103
124
|
|
104
|
-
levelNumber = oldSeries.
|
125
|
+
levelNumber = oldSeries.options._levelNumber || 0;
|
105
126
|
|
106
127
|
ddOptions = extend({
|
107
|
-
color: color
|
128
|
+
color: color,
|
129
|
+
_ddSeriesId: ddSeriesId++
|
108
130
|
}, ddOptions);
|
109
131
|
pointIndex = inArray(point, oldSeries.points);
|
110
132
|
|
@@ -112,19 +134,21 @@
|
|
112
134
|
each(oldSeries.chart.series, function (series) {
|
113
135
|
if (series.xAxis === xAxis) {
|
114
136
|
levelSeries.push(series);
|
115
|
-
|
116
|
-
series.
|
137
|
+
series.options._ddSeriesId = series.options._ddSeriesId || ddSeriesId++;
|
138
|
+
series.options._colorIndex = series.userOptions._colorIndex;
|
139
|
+
levelSeriesOptions.push(series.options);
|
140
|
+
series.options._levelNumber = series.options._levelNumber || levelNumber; // #3182
|
117
141
|
}
|
118
142
|
});
|
119
143
|
|
120
144
|
// Add a record of properties for each drilldown level
|
121
145
|
level = {
|
122
146
|
levelNumber: levelNumber,
|
123
|
-
seriesOptions: oldSeries.
|
147
|
+
seriesOptions: oldSeries.options,
|
124
148
|
levelSeriesOptions: levelSeriesOptions,
|
125
149
|
levelSeries: levelSeries,
|
126
150
|
shapeArgs: point.shapeArgs,
|
127
|
-
bBox: point.graphic.getBBox(),
|
151
|
+
bBox: point.graphic ? point.graphic.getBBox() : {}, // no graphic in line series with markers disabled
|
128
152
|
color: color,
|
129
153
|
lowerSeriesOptions: ddOptions,
|
130
154
|
pointOptions: oldSeries.options.data[pointIndex],
|
@@ -144,7 +168,7 @@
|
|
144
168
|
this.drilldownLevels.push(level);
|
145
169
|
|
146
170
|
newSeries = level.lowerSeries = this.addSeries(ddOptions, false);
|
147
|
-
newSeries.
|
171
|
+
newSeries.options._levelNumber = levelNumber + 1;
|
148
172
|
if (xAxis) {
|
149
173
|
xAxis.oldPos = xAxis.pos;
|
150
174
|
xAxis.userMin = xAxis.userMax = null;
|
@@ -167,7 +191,7 @@
|
|
167
191
|
each(this.drilldownLevels, function (level) {
|
168
192
|
if (level.levelNumber === levelToRemove) {
|
169
193
|
each(level.levelSeries, function (series) {
|
170
|
-
if (series.
|
194
|
+
if (series.options && series.options._levelNumber === levelToRemove) { // Not removed, not added as part of a multi-series drilldown
|
171
195
|
series.remove(false);
|
172
196
|
}
|
173
197
|
});
|
@@ -233,7 +257,7 @@
|
|
233
257
|
levelNumber = drilldownLevels[drilldownLevels.length - 1].levelNumber,
|
234
258
|
i = drilldownLevels.length,
|
235
259
|
chartSeries = chart.series,
|
236
|
-
seriesI
|
260
|
+
seriesI,
|
237
261
|
level,
|
238
262
|
oldSeries,
|
239
263
|
newSeries,
|
@@ -241,7 +265,7 @@
|
|
241
265
|
addSeries = function (seriesOptions) {
|
242
266
|
var addedSeries;
|
243
267
|
each(chartSeries, function (series) {
|
244
|
-
if (series.
|
268
|
+
if (series.options._ddSeriesId === seriesOptions._ddSeriesId) {
|
245
269
|
addedSeries = series;
|
246
270
|
}
|
247
271
|
});
|
@@ -254,7 +278,7 @@
|
|
254
278
|
newSeries = addedSeries;
|
255
279
|
}
|
256
280
|
};
|
257
|
-
|
281
|
+
|
258
282
|
while (i--) {
|
259
283
|
|
260
284
|
level = drilldownLevels[i];
|
@@ -264,6 +288,7 @@
|
|
264
288
|
// Get the lower series by reference or id
|
265
289
|
oldSeries = level.lowerSeries;
|
266
290
|
if (!oldSeries.chart) { // #2786
|
291
|
+
seriesI = chartSeries.length; // #2919
|
267
292
|
while (seriesI--) {
|
268
293
|
if (chartSeries[seriesI].options.id === level.lowerSeriesOptions.id) {
|
269
294
|
oldSeries = chartSeries[seriesI];
|
@@ -281,11 +306,11 @@
|
|
281
306
|
newSeries.drilldownLevel = level;
|
282
307
|
newSeries.options.animation = chart.options.drilldown.animation;
|
283
308
|
|
284
|
-
if (oldSeries.animateDrillupFrom) {
|
309
|
+
if (oldSeries.animateDrillupFrom && oldSeries.chart) { // #2919
|
285
310
|
oldSeries.animateDrillupFrom(level);
|
286
311
|
}
|
287
312
|
}
|
288
|
-
newSeries.
|
313
|
+
newSeries.options._levelNumber = levelNumber;
|
289
314
|
|
290
315
|
oldSeries.remove(false);
|
291
316
|
|
@@ -325,7 +350,9 @@
|
|
325
350
|
level = newSeries.drilldownLevel;
|
326
351
|
|
327
352
|
each(this.points, function (point) {
|
328
|
-
point.graphic
|
353
|
+
if (point.graphic) { // #3407
|
354
|
+
point.graphic.hide();
|
355
|
+
}
|
329
356
|
if (point.dataLabel) {
|
330
357
|
point.dataLabel.hide();
|
331
358
|
}
|
@@ -337,18 +364,22 @@
|
|
337
364
|
|
338
365
|
// Do dummy animation on first point to get to complete
|
339
366
|
setTimeout(function () {
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
367
|
+
if (newSeries.points) { // May be destroyed in the meantime, #3389
|
368
|
+
each(newSeries.points, function (point, i) {
|
369
|
+
// Fade in other points
|
370
|
+
var verb = i === (level && level.pointIndex) ? 'show' : 'fadeIn',
|
371
|
+
inherit = verb === 'show' ? true : undefined;
|
372
|
+
if (point.graphic) { // #3407
|
373
|
+
point.graphic[verb](inherit);
|
374
|
+
}
|
375
|
+
if (point.dataLabel) {
|
376
|
+
point.dataLabel[verb](inherit);
|
377
|
+
}
|
378
|
+
if (point.connector) {
|
379
|
+
point.connector[verb](inherit);
|
380
|
+
}
|
381
|
+
});
|
382
|
+
}
|
352
383
|
}, Math.max(this.chart.options.drilldown.animation.duration - 50, 0));
|
353
384
|
|
354
385
|
// Reset
|
@@ -360,23 +391,28 @@
|
|
360
391
|
ColumnSeries.prototype.animateDrilldown = function (init) {
|
361
392
|
var series = this,
|
362
393
|
drilldownLevels = this.chart.drilldownLevels,
|
363
|
-
animateFrom
|
364
|
-
animationOptions = this.chart.options.drilldown.animation
|
394
|
+
animateFrom,
|
395
|
+
animationOptions = this.chart.options.drilldown.animation,
|
396
|
+
xAxis = this.xAxis;
|
365
397
|
|
366
398
|
if (!init) {
|
367
399
|
each(drilldownLevels, function (level) {
|
368
|
-
if (series.
|
400
|
+
if (series.options._ddSeriesId === level.lowerSeriesOptions._ddSeriesId) {
|
369
401
|
animateFrom = level.shapeArgs;
|
402
|
+
animateFrom.fill = level.color;
|
370
403
|
}
|
371
404
|
});
|
372
405
|
|
373
|
-
animateFrom.x += (
|
374
|
-
|
406
|
+
animateFrom.x += (pick(xAxis.oldPos, xAxis.pos) - xAxis.pos);
|
407
|
+
|
375
408
|
each(this.points, function (point) {
|
376
409
|
if (point.graphic) {
|
377
410
|
point.graphic
|
378
411
|
.attr(animateFrom)
|
379
|
-
.animate(
|
412
|
+
.animate(
|
413
|
+
extend(point.shapeArgs, { fill: point.color }),
|
414
|
+
animationOptions
|
415
|
+
);
|
380
416
|
}
|
381
417
|
if (point.dataLabel) {
|
382
418
|
point.dataLabel.fadeIn(animationOptions);
|
@@ -407,8 +443,6 @@
|
|
407
443
|
delete this.group;
|
408
444
|
each(this.points, function (point) {
|
409
445
|
var graphic = point.graphic,
|
410
|
-
startColor = H.Color(point.color).rgba,
|
411
|
-
endColor = H.Color(level.color).rgba,
|
412
446
|
complete = function () {
|
413
447
|
graphic.destroy();
|
414
448
|
if (group) {
|
@@ -421,18 +455,10 @@
|
|
421
455
|
delete point.graphic;
|
422
456
|
|
423
457
|
if (animationOptions) {
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
this.attr({
|
429
|
-
fill: tweenColors(startColor, endColor, fx.pos)
|
430
|
-
});
|
431
|
-
}
|
432
|
-
},
|
433
|
-
complete: complete
|
434
|
-
}));
|
435
|
-
/*jslint unparam: false*/
|
458
|
+
graphic.animate(
|
459
|
+
extend(level.shapeArgs, { fill: level.color }),
|
460
|
+
H.merge(animationOptions, { complete: complete })
|
461
|
+
);
|
436
462
|
} else {
|
437
463
|
graphic.attr(level.shapeArgs);
|
438
464
|
complete();
|
@@ -453,28 +479,19 @@
|
|
453
479
|
animateFrom = level.shapeArgs,
|
454
480
|
start = animateFrom.start,
|
455
481
|
angle = animateFrom.end - start,
|
456
|
-
startAngle = angle / this.points.length
|
457
|
-
startColor = H.Color(level.color).rgba;
|
482
|
+
startAngle = angle / this.points.length;
|
458
483
|
|
459
484
|
if (!init) {
|
460
485
|
each(this.points, function (point, i) {
|
461
|
-
var endColor = H.Color(point.color).rgba;
|
462
|
-
|
463
|
-
/*jslint unparam: true*/
|
464
486
|
point.graphic
|
465
487
|
.attr(H.merge(animateFrom, {
|
466
488
|
start: start + i * startAngle,
|
467
|
-
end: start + (i + 1) * startAngle
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
});
|
474
|
-
}
|
475
|
-
}
|
476
|
-
}));
|
477
|
-
/*jslint unparam: false*/
|
489
|
+
end: start + (i + 1) * startAngle,
|
490
|
+
fill: level.color
|
491
|
+
}))[animationOptions ? 'animate' : 'attr'](
|
492
|
+
extend(point.shapeArgs, { fill: point.color }),
|
493
|
+
animationOptions
|
494
|
+
);
|
478
495
|
});
|
479
496
|
this.animate = null;
|
480
497
|
}
|
@@ -482,7 +499,7 @@
|
|
482
499
|
});
|
483
500
|
}
|
484
501
|
|
485
|
-
H.Point.prototype.doDrilldown = function (_holdRedraw) {
|
502
|
+
H.Point.prototype.doDrilldown = function (_holdRedraw, category) {
|
486
503
|
var series = this.series,
|
487
504
|
chart = series.chart,
|
488
505
|
drilldown = chart.options.drilldown,
|
@@ -500,7 +517,8 @@
|
|
500
517
|
// seriesOptions, and call addSeriesAsDrilldown async if necessary.
|
501
518
|
fireEvent(chart, 'drilldown', {
|
502
519
|
point: this,
|
503
|
-
seriesOptions: seriesOptions
|
520
|
+
seriesOptions: seriesOptions,
|
521
|
+
category: category
|
504
522
|
});
|
505
523
|
|
506
524
|
if (seriesOptions) {
|
@@ -510,7 +528,18 @@
|
|
510
528
|
chart.addSeriesAsDrilldown(this, seriesOptions);
|
511
529
|
}
|
512
530
|
}
|
531
|
+
};
|
513
532
|
|
533
|
+
/**
|
534
|
+
* Drill down to a given category. This is the same as clicking on an axis label.
|
535
|
+
*/
|
536
|
+
H.Axis.prototype.drilldownCategory = function (x) {
|
537
|
+
each(this.ticks[x].label.ddPoints, function (point) {
|
538
|
+
if (point.series && point.series.visible && point.doDrilldown) { // #3197
|
539
|
+
point.doDrilldown(true, x);
|
540
|
+
}
|
541
|
+
});
|
542
|
+
this.chart.applyDrilldown();
|
514
543
|
};
|
515
544
|
|
516
545
|
wrap(H.Point.prototype, 'init', function (proceed, series, options, x) {
|
@@ -543,12 +572,7 @@
|
|
543
572
|
.addClass('highcharts-drilldown-axis-label')
|
544
573
|
.css(chart.options.drilldown.activeAxisLabelStyle)
|
545
574
|
.on('click', function () {
|
546
|
-
|
547
|
-
if (point.doDrilldown) {
|
548
|
-
point.doDrilldown(true);
|
549
|
-
}
|
550
|
-
});
|
551
|
-
chart.applyDrilldown();
|
575
|
+
series.xAxis.drilldownCategory(x);
|
552
576
|
});
|
553
577
|
if (!tickLabel.ddPoints) {
|
554
578
|
tickLabel.ddPoints = [];
|