highcharts-rails 2.3.3.1 → 2.3.5
Sign up to get free protection for your applications and to get access to all the features.
- 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));
|