highcharts-rails 2.3.3.1 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.markdown +4 -0
- data/lib/highcharts/version.rb +1 -1
- data/vendor/assets/javascripts/highcharts.js +677 -507
- data/vendor/assets/javascripts/highcharts/adapters/mootools.js +15 -14
- data/vendor/assets/javascripts/highcharts/adapters/prototype.js +1 -1
- data/vendor/assets/javascripts/highcharts/highcharts-more.js +1581 -35
- data/vendor/assets/javascripts/highcharts/modules/canvas-tools.js +2792 -2792
- data/vendor/assets/javascripts/highcharts/modules/data.js +248 -13
- data/vendor/assets/javascripts/highcharts/modules/exporting.js +75 -59
- metadata +2 -2
@@ -7,9 +7,76 @@
|
|
7
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
|
+
*
|
10
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 series and an xAxis with categories if applicable. Thise options
|
28
|
+
* can be extended with additional options and passed directly to the chart constructor.
|
29
|
+
*
|
30
|
+
* - csv : String
|
31
|
+
* A comma delimited string to be parsed. Related options are startRow, endRow, startColumn
|
32
|
+
* and endColumn to delimit what part of the table is used. The lineDelimiter and
|
33
|
+
* itemDelimiter options define the CSV delimiter formats.
|
34
|
+
*
|
35
|
+
* - endColumn : Integer
|
36
|
+
* In tabular input data, the first row (indexed by 0) to use. Defaults to the last
|
37
|
+
* column containing data.
|
38
|
+
*
|
39
|
+
* - endRow : Integer
|
40
|
+
* In tabular input data, the last row (indexed by 0) to use. Defaults to the last row
|
41
|
+
* containing data.
|
42
|
+
*
|
43
|
+
* - googleSpreadsheetKey : String
|
44
|
+
* A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample
|
45
|
+
* for general information on GS.
|
46
|
+
*
|
47
|
+
* - googleSpreadsheetKey : String
|
48
|
+
* The Google Spreadsheet worksheet. The available id's can be read from
|
49
|
+
* https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic
|
50
|
+
*
|
51
|
+
* - itemDilimiter : String
|
52
|
+
* Item or cell delimiter for parsing CSV. Defaults to ",".
|
53
|
+
*
|
54
|
+
* - lineDilimiter : String
|
55
|
+
* Line delimiter for parsing CSV. Defaults to "\n".
|
56
|
+
*
|
57
|
+
* - parsed : Function
|
58
|
+
* A callback function to access the parsed columns, the two-dimentional input data
|
59
|
+
* array directly, before they are interpreted into series data and categories.
|
60
|
+
*
|
61
|
+
* - parseDate : Function
|
62
|
+
* A callback function to parse string representations of dates into JavaScript timestamps.
|
63
|
+
* Return an integer on success.
|
64
|
+
*
|
65
|
+
* - rows : Array<Array<Mixed>>
|
66
|
+
* The same as the columns input option, but defining rows intead of columns.
|
67
|
+
*
|
68
|
+
* - startColumn : Integer
|
69
|
+
* In tabular input data, the first column (indexed by 0) to use.
|
70
|
+
*
|
71
|
+
* - startRow : Integer
|
72
|
+
* In tabular input data, the first row (indexed by 0) to use.
|
73
|
+
*
|
74
|
+
* - table : String|HTMLElement
|
75
|
+
* A HTML table or the id of such to be parsed as input data. Related options ara startRow,
|
76
|
+
* endRow, startColumn and endColumn to delimit what part of the table is used.
|
11
77
|
*/
|
12
78
|
|
79
|
+
/*global jQuery */
|
13
80
|
(function (Highcharts) {
|
14
81
|
|
15
82
|
// Utilities
|
@@ -29,14 +96,28 @@
|
|
29
96
|
*/
|
30
97
|
init: function (options) {
|
31
98
|
this.options = options;
|
32
|
-
this.columns = [];
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
// Parse
|
39
|
-
|
99
|
+
this.columns = options.columns || this.rowsToColumns(options.rows) || [];
|
100
|
+
|
101
|
+
// No need to parse or interpret anything
|
102
|
+
if (this.columns.length) {
|
103
|
+
this.dataFound();
|
104
|
+
|
105
|
+
// Parse and interpret
|
106
|
+
} else {
|
107
|
+
|
108
|
+
// Parse a CSV string if options.csv is given
|
109
|
+
this.parseCSV();
|
110
|
+
|
111
|
+
// Parse a HTML table if options.table is given
|
112
|
+
this.parseTable();
|
113
|
+
|
114
|
+
// Parse a Google Spreadsheet
|
115
|
+
this.parseGoogleSpreadsheet();
|
116
|
+
}
|
117
|
+
|
118
|
+
},
|
119
|
+
|
120
|
+
dataFound: function () {
|
40
121
|
|
41
122
|
// Interpret the values into right types
|
42
123
|
this.parseTypes();
|
@@ -66,7 +147,11 @@
|
|
66
147
|
lines;
|
67
148
|
|
68
149
|
if (csv) {
|
69
|
-
|
150
|
+
|
151
|
+
lines = csv
|
152
|
+
.replace(/\r\n/g, "\n") // Unix
|
153
|
+
.replace(/\r/g, "\n") // Mac
|
154
|
+
.split(options.lineDelimiter || "\n");
|
70
155
|
|
71
156
|
each(lines, function (line, rowNo) {
|
72
157
|
if (rowNo >= startRow && rowNo <= endRow) {
|
@@ -81,7 +166,8 @@
|
|
81
166
|
}
|
82
167
|
});
|
83
168
|
}
|
84
|
-
});
|
169
|
+
});
|
170
|
+
this.dataFound();
|
85
171
|
}
|
86
172
|
},
|
87
173
|
|
@@ -119,6 +205,58 @@
|
|
119
205
|
});
|
120
206
|
}
|
121
207
|
});
|
208
|
+
|
209
|
+
this.dataFound(); // continue
|
210
|
+
}
|
211
|
+
},
|
212
|
+
|
213
|
+
/**
|
214
|
+
* TODO:
|
215
|
+
* - switchRowsAndColumns
|
216
|
+
* - startRow, endRow etc.
|
217
|
+
*/
|
218
|
+
parseGoogleSpreadsheet: function () {
|
219
|
+
var self = this,
|
220
|
+
options = this.options,
|
221
|
+
googleSpreadsheetKey = options.googleSpreadsheetKey,
|
222
|
+
columns = this.columns;
|
223
|
+
|
224
|
+
if (googleSpreadsheetKey) {
|
225
|
+
jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' +
|
226
|
+
googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') +
|
227
|
+
'/public/values?alt=json-in-script&callback=?',
|
228
|
+
function (json) {
|
229
|
+
|
230
|
+
// Prepare the data from the spreadsheat
|
231
|
+
var cells = json.feed.entry,
|
232
|
+
cell,
|
233
|
+
cellCount = cells.length,
|
234
|
+
colCount = 0,
|
235
|
+
rowCount = 0,
|
236
|
+
i;
|
237
|
+
|
238
|
+
// First, find the total number of columns and rows that
|
239
|
+
// are actually filled with data
|
240
|
+
for (i = 0; i < cellCount; i++) {
|
241
|
+
cell = cells[i];
|
242
|
+
colCount = Math.max(colCount, cell.gs$cell.col);
|
243
|
+
rowCount = Math.max(rowCount, cell.gs$cell.row);
|
244
|
+
}
|
245
|
+
|
246
|
+
// Set up arrays containing the column data
|
247
|
+
for (i = 0; i < colCount; i++) {
|
248
|
+
columns[i] = new Array(rowCount);
|
249
|
+
}
|
250
|
+
|
251
|
+
// Loop over the cells and assign the value to the right
|
252
|
+
// place in the column arrays
|
253
|
+
for (i = 0; i < cellCount; i++) {
|
254
|
+
cell = cells[i];
|
255
|
+
columns[cell.gs$cell.col - 1][cell.gs$cell.row - 1] =
|
256
|
+
cell.content.$t;
|
257
|
+
}
|
258
|
+
self.dataFound();
|
259
|
+
});
|
122
260
|
}
|
123
261
|
},
|
124
262
|
|
@@ -141,7 +279,8 @@
|
|
141
279
|
* Trim a string from whitespace
|
142
280
|
*/
|
143
281
|
trim: function (str) {
|
144
|
-
return str.replace(/^\s+|\s+$/g, '');
|
282
|
+
//return typeof str === 'number' ? str : str.replace(/^\s+|\s+$/g, ''); // fails with spreadsheet
|
283
|
+
return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str;
|
145
284
|
},
|
146
285
|
|
147
286
|
/**
|
@@ -176,7 +315,7 @@
|
|
176
315
|
}
|
177
316
|
|
178
317
|
} else { // string, continue to determine if it is a date string or really a string
|
179
|
-
dateVal =
|
318
|
+
dateVal = this.parseDate(val);
|
180
319
|
|
181
320
|
if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date
|
182
321
|
columns[col][row] = dateVal;
|
@@ -188,9 +327,73 @@
|
|
188
327
|
}
|
189
328
|
|
190
329
|
}
|
191
|
-
}
|
330
|
+
}
|
331
|
+
},
|
332
|
+
//*
|
333
|
+
dateFormats: {
|
334
|
+
'YYYY-mm-dd': {
|
335
|
+
regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$',
|
336
|
+
parser: function (match) {
|
337
|
+
return Date.UTC(+match[1], match[2] - 1, +match[3]);
|
338
|
+
}
|
339
|
+
}
|
340
|
+
},
|
341
|
+
// */
|
342
|
+
/**
|
343
|
+
* Parse a date and return it as a number. Overridable through options.parseDate.
|
344
|
+
*/
|
345
|
+
parseDate: function (val) {
|
346
|
+
var parseDate = this.options.parseDate,
|
347
|
+
ret,
|
348
|
+
key,
|
349
|
+
format,
|
350
|
+
match;
|
351
|
+
|
352
|
+
if (parseDate) {
|
353
|
+
ret = parseDate;
|
354
|
+
}
|
355
|
+
|
356
|
+
if (typeof val === 'string') {
|
357
|
+
for (key in this.dateFormats) {
|
358
|
+
format = this.dateFormats[key];
|
359
|
+
match = val.match(format.regex);
|
360
|
+
if (match) {
|
361
|
+
ret = format.parser(match);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
}
|
365
|
+
return ret;
|
366
|
+
},
|
367
|
+
|
368
|
+
/**
|
369
|
+
* Reorganize rows into columns
|
370
|
+
*/
|
371
|
+
rowsToColumns: function (rows) {
|
372
|
+
var row,
|
373
|
+
rowsLength,
|
374
|
+
col,
|
375
|
+
colsLength,
|
376
|
+
columns;
|
377
|
+
|
378
|
+
if (rows) {
|
379
|
+
columns = [];
|
380
|
+
rowsLength = rows.length;
|
381
|
+
for (row = 0; row < rowsLength; row++) {
|
382
|
+
colsLength = rows[row].length;
|
383
|
+
for (col = 0; col < colsLength; col++) {
|
384
|
+
if (!columns[col]) {
|
385
|
+
columns[col] = [];
|
386
|
+
}
|
387
|
+
columns[col][row] = rows[row][col];
|
388
|
+
}
|
389
|
+
}
|
390
|
+
}
|
391
|
+
return columns;
|
192
392
|
},
|
193
393
|
|
394
|
+
/**
|
395
|
+
* A hook for working directly on the parsed columns
|
396
|
+
*/
|
194
397
|
parsed: function () {
|
195
398
|
if (this.options.parsed) {
|
196
399
|
this.options.parsed.call(this, this.columns);
|
@@ -274,4 +477,36 @@
|
|
274
477
|
Highcharts.data = function (options) {
|
275
478
|
return new Data(options);
|
276
479
|
};
|
480
|
+
|
481
|
+
// Extend Chart.init so that the Chart constructor accepts a new configuration
|
482
|
+
// option group, data.
|
483
|
+
Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) {
|
484
|
+
var chart = this;
|
485
|
+
|
486
|
+
if (userOptions && userOptions.data) {
|
487
|
+
Highcharts.data(Highcharts.extend(userOptions.data, {
|
488
|
+
complete: function (dataOptions) {
|
489
|
+
var datasets = [];
|
490
|
+
|
491
|
+
// Don't merge the data arrays themselves
|
492
|
+
each(dataOptions.series, function (series, i) {
|
493
|
+
datasets[i] = series.data;
|
494
|
+
series.data = null;
|
495
|
+
});
|
496
|
+
|
497
|
+
// Do the merge
|
498
|
+
userOptions = Highcharts.merge(dataOptions, userOptions);
|
499
|
+
|
500
|
+
// Re-insert the data
|
501
|
+
each(datasets, function (data, i) {
|
502
|
+
userOptions.series[i].data = data;
|
503
|
+
});
|
504
|
+
proceed.call(chart, userOptions, callback);
|
505
|
+
}
|
506
|
+
}));
|
507
|
+
} else {
|
508
|
+
proceed.call(chart, userOptions, callback);
|
509
|
+
}
|
510
|
+
});
|
511
|
+
|
277
512
|
}(Highcharts));
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v2.3.
|
2
|
+
* @license Highcharts JS v2.3.5 (2012-12-19)
|
3
3
|
* Exporting module
|
4
4
|
*
|
5
5
|
* (c) 2010-2011 Torstein Hønsi
|
@@ -10,24 +10,23 @@
|
|
10
10
|
// JSLint options:
|
11
11
|
/*global Highcharts, document, window, Math, setTimeout */
|
12
12
|
|
13
|
-
(function () { // encapsulate
|
13
|
+
(function (Highcharts) { // encapsulate
|
14
14
|
|
15
15
|
// create shortcuts
|
16
|
-
var
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
extend = HC.extend,
|
16
|
+
var Chart = Highcharts.Chart,
|
17
|
+
addEvent = Highcharts.addEvent,
|
18
|
+
removeEvent = Highcharts.removeEvent,
|
19
|
+
createElement = Highcharts.createElement,
|
20
|
+
discardElement = Highcharts.discardElement,
|
21
|
+
css = Highcharts.css,
|
22
|
+
merge = Highcharts.merge,
|
23
|
+
each = Highcharts.each,
|
24
|
+
extend = Highcharts.extend,
|
26
25
|
math = Math,
|
27
26
|
mathMax = math.max,
|
28
27
|
doc = document,
|
29
28
|
win = window,
|
30
|
-
|
29
|
+
isTouchDevice = Highcharts.isTouchDevice,
|
31
30
|
M = 'M',
|
32
31
|
L = 'L',
|
33
32
|
DIV = 'div',
|
@@ -37,7 +36,8 @@ var HC = Highcharts,
|
|
37
36
|
ABSOLUTE = 'absolute',
|
38
37
|
PX = 'px',
|
39
38
|
UNDEFINED,
|
40
|
-
|
39
|
+
symbols = Highcharts.Renderer.prototype.symbols,
|
40
|
+
defaultOptions = Highcharts.getOptions();
|
41
41
|
|
42
42
|
// Add language
|
43
43
|
extend(defaultOptions.lang, {
|
@@ -60,7 +60,7 @@ defaultOptions.navigation = {
|
|
60
60
|
padding: '0 5px',
|
61
61
|
background: NONE,
|
62
62
|
color: '#303030',
|
63
|
-
fontSize:
|
63
|
+
fontSize: isTouchDevice ? '14px' : '11px'
|
64
64
|
},
|
65
65
|
menuItemHoverStyle: {
|
66
66
|
background: '#4572A5',
|
@@ -172,7 +172,35 @@ defaultOptions.exporting = {
|
|
172
172
|
}
|
173
173
|
};
|
174
174
|
|
175
|
+
// Add the Highcharts.post utility
|
176
|
+
Highcharts.post = function (url, data) {
|
177
|
+
var name,
|
178
|
+
form;
|
179
|
+
|
180
|
+
// create the form
|
181
|
+
form = createElement('form', {
|
182
|
+
method: 'post',
|
183
|
+
action: url,
|
184
|
+
enctype: 'multipart/form-data'
|
185
|
+
}, {
|
186
|
+
display: NONE
|
187
|
+
}, doc.body);
|
188
|
+
|
189
|
+
// add the data
|
190
|
+
for (name in data) {
|
191
|
+
createElement('input', {
|
192
|
+
type: HIDDEN,
|
193
|
+
name: name,
|
194
|
+
value: data[name]
|
195
|
+
}, null, form);
|
196
|
+
}
|
197
|
+
|
198
|
+
// submit
|
199
|
+
form.submit();
|
175
200
|
|
201
|
+
// clean up
|
202
|
+
discardElement(form);
|
203
|
+
};
|
176
204
|
|
177
205
|
extend(Chart.prototype, {
|
178
206
|
/**
|
@@ -223,12 +251,6 @@ extend(Chart.prototype, {
|
|
223
251
|
});
|
224
252
|
|
225
253
|
if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
|
226
|
-
|
227
|
-
// remove image markers
|
228
|
-
if (seriesOptions && seriesOptions.marker && /^url\(/.test(seriesOptions.marker.symbol)) {
|
229
|
-
seriesOptions.marker.symbol = 'circle';
|
230
|
-
}
|
231
|
-
|
232
254
|
options.series.push(seriesOptions);
|
233
255
|
}
|
234
256
|
});
|
@@ -308,43 +330,23 @@ extend(Chart.prototype, {
|
|
308
330
|
* @param {Object} chartOptions Additional chart options for the SVG representation of the chart
|
309
331
|
*/
|
310
332
|
exportChart: function (options, chartOptions) {
|
311
|
-
var
|
312
|
-
|
313
|
-
svg = chart.getSVG(merge(chart.options.exporting.chartOptions, chartOptions)); // docs
|
333
|
+
var exportingOptions = this.options.exporting,
|
334
|
+
svg = this.getSVG(merge(exportingOptions.chartOptions, chartOptions));
|
314
335
|
|
315
336
|
// merge the options
|
316
|
-
options = merge(
|
317
|
-
|
318
|
-
//
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
}, doc.body);
|
326
|
-
|
327
|
-
// add the values
|
328
|
-
each(['filename', 'type', 'width', 'svg'], function (name) {
|
329
|
-
createElement('input', {
|
330
|
-
type: HIDDEN,
|
331
|
-
name: name,
|
332
|
-
value: {
|
333
|
-
filename: options.filename || 'chart',
|
334
|
-
type: options.type,
|
335
|
-
width: options.width,
|
336
|
-
svg: svg
|
337
|
-
}[name]
|
338
|
-
}, null, form);
|
337
|
+
options = merge(exportingOptions, options);
|
338
|
+
|
339
|
+
// do the post
|
340
|
+
Highcharts.post(options.url, {
|
341
|
+
filename: options.filename || 'chart',
|
342
|
+
type: options.type,
|
343
|
+
width: options.width,
|
344
|
+
scale: options.scale || 2,
|
345
|
+
svg: svg
|
339
346
|
});
|
340
347
|
|
341
|
-
// submit
|
342
|
-
form.submit();
|
343
|
-
|
344
|
-
// clean up
|
345
|
-
discardElement(form);
|
346
348
|
},
|
347
|
-
|
349
|
+
|
348
350
|
/**
|
349
351
|
* Print the chart
|
350
352
|
*/
|
@@ -418,6 +420,7 @@ extend(Chart.prototype, {
|
|
418
420
|
boxShadow = '3px 3px 10px #888',
|
419
421
|
innerMenu,
|
420
422
|
hide,
|
423
|
+
hideTimer,
|
421
424
|
menuStyle;
|
422
425
|
|
423
426
|
// create the menu only the first time
|
@@ -444,7 +447,13 @@ extend(Chart.prototype, {
|
|
444
447
|
css(menu, { display: NONE });
|
445
448
|
};
|
446
449
|
|
447
|
-
|
450
|
+
// Hide the menu some time after mouse leave (#1357)
|
451
|
+
addEvent(menu, 'mouseleave', function () {
|
452
|
+
hideTimer = setTimeout(hide, 500);
|
453
|
+
});
|
454
|
+
addEvent(menu, 'mouseenter', function () {
|
455
|
+
clearTimeout(hideTimer);
|
456
|
+
});
|
448
457
|
|
449
458
|
|
450
459
|
// create the items
|
@@ -462,7 +471,7 @@ extend(Chart.prototype, {
|
|
462
471
|
cursor: 'pointer'
|
463
472
|
}, menuItemStyle), innerMenu);
|
464
473
|
|
465
|
-
div
|
474
|
+
div.onclick = function () {
|
466
475
|
hide();
|
467
476
|
item.onclick.apply(chart, arguments);
|
468
477
|
};
|
@@ -511,6 +520,7 @@ extend(Chart.prototype, {
|
|
511
520
|
box,
|
512
521
|
symbol,
|
513
522
|
button,
|
523
|
+
menuKey,
|
514
524
|
borderWidth = btnOptions.borderWidth,
|
515
525
|
boxAttr = {
|
516
526
|
stroke: btnOptions.borderColor
|
@@ -522,6 +532,11 @@ extend(Chart.prototype, {
|
|
522
532
|
},
|
523
533
|
symbolSize = btnOptions.symbolSize || 12;
|
524
534
|
|
535
|
+
if (!chart.btnCount) {
|
536
|
+
chart.btnCount = 0;
|
537
|
+
}
|
538
|
+
menuKey = chart.btnCount++;
|
539
|
+
|
525
540
|
// Keeps references to the button elements
|
526
541
|
if (!chart.exportDivElements) {
|
527
542
|
chart.exportDivElements = [];
|
@@ -587,10 +602,11 @@ extend(Chart.prototype, {
|
|
587
602
|
|
588
603
|
// add the click event
|
589
604
|
if (menuItems) {
|
605
|
+
|
590
606
|
onclick = function () {
|
591
607
|
revert();
|
592
608
|
var bBox = button.getBBox();
|
593
|
-
chart.contextMenu('
|
609
|
+
chart.contextMenu('menu' + menuKey, menuItems, bBox.x, bBox.y, buttonWidth, buttonHeight);
|
594
610
|
};
|
595
611
|
}
|
596
612
|
/*addEvent(button.element, 'click', function() {
|
@@ -665,7 +681,7 @@ function crisp(arr) {
|
|
665
681
|
}
|
666
682
|
|
667
683
|
// Create the export icon
|
668
|
-
|
684
|
+
symbols.exportIcon = function (x, y, width, height) {
|
669
685
|
return crisp([
|
670
686
|
M, // the disk
|
671
687
|
x, y + width,
|
@@ -687,7 +703,7 @@ HC.Renderer.prototype.symbols.exportIcon = function (x, y, width, height) {
|
|
687
703
|
]);
|
688
704
|
};
|
689
705
|
// Create the print icon
|
690
|
-
|
706
|
+
symbols.printIcon = function (x, y, width, height) {
|
691
707
|
return crisp([
|
692
708
|
M, // the printer
|
693
709
|
x, y + height * 0.7,
|
@@ -733,4 +749,4 @@ Chart.prototype.callbacks.push(function (chart) {
|
|
733
749
|
});
|
734
750
|
|
735
751
|
|
736
|
-
}());
|
752
|
+
}(Highcharts));
|