highcharts-rails 2.3.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,8 @@
1
1
  /**
2
- * @license Data plugin for Highcharts v0.1
2
+ * @license Data plugin for Highcharts
3
3
  *
4
- * (c) 2012 Torstein Hønsi
4
+ * (c) 2012-2013 Torstein Hønsi
5
+ * Last revision 2012-11-27
5
6
  *
6
7
  * License: www.highcharts.com/license
7
8
  */
@@ -44,7 +45,7 @@
44
45
  * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample
45
46
  * for general information on GS.
46
47
  *
47
- * - googleSpreadsheetKey : String
48
+ * - googleSpreadsheetWorksheet : String
48
49
  * The Google Spreadsheet worksheet. The available id's can be read from
49
50
  * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic
50
51
  *
@@ -76,7 +77,9 @@
76
77
  * endRow, startColumn and endColumn to delimit what part of the table is used.
77
78
  */
78
79
 
80
+ // JSLint options:
79
81
  /*global jQuery */
82
+
80
83
  (function (Highcharts) {
81
84
 
82
85
  // Utilities
@@ -118,7 +121,6 @@
118
121
  },
119
122
 
120
123
  dataFound: function () {
121
-
122
124
  // Interpret the values into right types
123
125
  this.parseTypes();
124
126
 
@@ -213,13 +215,18 @@
213
215
  /**
214
216
  * TODO:
215
217
  * - switchRowsAndColumns
216
- * - startRow, endRow etc.
217
218
  */
218
219
  parseGoogleSpreadsheet: function () {
219
220
  var self = this,
220
221
  options = this.options,
221
222
  googleSpreadsheetKey = options.googleSpreadsheetKey,
222
- columns = this.columns;
223
+ columns = this.columns,
224
+ startRow = options.startRow || 0,
225
+ endRow = options.endRow || Number.MAX_VALUE,
226
+ startColumn = options.startColumn || 0,
227
+ endColumn = options.endColumn || Number.MAX_VALUE,
228
+ gr, // google row
229
+ gc; // google column
223
230
 
224
231
  if (googleSpreadsheetKey) {
225
232
  jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' +
@@ -245,15 +252,28 @@
245
252
 
246
253
  // Set up arrays containing the column data
247
254
  for (i = 0; i < colCount; i++) {
248
- columns[i] = new Array(rowCount);
255
+ if (i >= startColumn && i <= endColumn) {
256
+ // Create new columns with the length of either end-start or rowCount
257
+ columns[i - startColumn] = [];
258
+
259
+ // Setting the length to avoid jslint warning
260
+ columns[i - startColumn].length = Math.min(rowCount, endRow - startRow);
261
+ }
249
262
  }
250
263
 
251
264
  // Loop over the cells and assign the value to the right
252
265
  // place in the column arrays
253
266
  for (i = 0; i < cellCount; i++) {
254
267
  cell = cells[i];
255
- columns[cell.gs$cell.col - 1][cell.gs$cell.row - 1] =
256
- cell.content.$t;
268
+ gr = cell.gs$cell.row - 1; // rows start at 1
269
+ gc = cell.gs$cell.col - 1; // columns start at 1
270
+
271
+ // If both row and col falls inside start and end
272
+ // set the transposed cell value in the newly created columns
273
+ if (gc >= startColumn && gc <= endColumn &&
274
+ gr >= startRow && gr <= endRow) {
275
+ columns[gc - startColumn][gr - startRow] = cell.content.$t;
276
+ }
257
277
  }
258
278
  self.dataFound();
259
279
  });
@@ -322,7 +342,7 @@
322
342
  columns[col].isDatetime = true;
323
343
 
324
344
  } else { // string
325
- columns[col][row] = trimVal;
345
+ columns[col][row] = trimVal === '' ? null : trimVal;
326
346
  }
327
347
  }
328
348
 
@@ -486,21 +506,17 @@
486
506
  if (userOptions && userOptions.data) {
487
507
  Highcharts.data(Highcharts.extend(userOptions.data, {
488
508
  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
509
 
510
+ // Merge series configs
511
+ if (userOptions.series) {
512
+ each(userOptions.series, function (series, i) {
513
+ userOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]);
514
+ });
515
+ }
516
+
497
517
  // Do the merge
498
518
  userOptions = Highcharts.merge(dataOptions, userOptions);
499
-
500
- // Re-insert the data
501
- each(datasets, function (data, i) {
502
- userOptions.series[i].data = data;
503
- });
519
+
504
520
  proceed.call(chart, userOptions, callback);
505
521
  }
506
522
  }));
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @license Highcharts JS v2.3.5 (2012-12-19)
2
+ * @license Highcharts JS v3.0.0 (2013-03-22)
3
3
  * Exporting module
4
4
  *
5
- * (c) 2010-2011 Torstein Hønsi
5
+ * (c) 2010-2013 Torstein Hønsi
6
6
  *
7
7
  * License: www.highcharts.com/license
8
8
  */
@@ -37,7 +37,8 @@ var Chart = Highcharts.Chart,
37
37
  PX = 'px',
38
38
  UNDEFINED,
39
39
  symbols = Highcharts.Renderer.prototype.symbols,
40
- defaultOptions = Highcharts.getOptions();
40
+ defaultOptions = Highcharts.getOptions(),
41
+ buttonOffset;
41
42
 
42
43
  // Add language
43
44
  extend(defaultOptions.lang, {
@@ -45,19 +46,21 @@ var Chart = Highcharts.Chart,
45
46
  downloadJPEG: 'Download JPEG image',
46
47
  downloadPDF: 'Download PDF document',
47
48
  downloadSVG: 'Download SVG vector image',
48
- exportButtonTitle: 'Export to raster or vector image',
49
- printButtonTitle: 'Print the chart'
49
+ contextButtonTitle: 'Chart context menu'
50
50
  });
51
51
 
52
+ // docs: update the new defaults and explain the compatibility pack
53
+
52
54
  // Buttons and menus are collected in a separate config option set called 'navigation'.
53
55
  // This can be extended later to add control buttons like zoom and pan right click menus.
54
56
  defaultOptions.navigation = {
55
57
  menuStyle: {
56
58
  border: '1px solid #A0A0A0',
57
- background: '#FFFFFF'
59
+ background: '#FFFFFF',
60
+ padding: '5px 0'
58
61
  },
59
62
  menuItemStyle: {
60
- padding: '0 5px',
63
+ padding: '0 10px',
61
64
  background: NONE,
62
65
  color: '#303030',
63
66
  fontSize: isTouchDevice ? '14px' : '11px'
@@ -67,32 +70,22 @@ defaultOptions.navigation = {
67
70
  color: '#FFFFFF'
68
71
  },
69
72
 
70
- buttonOptions: {
71
- align: 'right',
72
- backgroundColor: {
73
- linearGradient: [0, 0, 0, 20],
74
- stops: [
75
- [0.4, '#F7F7F7'],
76
- [0.6, '#E3E3E3']
77
- ]
78
- },
79
- borderColor: '#B0B0B0',
80
- borderRadius: 3,
81
- borderWidth: 1,
82
- //enabled: true,
83
- height: 20,
84
- hoverBorderColor: '#909090',
85
- hoverSymbolFill: '#81A7CF',
86
- hoverSymbolStroke: '#4572A5',
73
+ buttonOptions: { // docs
87
74
  symbolFill: '#E0E0E0',
88
- //symbolSize: 12,
89
- symbolStroke: '#A0A0A0',
90
- //symbolStrokeWidth: 1,
91
- symbolX: 11.5,
75
+ symbolSize: 14,
76
+ symbolStroke: '#666',
77
+ symbolStrokeWidth: 3,
78
+ symbolX: 12.5,
92
79
  symbolY: 10.5,
80
+ align: 'right',
81
+ buttonSpacing: 3,
82
+ height: 22,
83
+ theme: {
84
+ fill: 'white', // capture hover
85
+ stroke: 'none'
86
+ },
93
87
  verticalAlign: 'top',
94
- width: 24,
95
- y: 10
88
+ width: 24
96
89
  }
97
90
  };
98
91
 
@@ -104,17 +97,21 @@ defaultOptions.exporting = {
104
97
  //filename: 'chart',
105
98
  type: 'image/png',
106
99
  url: 'http://export.highcharts.com/',
107
- width: 800,
100
+ //width: undefined, // docs
101
+ //scale: 2 // docs
108
102
  buttons: {
109
- exportButton: {
110
- //enabled: true,
111
- symbol: 'exportIcon',
112
- x: -10,
113
- symbolFill: '#A8BF77',
114
- hoverSymbolFill: '#768F3E',
115
- _id: 'exportButton',
116
- _titleKey: 'exportButtonTitle',
103
+ contextButton: { // docs
104
+ //x: -10, // docs: x is different now
105
+ symbol: 'menu',
106
+ _titleKey: 'contextButtonTitle',
117
107
  menuItems: [{
108
+ text: 'Print chart',
109
+ onclick: function () {
110
+ this.print();
111
+ }
112
+ }, {
113
+ separator: true
114
+ }, {
118
115
  textKey: 'downloadPNG',
119
116
  onclick: function () {
120
117
  this.exportChart();
@@ -155,19 +152,6 @@ defaultOptions.exporting = {
155
152
  }
156
153
  } // */
157
154
  ]
158
-
159
- },
160
- printButton: {
161
- //enabled: true,
162
- symbol: 'printIcon',
163
- x: -36,
164
- symbolFill: '#B5C9DF',
165
- hoverSymbolFill: '#779ABF',
166
- _id: 'printButton',
167
- _titleKey: 'printButtonTitle',
168
- onclick: function () {
169
- this.print();
170
- }
171
155
  }
172
156
  }
173
157
  };
@@ -203,6 +187,7 @@ Highcharts.post = function (url, data) {
203
187
  };
204
188
 
205
189
  extend(Chart.prototype, {
190
+
206
191
  /**
207
192
  * Return an SVG representation of the chart
208
193
  *
@@ -214,6 +199,10 @@ extend(Chart.prototype, {
214
199
  sandbox,
215
200
  svg,
216
201
  seriesOptions,
202
+ sourceWidth,
203
+ sourceHeight,
204
+ cssWidth,
205
+ cssHeight,
217
206
  options = merge(chart.options, additionalOptions); // copy the options and add extra options
218
207
 
219
208
  // IE compatibility hack for generating SVG content that it doesn't really understand
@@ -232,11 +221,27 @@ extend(Chart.prototype, {
232
221
  width: chart.chartWidth + PX,
233
222
  height: chart.chartHeight + PX
234
223
  }, doc.body);
224
+
225
+ // get the source size
226
+ cssWidth = chart.renderTo.style.width;
227
+ cssHeight = chart.renderTo.style.height;
228
+ sourceWidth = options.exporting.sourceWidth ||
229
+ options.chart.width ||
230
+ (/px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||
231
+ 600;
232
+ sourceHeight = options.exporting.sourceHeight ||
233
+ options.chart.height ||
234
+ (/px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||
235
+ 400;
236
+
235
237
 
236
238
  // override some options
237
239
  extend(options.chart, {
240
+ animation: false,
238
241
  renderTo: sandbox,
239
- forExport: true
242
+ forExport: true,
243
+ width: sourceWidth, // docs,
244
+ height: sourceHeight // docs
240
245
  });
241
246
  options.exporting.enabled = false; // hide buttons in print
242
247
  options.chart.plotBackgroundImage = null; // the converter doesn't handle images
@@ -256,7 +261,7 @@ extend(Chart.prototype, {
256
261
  });
257
262
 
258
263
  // generate the chart copy
259
- chartCopy = new Highcharts.Chart(options);
264
+ chartCopy = new Highcharts.Chart(options, chart.callback);
260
265
 
261
266
  // reflect axis extremes in the export
262
267
  each(['xAxis', 'yAxis'], function (axisType) {
@@ -286,7 +291,6 @@ extend(Chart.prototype, {
286
291
  .replace(/isShadow="[^"]+"/g, '')
287
292
  .replace(/symbolName="[^"]+"/g, '')
288
293
  .replace(/jQuery[0-9]+="[^"]+"/g, '')
289
- .replace(/isTracker="[^"]+"/g, '')
290
294
  .replace(/url\([^#]+#/g, 'url(#')
291
295
  .replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
292
296
  .replace(/ href=/g, ' xlink:href=')
@@ -330,17 +334,30 @@ extend(Chart.prototype, {
330
334
  * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
331
335
  */
332
336
  exportChart: function (options, chartOptions) {
333
- var exportingOptions = this.options.exporting,
334
- svg = this.getSVG(merge(exportingOptions.chartOptions, chartOptions));
337
+
338
+ options = options || {};
339
+
340
+ var chart = this,
341
+ svg = chart.getSVG(merge(
342
+ { chart: { borderRadius: 0 } }, // docs: defaults to 0 for exported charts
343
+ chart.options.exporting.chartOptions, // docs
344
+ chartOptions,
345
+ {
346
+ exporting: {
347
+ sourceWidth: options.sourceWidth, // docs
348
+ sourceHeight: options.sourceHeight // docs
349
+ }
350
+ }
351
+ ));
335
352
 
336
353
  // merge the options
337
- options = merge(exportingOptions, options);
354
+ options = merge(chart.options.exporting, options);
338
355
 
339
356
  // do the post
340
357
  Highcharts.post(options.url, {
341
358
  filename: options.filename || 'chart',
342
359
  type: options.type,
343
- width: options.width,
360
+ width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
344
361
  scale: options.scale || 2,
345
362
  svg: svg
346
363
  });
@@ -377,6 +394,7 @@ extend(Chart.prototype, {
377
394
  body.appendChild(container);
378
395
 
379
396
  // print
397
+ win.focus(); // #1510
380
398
  win.print();
381
399
 
382
400
  // allow the browser to prepare before reverting
@@ -408,7 +426,7 @@ extend(Chart.prototype, {
408
426
  * @param {Number} width The width of the opener button
409
427
  * @param {Number} height The height of the opener button
410
428
  */
411
- contextMenu: function (name, items, x, y, width, height) {
429
+ contextMenu: function (name, items, x, y, width, height, button) {
412
430
  var chart = this,
413
431
  navOptions = chart.options.navigation,
414
432
  menuItemStyle = navOptions.menuItemStyle,
@@ -445,6 +463,9 @@ extend(Chart.prototype, {
445
463
  // hide on mouse out
446
464
  hide = function () {
447
465
  css(menu, { display: NONE });
466
+ if (button) {
467
+ button.setState(0);
468
+ }
448
469
  };
449
470
 
450
471
  // Hide the menu some time after mouse leave (#1357)
@@ -459,25 +480,27 @@ extend(Chart.prototype, {
459
480
  // create the items
460
481
  each(items, function (item) {
461
482
  if (item) {
462
- var div = createElement(DIV, {
463
- onmouseover: function () {
464
- css(this, navOptions.menuItemHoverStyle);
465
- },
466
- onmouseout: function () {
467
- css(this, menuItemStyle);
468
- },
469
- innerHTML: item.text || chart.options.lang[item.textKey]
470
- }, extend({
471
- cursor: 'pointer'
472
- }, menuItemStyle), innerMenu);
473
-
474
- div.onclick = function () {
475
- hide();
476
- item.onclick.apply(chart, arguments);
477
- };
483
+ var element = item.separator ?
484
+ createElement('hr', null, null, innerMenu) :
485
+ createElement(DIV, {
486
+ onmouseover: function () {
487
+ css(this, navOptions.menuItemHoverStyle);
488
+ },
489
+ onmouseout: function () {
490
+ css(this, menuItemStyle);
491
+ },
492
+ onclick: function () {
493
+ hide();
494
+ item.onclick.apply(chart, arguments);
495
+ },
496
+ innerHTML: item.text || chart.options.lang[item.textKey]
497
+ }, extend({
498
+ cursor: 'pointer'
499
+ }, menuItemStyle), innerMenu);
500
+
478
501
 
479
502
  // Keep references to menu divs to be able to destroy them
480
- chart.exportDivElements.push(div);
503
+ chart.exportDivElements.push(element);
481
504
  }
482
505
  });
483
506
 
@@ -515,22 +538,14 @@ extend(Chart.prototype, {
515
538
  btnOptions = merge(chart.options.navigation.buttonOptions, options),
516
539
  onclick = btnOptions.onclick,
517
540
  menuItems = btnOptions.menuItems,
518
- buttonWidth = btnOptions.width,
519
- buttonHeight = btnOptions.height,
520
- box,
521
541
  symbol,
522
542
  button,
523
- menuKey,
524
- borderWidth = btnOptions.borderWidth,
525
- boxAttr = {
526
- stroke: btnOptions.borderColor
527
-
528
- },
529
543
  symbolAttr = {
530
544
  stroke: btnOptions.symbolStroke,
531
545
  fill: btnOptions.symbolFill
532
546
  },
533
- symbolSize = btnOptions.symbolSize || 12;
547
+ symbolSize = btnOptions.symbolSize || 12,
548
+ menuKey;
534
549
 
535
550
  if (!chart.btnCount) {
536
551
  chart.btnCount = 0;
@@ -547,99 +562,85 @@ extend(Chart.prototype, {
547
562
  return;
548
563
  }
549
564
 
550
- // element to capture the click
551
- function revert() {
552
- symbol.attr(symbolAttr);
553
- box.attr(boxAttr);
565
+
566
+ var attr = btnOptions.theme,
567
+ states = attr.states,
568
+ hover = states && states.hover,
569
+ select = states && states.select,
570
+ callback;
571
+
572
+ delete attr.states;
573
+
574
+ if (onclick) {
575
+ callback = function () {
576
+ onclick.apply(chart, arguments);
577
+ };
578
+
579
+ } else if (menuItems) {
580
+ callback = function () {
581
+ chart.contextMenu(
582
+ 'contextmenu',
583
+ menuItems,
584
+ button.translateX,
585
+ button.translateY,
586
+ button.width,
587
+ button.height,
588
+ button
589
+ );
590
+ button.setState(2);
591
+ };
592
+ }
593
+
594
+
595
+ if (btnOptions.text && btnOptions.symbol) {
596
+ attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
597
+
598
+ } else if (!btnOptions.text) {
599
+ extend(attr, {
600
+ width: btnOptions.width,
601
+ height: btnOptions.height,
602
+ padding: 0
603
+ });
554
604
  }
555
605
 
556
- // the box border
557
- box = renderer.rect(
558
- 0,
559
- 0,
560
- buttonWidth,
561
- buttonHeight,
562
- btnOptions.borderRadius,
563
- borderWidth
564
- )
565
- //.translate(buttonLeft, buttonTop) // to allow gradients
566
- .align(btnOptions, true)
567
- .attr(extend({
568
- fill: btnOptions.backgroundColor,
569
- 'stroke-width': borderWidth,
570
- zIndex: 19
571
- }, boxAttr)).add();
572
-
573
- // the invisible element to track the clicks
574
- button = renderer.rect(
575
- 0,
576
- 0,
577
- buttonWidth,
578
- buttonHeight,
579
- 0
580
- )
581
- .align(btnOptions)
606
+ button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
582
607
  .attr({
583
- id: btnOptions._id,
584
- fill: 'rgba(255, 255, 255, 0.001)',
585
608
  title: chart.options.lang[btnOptions._titleKey],
586
- zIndex: 21
587
- }).css({
588
- cursor: 'pointer'
589
- })
590
- .on('mouseover', function () {
591
- symbol.attr({
592
- stroke: btnOptions.hoverSymbolStroke,
593
- fill: btnOptions.hoverSymbolFill
594
- });
595
- box.attr({
596
- stroke: btnOptions.hoverBorderColor
597
- });
598
- })
599
- .on('mouseout', revert)
600
- .on('click', revert)
601
- .add();
602
-
603
- // add the click event
604
- if (menuItems) {
605
-
606
- onclick = function () {
607
- revert();
608
- var bBox = button.getBBox();
609
- chart.contextMenu('menu' + menuKey, menuItems, bBox.x, bBox.y, buttonWidth, buttonHeight);
610
- };
609
+ 'stroke-linecap': 'round'
610
+ });
611
+
612
+ if (btnOptions.symbol) {
613
+ symbol = renderer.symbol(
614
+ btnOptions.symbol,
615
+ btnOptions.symbolX - (symbolSize / 2),
616
+ btnOptions.symbolY - (symbolSize / 2),
617
+ symbolSize,
618
+ symbolSize
619
+ )
620
+ .attr(extend(symbolAttr, {
621
+ 'stroke-width': btnOptions.symbolStrokeWidth || 1,
622
+ zIndex: 1
623
+ })).add(button);
611
624
  }
612
- /*addEvent(button.element, 'click', function() {
613
- onclick.apply(chart, arguments);
614
- });*/
615
- button.on('click', function () {
616
- onclick.apply(chart, arguments);
617
- });
618
625
 
619
- // the icon
620
- symbol = renderer.symbol(
621
- btnOptions.symbol,
622
- btnOptions.symbolX - (symbolSize / 2),
623
- btnOptions.symbolY - (symbolSize / 2),
624
- symbolSize,
625
- symbolSize
626
- )
627
- .align(btnOptions, true)
628
- .attr(extend(symbolAttr, {
629
- 'stroke-width': btnOptions.symbolStrokeWidth || 1,
630
- zIndex: 20
631
- })).add();
632
-
633
- // Keep references to the renderer element so to be able to destroy them later.
634
- chart.exportSVGElements.push(box, button, symbol);
626
+ button.add()
627
+ .align(extend(btnOptions, {
628
+ width: button.width,
629
+ x: buttonOffset
630
+ }), true, 'spacingBox');
631
+
632
+ buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);
633
+
634
+ chart.exportSVGElements.push(button, symbol);
635
+
635
636
  },
636
637
 
637
638
  /**
638
639
  * Destroy the buttons.
639
640
  */
640
- destroyExport: function () {
641
- var i,
642
- chart = this,
641
+ destroyExport: function (e) {
642
+ var chart = e.target,
643
+ i,
643
644
  elem;
644
645
 
645
646
  // Destroy the extra buttons added
@@ -666,69 +667,18 @@ extend(Chart.prototype, {
666
667
  }
667
668
  });
668
669
 
669
- /**
670
- * Crisp for 1px stroke width, which is default. In the future, consider a smarter,
671
- * global function.
672
- */
673
- function crisp(arr) {
674
- var i = arr.length;
675
- while (i--) {
676
- if (typeof arr[i] === 'number') {
677
- arr[i] = Math.round(arr[i]) - 0.5;
678
- }
679
- }
670
+
671
+ symbols.menu = function (x, y, width, height) {
672
+ var arr = [
673
+ M, x, y + 2.5,
674
+ L, x + width, y + 2.5,
675
+ M, x, y + height / 2 + 0.5,
676
+ L, x + width, y + height / 2 + 0.5,
677
+ M, x, y + height - 1.5,
678
+ L, x + width, y + height - 1.5
679
+ ];
680
680
  return arr;
681
- }
682
-
683
- // Create the export icon
684
- symbols.exportIcon = function (x, y, width, height) {
685
- return crisp([
686
- M, // the disk
687
- x, y + width,
688
- L,
689
- x + width, y + height,
690
- x + width, y + height * 0.8,
691
- x, y + height * 0.8,
692
- 'Z',
693
- M, // the arrow
694
- x + width * 0.5, y + height * 0.8,
695
- L,
696
- x + width * 0.8, y + height * 0.4,
697
- x + width * 0.4, y + height * 0.4,
698
- x + width * 0.4, y,
699
- x + width * 0.6, y,
700
- x + width * 0.6, y + height * 0.4,
701
- x + width * 0.2, y + height * 0.4,
702
- 'Z'
703
- ]);
704
681
  };
705
- // Create the print icon
706
- symbols.printIcon = function (x, y, width, height) {
707
- return crisp([
708
- M, // the printer
709
- x, y + height * 0.7,
710
- L,
711
- x + width, y + height * 0.7,
712
- x + width, y + height * 0.4,
713
- x, y + height * 0.4,
714
- 'Z',
715
- M, // the upper sheet
716
- x + width * 0.2, y + height * 0.4,
717
- L,
718
- x + width * 0.2, y,
719
- x + width * 0.8, y,
720
- x + width * 0.8, y + height * 0.4,
721
- 'Z',
722
- M, // the lower sheet
723
- x + width * 0.2, y + height * 0.7,
724
- L,
725
- x, y + height,
726
- x + width, y + height,
727
- x + width * 0.8, y + height * 0.7,
728
- 'Z'
729
- ]);
730
- };
731
-
732
682
 
733
683
  // Add the buttons on chart load
734
684
  Chart.prototype.callbacks.push(function (chart) {
@@ -736,6 +686,8 @@ Chart.prototype.callbacks.push(function (chart) {
736
686
  exportingOptions = chart.options.exporting,
737
687
  buttons = exportingOptions.buttons;
738
688
 
689
+ buttonOffset = 0;
690
+
739
691
  if (exportingOptions.enabled !== false) {
740
692
 
741
693
  for (n in buttons) {