highcharts-js-rails 0.2.1 → 1.0.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 +7 -0
- data/.gitignore +2 -1
- data/.rspec +0 -1
- data/.travis.yml +6 -0
- data/CHANGELOG.md +7 -0
- data/{lib/LICENSE → LICENSE} +1 -1
- data/README.md +16 -13
- data/highcharts-js-rails.gemspec +3 -5
- data/lib/highcharts-js-rails.rb +1 -1
- data/lib/highcharts.rb +4 -3
- data/lib/highcharts/axis/plot_bands.rb +1 -1
- data/lib/highcharts/axis/plot_lines.rb +1 -1
- data/lib/highcharts/axis/x.rb +6 -8
- data/lib/highcharts/axis/y.rb +6 -6
- data/lib/highcharts/base.rb +8 -8
- data/lib/highcharts/{color.rb → colors.rb} +0 -0
- data/lib/highcharts/engine.rb +2 -0
- data/lib/highcharts/legend.rb +2 -2
- data/lib/highcharts/plot_options.rb +13 -13
- data/lib/highcharts/plot_options/plot_type.rb +7 -7
- data/lib/highcharts/plot_options/plot_type/marker.rb +1 -1
- data/lib/highcharts/plot_options/plot_type/marker/states.rb +2 -2
- data/lib/highcharts/plot_options/plot_type/states.rb +1 -1
- data/lib/highcharts/plot_options/plot_type/states/hover.rb +1 -1
- data/lib/highcharts/point.rb +2 -2
- data/spec/highcharts/axis/x_spec.rb +51 -0
- data/spec/highcharts/base_spec.rb +55 -1
- data/spec/highcharts/series_spec.rb +25 -0
- data/spec/highcharts_spec.rb +65 -0
- data/spec/spec_helper.rb +4 -4
- data/vendor/assets/javascripts/highcharts-more.js +2290 -1387
- data/vendor/assets/javascripts/highcharts.js +2712 -1720
- data/vendor/assets/javascripts/highcharts/adapters/mootools.js +15 -30
- data/vendor/assets/javascripts/highcharts/adapters/prototype.js +10 -79
- data/vendor/assets/javascripts/highcharts/modules/canvas-tools.js +1 -1
- data/vendor/assets/javascripts/highcharts/modules/data.js +57 -32
- data/vendor/assets/javascripts/highcharts/modules/exporting.js +180 -229
- data/vendor/assets/javascripts/highcharts/modules/funnel.js +284 -0
- data/vendor/assets/javascripts/highcharts/themes/dark-blue.js +11 -20
- data/vendor/assets/javascripts/highcharts/themes/dark-green.js +12 -20
- data/vendor/assets/javascripts/highcharts/themes/gray.js +15 -20
- data/vendor/assets/javascripts/highcharts/themes/grid.js +8 -0
- metadata +34 -38
@@ -1,8 +1,8 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v3.0.1 (2013-04-09)
|
3
3
|
* MooTools adapter
|
4
4
|
*
|
5
|
-
* (c) 2010-
|
5
|
+
* (c) 2010-2013 Torstein Hønsi
|
6
6
|
*
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
@@ -190,36 +190,11 @@ win.HighchartsAdapter = {
|
|
190
190
|
return arr.indexOf(item, from);
|
191
191
|
},
|
192
192
|
|
193
|
-
/**
|
194
|
-
* Deep merge two objects and return a third
|
195
|
-
*/
|
196
|
-
merge: function () {
|
197
|
-
var args = arguments,
|
198
|
-
args13 = [{}], // MooTools 1.3+
|
199
|
-
i = args.length,
|
200
|
-
ret;
|
201
|
-
|
202
|
-
if (legacy) {
|
203
|
-
ret = $merge.apply(null, args);
|
204
|
-
} else {
|
205
|
-
while (i--) {
|
206
|
-
// Boolean argumens should not be merged.
|
207
|
-
// JQuery explicitly skips this, so we do it here as well.
|
208
|
-
if (typeof args[i] !== 'boolean') {
|
209
|
-
args13[i + 1] = args[i];
|
210
|
-
}
|
211
|
-
}
|
212
|
-
ret = Object.merge.apply(Object, args13);
|
213
|
-
}
|
214
|
-
|
215
|
-
return ret;
|
216
|
-
},
|
217
|
-
|
218
193
|
/**
|
219
194
|
* Get the offset of an element relative to the top left corner of the web page
|
220
195
|
*/
|
221
196
|
offset: function (el) {
|
222
|
-
var offsets =
|
197
|
+
var offsets = el.getPosition(); // #1496
|
223
198
|
return {
|
224
199
|
left: offsets.x,
|
225
200
|
top: offsets.y
|
@@ -291,6 +266,12 @@ win.HighchartsAdapter = {
|
|
291
266
|
// create an event object that keeps all functions
|
292
267
|
event = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs);
|
293
268
|
event = $extend(event, eventArguments);
|
269
|
+
|
270
|
+
// When running an event on the Chart.prototype, MooTools nests the target in event.event
|
271
|
+
if (!event.target && event.event) {
|
272
|
+
event.target = event.event.target;
|
273
|
+
}
|
274
|
+
|
294
275
|
// override the preventDefault function to be able to use
|
295
276
|
// this for custom events
|
296
277
|
event.preventDefault = function () {
|
@@ -309,10 +290,14 @@ win.HighchartsAdapter = {
|
|
309
290
|
},
|
310
291
|
|
311
292
|
/**
|
312
|
-
* Set back e.pageX and e.pageY that MooTools has abstracted away
|
293
|
+
* Set back e.pageX and e.pageY that MooTools has abstracted away. #1165, #1346.
|
313
294
|
*/
|
314
295
|
washMouseEvent: function (e) {
|
315
|
-
|
296
|
+
if (e.page) {
|
297
|
+
e.pageX = e.page.x;
|
298
|
+
e.pageY = e.page.y;
|
299
|
+
}
|
300
|
+
return e;
|
316
301
|
},
|
317
302
|
|
318
303
|
/**
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v3.0.1 (2013-04-09)
|
3
3
|
* Prototype adapter
|
4
4
|
*
|
5
5
|
* @author Michael Nelson, Torstein Hønsi.
|
@@ -83,7 +83,10 @@ return {
|
|
83
83
|
}
|
84
84
|
|
85
85
|
if (element.attr) { // SVGElement
|
86
|
-
|
86
|
+
|
87
|
+
if (element.element) { // If not, it has been destroyed (#1405)
|
88
|
+
element.attr(this.options.attribute, position);
|
89
|
+
}
|
87
90
|
|
88
91
|
} else { // HTML, #409
|
89
92
|
obj = {};
|
@@ -95,7 +98,9 @@ return {
|
|
95
98
|
finish: function () {
|
96
99
|
// Delete the property that holds this animation now that it is finished.
|
97
100
|
// Both canceled animations and complete ones gets a 'finish' call.
|
98
|
-
|
101
|
+
if (this.element && this.element._highchart_animation) { // #1405
|
102
|
+
delete this.element._highchart_animation[this.key];
|
103
|
+
}
|
99
104
|
}
|
100
105
|
});
|
101
106
|
}
|
@@ -261,82 +266,6 @@ return {
|
|
261
266
|
return arr.map(fn);
|
262
267
|
},
|
263
268
|
|
264
|
-
// deep merge. merge({a : 'a', b : {b1 : 'b1', b2 : 'b2'}}, {b : {b2 : 'b2_prime'}, c : 'c'}) => {a : 'a', b : {b1 : 'b1', b2 : 'b2_prime'}, c : 'c'}
|
265
|
-
/*merge: function(){
|
266
|
-
function doCopy(copy, original) {
|
267
|
-
var value,
|
268
|
-
key,
|
269
|
-
undef,
|
270
|
-
nil,
|
271
|
-
same,
|
272
|
-
obj,
|
273
|
-
arr,
|
274
|
-
node;
|
275
|
-
|
276
|
-
for (key in original) {
|
277
|
-
value = original[key];
|
278
|
-
undef = typeof(value) === 'undefined';
|
279
|
-
nil = value === null;
|
280
|
-
same = original === copy[key];
|
281
|
-
|
282
|
-
if (undef || nil || same) {
|
283
|
-
continue;
|
284
|
-
}
|
285
|
-
|
286
|
-
obj = typeof(value) === 'object';
|
287
|
-
arr = value && obj && value.constructor == Array;
|
288
|
-
node = !!value.nodeType;
|
289
|
-
|
290
|
-
if (obj && !arr && !node) {
|
291
|
-
copy[key] = doCopy(typeof copy[key] == 'object' ? copy[key] : {}, value);
|
292
|
-
}
|
293
|
-
else {
|
294
|
-
copy[key] = original[key];
|
295
|
-
}
|
296
|
-
}
|
297
|
-
return copy;
|
298
|
-
}
|
299
|
-
|
300
|
-
var args = arguments, retVal = {};
|
301
|
-
|
302
|
-
for (var i = 0; i < args.length; i++) {
|
303
|
-
retVal = doCopy(retVal, args[i]);
|
304
|
-
}
|
305
|
-
|
306
|
-
return retVal;
|
307
|
-
},*/
|
308
|
-
merge: function () { // the built-in prototype merge function doesn't do deep copy
|
309
|
-
function doCopy(copy, original) {
|
310
|
-
var value, key;
|
311
|
-
|
312
|
-
for (key in original) {
|
313
|
-
value = original[key];
|
314
|
-
if (value && typeof value === 'object' && value.constructor !== Array &&
|
315
|
-
typeof value.nodeType !== 'number') {
|
316
|
-
copy[key] = doCopy(copy[key] || {}, value); // copy
|
317
|
-
|
318
|
-
} else {
|
319
|
-
copy[key] = original[key];
|
320
|
-
}
|
321
|
-
}
|
322
|
-
return copy;
|
323
|
-
}
|
324
|
-
|
325
|
-
function merge() {
|
326
|
-
var args = arguments,
|
327
|
-
i,
|
328
|
-
retVal = {};
|
329
|
-
|
330
|
-
for (i = 0; i < args.length; i++) {
|
331
|
-
retVal = doCopy(retVal, args[i]);
|
332
|
-
|
333
|
-
}
|
334
|
-
return retVal;
|
335
|
-
}
|
336
|
-
|
337
|
-
return merge.apply(this, arguments);
|
338
|
-
},
|
339
|
-
|
340
269
|
// extend an object to handle highchart events (highchart objects, not svg elements).
|
341
270
|
// this is a very simple way of handling events but whatever, it works (i think)
|
342
271
|
_extend: function (object) {
|
@@ -360,6 +289,7 @@ return {
|
|
360
289
|
}
|
361
290
|
},
|
362
291
|
_highcharts_fire: function (name, args) {
|
292
|
+
var target = this;
|
363
293
|
(this._highchart_events[name] || []).each(function (fn) {
|
364
294
|
// args is never null here
|
365
295
|
if (args.stopped) {
|
@@ -370,6 +300,7 @@ return {
|
|
370
300
|
args.preventDefault = function () {
|
371
301
|
args.defaultPrevented = true;
|
372
302
|
};
|
303
|
+
args.target = target;
|
373
304
|
|
374
305
|
// If the event handler return false, prevent the default handler from executing
|
375
306
|
if (fn.bind(this)(args) === false) {
|
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
|
|
2908
2908
|
});
|
2909
2909
|
}
|
2910
2910
|
}/**
|
2911
|
-
* @license Highcharts JS
|
2911
|
+
* @license Highcharts JS v3.0.1 (2013-04-09)
|
2912
2912
|
* CanVGRenderer Extension module
|
2913
2913
|
*
|
2914
2914
|
* (c) 2011-2012 Torstein Hønsi, Erik Olsson
|
@@ -1,7 +1,8 @@
|
|
1
1
|
/**
|
2
|
-
* @license Data plugin for Highcharts
|
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,14 +45,14 @@
|
|
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
|
-
* -
|
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
|
*
|
51
|
-
* -
|
52
|
+
* - itemDelimiter : String
|
52
53
|
* Item or cell delimiter for parsing CSV. Defaults to ",".
|
53
54
|
*
|
54
|
-
* -
|
55
|
+
* - lineDelimiter : String
|
55
56
|
* Line delimiter for parsing CSV. Defaults to "\n".
|
56
57
|
*
|
57
58
|
* - parsed : Function
|
@@ -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
|
|
@@ -137,14 +139,16 @@
|
|
137
139
|
* Parse a CSV input string
|
138
140
|
*/
|
139
141
|
parseCSV: function () {
|
140
|
-
var
|
142
|
+
var self = this,
|
143
|
+
options = this.options,
|
141
144
|
csv = options.csv,
|
142
145
|
columns = this.columns,
|
143
146
|
startRow = options.startRow || 0,
|
144
147
|
endRow = options.endRow || Number.MAX_VALUE,
|
145
148
|
startColumn = options.startColumn || 0,
|
146
149
|
endColumn = options.endColumn || Number.MAX_VALUE,
|
147
|
-
lines
|
150
|
+
lines,
|
151
|
+
activeRowNo = 0;
|
148
152
|
|
149
153
|
if (csv) {
|
150
154
|
|
@@ -154,19 +158,26 @@
|
|
154
158
|
.split(options.lineDelimiter || "\n");
|
155
159
|
|
156
160
|
each(lines, function (line, rowNo) {
|
157
|
-
|
158
|
-
|
161
|
+
var trimmed = self.trim(line),
|
162
|
+
isComment = trimmed.indexOf('#') === 0,
|
163
|
+
isBlank = trimmed === '',
|
164
|
+
items;
|
165
|
+
|
166
|
+
if (rowNo >= startRow && rowNo <= endRow && !isComment && !isBlank) {
|
167
|
+
items = line.split(options.itemDelimiter || ',');
|
159
168
|
each(items, function (item, colNo) {
|
160
169
|
if (colNo >= startColumn && colNo <= endColumn) {
|
161
170
|
if (!columns[colNo - startColumn]) {
|
162
171
|
columns[colNo - startColumn] = [];
|
163
172
|
}
|
164
173
|
|
165
|
-
columns[colNo - startColumn][
|
174
|
+
columns[colNo - startColumn][activeRowNo] = item;
|
166
175
|
}
|
167
176
|
});
|
177
|
+
activeRowNo += 1;
|
168
178
|
}
|
169
|
-
});
|
179
|
+
});
|
180
|
+
|
170
181
|
this.dataFound();
|
171
182
|
}
|
172
183
|
},
|
@@ -213,13 +224,18 @@
|
|
213
224
|
/**
|
214
225
|
* TODO:
|
215
226
|
* - switchRowsAndColumns
|
216
|
-
* - startRow, endRow etc.
|
217
227
|
*/
|
218
228
|
parseGoogleSpreadsheet: function () {
|
219
229
|
var self = this,
|
220
230
|
options = this.options,
|
221
231
|
googleSpreadsheetKey = options.googleSpreadsheetKey,
|
222
|
-
columns = this.columns
|
232
|
+
columns = this.columns,
|
233
|
+
startRow = options.startRow || 0,
|
234
|
+
endRow = options.endRow || Number.MAX_VALUE,
|
235
|
+
startColumn = options.startColumn || 0,
|
236
|
+
endColumn = options.endColumn || Number.MAX_VALUE,
|
237
|
+
gr, // google row
|
238
|
+
gc; // google column
|
223
239
|
|
224
240
|
if (googleSpreadsheetKey) {
|
225
241
|
jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' +
|
@@ -245,15 +261,28 @@
|
|
245
261
|
|
246
262
|
// Set up arrays containing the column data
|
247
263
|
for (i = 0; i < colCount; i++) {
|
248
|
-
|
264
|
+
if (i >= startColumn && i <= endColumn) {
|
265
|
+
// Create new columns with the length of either end-start or rowCount
|
266
|
+
columns[i - startColumn] = [];
|
267
|
+
|
268
|
+
// Setting the length to avoid jslint warning
|
269
|
+
columns[i - startColumn].length = Math.min(rowCount, endRow - startRow);
|
270
|
+
}
|
249
271
|
}
|
250
272
|
|
251
273
|
// Loop over the cells and assign the value to the right
|
252
274
|
// place in the column arrays
|
253
275
|
for (i = 0; i < cellCount; i++) {
|
254
276
|
cell = cells[i];
|
255
|
-
|
256
|
-
|
277
|
+
gr = cell.gs$cell.row - 1; // rows start at 1
|
278
|
+
gc = cell.gs$cell.col - 1; // columns start at 1
|
279
|
+
|
280
|
+
// If both row and col falls inside start and end
|
281
|
+
// set the transposed cell value in the newly created columns
|
282
|
+
if (gc >= startColumn && gc <= endColumn &&
|
283
|
+
gr >= startRow && gr <= endRow) {
|
284
|
+
columns[gc - startColumn][gr - startRow] = cell.content.$t;
|
285
|
+
}
|
257
286
|
}
|
258
287
|
self.dataFound();
|
259
288
|
});
|
@@ -279,7 +308,6 @@
|
|
279
308
|
* Trim a string from whitespace
|
280
309
|
*/
|
281
310
|
trim: function (str) {
|
282
|
-
//return typeof str === 'number' ? str : str.replace(/^\s+|\s+$/g, ''); // fails with spreadsheet
|
283
311
|
return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str;
|
284
312
|
},
|
285
313
|
|
@@ -302,6 +330,7 @@
|
|
302
330
|
val = columns[col][row];
|
303
331
|
floatVal = parseFloat(val);
|
304
332
|
trimVal = this.trim(val);
|
333
|
+
|
305
334
|
/*jslint eqeq: true*/
|
306
335
|
if (trimVal == floatVal) { // is numeric
|
307
336
|
/*jslint eqeq: false*/
|
@@ -322,7 +351,7 @@
|
|
322
351
|
columns[col].isDatetime = true;
|
323
352
|
|
324
353
|
} else { // string
|
325
|
-
columns[col][row] = trimVal;
|
354
|
+
columns[col][row] = trimVal === '' ? null : trimVal;
|
326
355
|
}
|
327
356
|
}
|
328
357
|
|
@@ -350,7 +379,7 @@
|
|
350
379
|
match;
|
351
380
|
|
352
381
|
if (parseDate) {
|
353
|
-
ret = parseDate;
|
382
|
+
ret = parseDate(val);
|
354
383
|
}
|
355
384
|
|
356
385
|
if (typeof val === 'string') {
|
@@ -486,21 +515,17 @@
|
|
486
515
|
if (userOptions && userOptions.data) {
|
487
516
|
Highcharts.data(Highcharts.extend(userOptions.data, {
|
488
517
|
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
518
|
|
519
|
+
// Merge series configs
|
520
|
+
if (userOptions.series) {
|
521
|
+
each(userOptions.series, function (series, i) {
|
522
|
+
userOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]);
|
523
|
+
});
|
524
|
+
}
|
525
|
+
|
497
526
|
// Do the merge
|
498
527
|
userOptions = Highcharts.merge(dataOptions, userOptions);
|
499
|
-
|
500
|
-
// Re-insert the data
|
501
|
-
each(datasets, function (data, i) {
|
502
|
-
userOptions.series[i].data = data;
|
503
|
-
});
|
528
|
+
|
504
529
|
proceed.call(chart, userOptions, callback);
|
505
530
|
}
|
506
531
|
}));
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v3.0.1 (2013-04-09)
|
3
3
|
* Exporting module
|
4
4
|
*
|
5
|
-
* (c) 2010-
|
5
|
+
* (c) 2010-2013 Torstein Hønsi
|
6
6
|
*
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
@@ -37,16 +37,17 @@ 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
|
+
printChart: 'Print chart',
|
44
46
|
downloadPNG: 'Download PNG image',
|
45
47
|
downloadJPEG: 'Download JPEG image',
|
46
48
|
downloadPDF: 'Download PDF document',
|
47
49
|
downloadSVG: 'Download SVG vector image',
|
48
|
-
|
49
|
-
printButtonTitle: 'Print the chart'
|
50
|
+
contextButtonTitle: 'Chart context menu'
|
50
51
|
});
|
51
52
|
|
52
53
|
// Buttons and menus are collected in a separate config option set called 'navigation'.
|
@@ -54,10 +55,11 @@ var Chart = Highcharts.Chart,
|
|
54
55
|
defaultOptions.navigation = {
|
55
56
|
menuStyle: {
|
56
57
|
border: '1px solid #A0A0A0',
|
57
|
-
background: '#FFFFFF'
|
58
|
+
background: '#FFFFFF',
|
59
|
+
padding: '5px 0'
|
58
60
|
},
|
59
61
|
menuItemStyle: {
|
60
|
-
padding: '0
|
62
|
+
padding: '0 10px',
|
61
63
|
background: NONE,
|
62
64
|
color: '#303030',
|
63
65
|
fontSize: isTouchDevice ? '14px' : '11px'
|
@@ -68,31 +70,22 @@ defaultOptions.navigation = {
|
|
68
70
|
},
|
69
71
|
|
70
72
|
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',
|
87
73
|
symbolFill: '#E0E0E0',
|
88
|
-
|
89
|
-
symbolStroke: '#
|
90
|
-
|
91
|
-
symbolX:
|
74
|
+
symbolSize: 14,
|
75
|
+
symbolStroke: '#666',
|
76
|
+
symbolStrokeWidth: 3,
|
77
|
+
symbolX: 12.5,
|
92
78
|
symbolY: 10.5,
|
79
|
+
align: 'right',
|
80
|
+
buttonSpacing: 3,
|
81
|
+
height: 22,
|
82
|
+
// text: null,
|
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:
|
100
|
+
//width: undefined,
|
101
|
+
//scale: 2
|
108
102
|
buttons: {
|
109
|
-
|
110
|
-
//
|
111
|
-
symbol: '
|
112
|
-
|
113
|
-
symbolFill: '#A8BF77',
|
114
|
-
hoverSymbolFill: '#768F3E',
|
115
|
-
_id: 'exportButton',
|
116
|
-
_titleKey: 'exportButtonTitle',
|
103
|
+
contextButton: {
|
104
|
+
//x: -10,
|
105
|
+
symbol: 'menu',
|
106
|
+
_titleKey: 'contextButtonTitle',
|
117
107
|
menuItems: [{
|
108
|
+
textKey: 'printChart',
|
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,26 @@ 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;
|
235
236
|
|
236
237
|
// override some options
|
237
238
|
extend(options.chart, {
|
239
|
+
animation: false,
|
238
240
|
renderTo: sandbox,
|
239
|
-
forExport: true
|
241
|
+
forExport: true,
|
242
|
+
width: sourceWidth,
|
243
|
+
height: sourceHeight
|
240
244
|
});
|
241
245
|
options.exporting.enabled = false; // hide buttons in print
|
242
246
|
options.chart.plotBackgroundImage = null; // the converter doesn't handle images
|
@@ -256,7 +260,7 @@ extend(Chart.prototype, {
|
|
256
260
|
});
|
257
261
|
|
258
262
|
// generate the chart copy
|
259
|
-
chartCopy = new Highcharts.Chart(options);
|
263
|
+
chartCopy = new Highcharts.Chart(options, chart.callback);
|
260
264
|
|
261
265
|
// reflect axis extremes in the export
|
262
266
|
each(['xAxis', 'yAxis'], function (axisType) {
|
@@ -286,7 +290,6 @@ extend(Chart.prototype, {
|
|
286
290
|
.replace(/isShadow="[^"]+"/g, '')
|
287
291
|
.replace(/symbolName="[^"]+"/g, '')
|
288
292
|
.replace(/jQuery[0-9]+="[^"]+"/g, '')
|
289
|
-
.replace(/isTracker="[^"]+"/g, '')
|
290
293
|
.replace(/url\([^#]+#/g, 'url(#')
|
291
294
|
.replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
|
292
295
|
.replace(/ href=/g, ' xlink:href=')
|
@@ -330,17 +333,30 @@ extend(Chart.prototype, {
|
|
330
333
|
* @param {Object} chartOptions Additional chart options for the SVG representation of the chart
|
331
334
|
*/
|
332
335
|
exportChart: function (options, chartOptions) {
|
333
|
-
|
334
|
-
|
336
|
+
options = options || {};
|
337
|
+
|
338
|
+
var chart = this,
|
339
|
+
chartExportingOptions = chart.options.exporting,
|
340
|
+
svg = chart.getSVG(merge(
|
341
|
+
{ chart: { borderRadius: 0 } },
|
342
|
+
chartExportingOptions,
|
343
|
+
chartOptions,
|
344
|
+
{
|
345
|
+
exporting: {
|
346
|
+
sourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth, // docs: option and parameter in exportChart()
|
347
|
+
sourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight // docs
|
348
|
+
}
|
349
|
+
}
|
350
|
+
));
|
335
351
|
|
336
352
|
// merge the options
|
337
|
-
options = merge(
|
353
|
+
options = merge(chart.options.exporting, options);
|
338
354
|
|
339
355
|
// do the post
|
340
356
|
Highcharts.post(options.url, {
|
341
357
|
filename: options.filename || 'chart',
|
342
358
|
type: options.type,
|
343
|
-
width: options.width,
|
359
|
+
width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
|
344
360
|
scale: options.scale || 2,
|
345
361
|
svg: svg
|
346
362
|
});
|
@@ -377,6 +393,7 @@ extend(Chart.prototype, {
|
|
377
393
|
body.appendChild(container);
|
378
394
|
|
379
395
|
// print
|
396
|
+
win.focus(); // #1510
|
380
397
|
win.print();
|
381
398
|
|
382
399
|
// allow the browser to prepare before reverting
|
@@ -408,7 +425,7 @@ extend(Chart.prototype, {
|
|
408
425
|
* @param {Number} width The width of the opener button
|
409
426
|
* @param {Number} height The height of the opener button
|
410
427
|
*/
|
411
|
-
contextMenu: function (name, items, x, y, width, height) {
|
428
|
+
contextMenu: function (name, items, x, y, width, height, button) {
|
412
429
|
var chart = this,
|
413
430
|
navOptions = chart.options.navigation,
|
414
431
|
menuItemStyle = navOptions.menuItemStyle,
|
@@ -445,6 +462,9 @@ extend(Chart.prototype, {
|
|
445
462
|
// hide on mouse out
|
446
463
|
hide = function () {
|
447
464
|
css(menu, { display: NONE });
|
465
|
+
if (button) {
|
466
|
+
button.setState(0);
|
467
|
+
}
|
448
468
|
};
|
449
469
|
|
450
470
|
// Hide the menu some time after mouse leave (#1357)
|
@@ -459,25 +479,27 @@ extend(Chart.prototype, {
|
|
459
479
|
// create the items
|
460
480
|
each(items, function (item) {
|
461
481
|
if (item) {
|
462
|
-
var
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
482
|
+
var element = item.separator ?
|
483
|
+
createElement('hr', null, null, innerMenu) :
|
484
|
+
createElement(DIV, {
|
485
|
+
onmouseover: function () {
|
486
|
+
css(this, navOptions.menuItemHoverStyle);
|
487
|
+
},
|
488
|
+
onmouseout: function () {
|
489
|
+
css(this, menuItemStyle);
|
490
|
+
},
|
491
|
+
onclick: function () {
|
492
|
+
hide();
|
493
|
+
item.onclick.apply(chart, arguments);
|
494
|
+
},
|
495
|
+
innerHTML: item.text || chart.options.lang[item.textKey]
|
496
|
+
}, extend({
|
497
|
+
cursor: 'pointer'
|
498
|
+
}, menuItemStyle), innerMenu);
|
499
|
+
|
478
500
|
|
479
501
|
// Keep references to menu divs to be able to destroy them
|
480
|
-
chart.exportDivElements.push(
|
502
|
+
chart.exportDivElements.push(element);
|
481
503
|
}
|
482
504
|
});
|
483
505
|
|
@@ -515,22 +537,14 @@ extend(Chart.prototype, {
|
|
515
537
|
btnOptions = merge(chart.options.navigation.buttonOptions, options),
|
516
538
|
onclick = btnOptions.onclick,
|
517
539
|
menuItems = btnOptions.menuItems,
|
518
|
-
buttonWidth = btnOptions.width,
|
519
|
-
buttonHeight = btnOptions.height,
|
520
|
-
box,
|
521
540
|
symbol,
|
522
541
|
button,
|
523
|
-
menuKey,
|
524
|
-
borderWidth = btnOptions.borderWidth,
|
525
|
-
boxAttr = {
|
526
|
-
stroke: btnOptions.borderColor
|
527
|
-
|
528
|
-
},
|
529
542
|
symbolAttr = {
|
530
543
|
stroke: btnOptions.symbolStroke,
|
531
544
|
fill: btnOptions.symbolFill
|
532
545
|
},
|
533
|
-
symbolSize = btnOptions.symbolSize || 12
|
546
|
+
symbolSize = btnOptions.symbolSize || 12,
|
547
|
+
menuKey;
|
534
548
|
|
535
549
|
if (!chart.btnCount) {
|
536
550
|
chart.btnCount = 0;
|
@@ -547,99 +561,85 @@ extend(Chart.prototype, {
|
|
547
561
|
return;
|
548
562
|
}
|
549
563
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
564
|
+
|
565
|
+
var attr = btnOptions.theme,
|
566
|
+
states = attr.states,
|
567
|
+
hover = states && states.hover,
|
568
|
+
select = states && states.select,
|
569
|
+
callback;
|
570
|
+
|
571
|
+
delete attr.states;
|
572
|
+
|
573
|
+
if (onclick) {
|
574
|
+
callback = function () {
|
575
|
+
onclick.apply(chart, arguments);
|
576
|
+
};
|
577
|
+
|
578
|
+
} else if (menuItems) {
|
579
|
+
callback = function () {
|
580
|
+
chart.contextMenu(
|
581
|
+
'contextmenu',
|
582
|
+
menuItems,
|
583
|
+
button.translateX,
|
584
|
+
button.translateY,
|
585
|
+
button.width,
|
586
|
+
button.height,
|
587
|
+
button
|
588
|
+
);
|
589
|
+
button.setState(2);
|
590
|
+
};
|
591
|
+
}
|
592
|
+
|
593
|
+
|
594
|
+
if (btnOptions.text && btnOptions.symbol) {
|
595
|
+
attr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);
|
596
|
+
|
597
|
+
} else if (!btnOptions.text) {
|
598
|
+
extend(attr, {
|
599
|
+
width: btnOptions.width,
|
600
|
+
height: btnOptions.height,
|
601
|
+
padding: 0
|
602
|
+
});
|
554
603
|
}
|
555
604
|
|
556
|
-
|
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)
|
605
|
+
button = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)
|
582
606
|
.attr({
|
583
|
-
id: btnOptions._id,
|
584
|
-
fill: 'rgba(255, 255, 255, 0.001)',
|
585
607
|
title: chart.options.lang[btnOptions._titleKey],
|
586
|
-
|
587
|
-
})
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
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
|
-
};
|
608
|
+
'stroke-linecap': 'round'
|
609
|
+
});
|
610
|
+
|
611
|
+
if (btnOptions.symbol) {
|
612
|
+
symbol = renderer.symbol(
|
613
|
+
btnOptions.symbol,
|
614
|
+
btnOptions.symbolX - (symbolSize / 2),
|
615
|
+
btnOptions.symbolY - (symbolSize / 2),
|
616
|
+
symbolSize,
|
617
|
+
symbolSize
|
618
|
+
)
|
619
|
+
.attr(extend(symbolAttr, {
|
620
|
+
'stroke-width': btnOptions.symbolStrokeWidth || 1,
|
621
|
+
zIndex: 1
|
622
|
+
})).add(button);
|
611
623
|
}
|
612
|
-
/*addEvent(button.element, 'click', function() {
|
613
|
-
onclick.apply(chart, arguments);
|
614
|
-
});*/
|
615
|
-
button.on('click', function () {
|
616
|
-
onclick.apply(chart, arguments);
|
617
|
-
});
|
618
624
|
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
btnOptions.
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
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);
|
625
|
+
button.add()
|
626
|
+
.align(extend(btnOptions, {
|
627
|
+
width: button.width,
|
628
|
+
x: Highcharts.pick(btnOptions.x, buttonOffset) // #1654
|
629
|
+
}), true, 'spacingBox');
|
630
|
+
|
631
|
+
buttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);
|
632
|
+
|
633
|
+
chart.exportSVGElements.push(button, symbol);
|
634
|
+
|
635
635
|
},
|
636
636
|
|
637
637
|
/**
|
638
638
|
* Destroy the buttons.
|
639
639
|
*/
|
640
|
-
destroyExport: function () {
|
641
|
-
var
|
642
|
-
|
640
|
+
destroyExport: function (e) {
|
641
|
+
var chart = e.target,
|
642
|
+
i,
|
643
643
|
elem;
|
644
644
|
|
645
645
|
// Destroy the extra buttons added
|
@@ -666,76 +666,27 @@ extend(Chart.prototype, {
|
|
666
666
|
}
|
667
667
|
});
|
668
668
|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
}
|
669
|
+
|
670
|
+
symbols.menu = function (x, y, width, height) {
|
671
|
+
var arr = [
|
672
|
+
M, x, y + 2.5,
|
673
|
+
L, x + width, y + 2.5,
|
674
|
+
M, x, y + height / 2 + 0.5,
|
675
|
+
L, x + width, y + height / 2 + 0.5,
|
676
|
+
M, x, y + height - 1.5,
|
677
|
+
L, x + width, y + height - 1.5
|
678
|
+
];
|
680
679
|
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
|
-
};
|
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
680
|
};
|
731
681
|
|
732
|
-
|
733
682
|
// Add the buttons on chart load
|
734
683
|
Chart.prototype.callbacks.push(function (chart) {
|
735
684
|
var n,
|
736
685
|
exportingOptions = chart.options.exporting,
|
737
686
|
buttons = exportingOptions.buttons;
|
738
687
|
|
688
|
+
buttonOffset = 0;
|
689
|
+
|
739
690
|
if (exportingOptions.enabled !== false) {
|
740
691
|
|
741
692
|
for (n in buttons) {
|