amcharts.rb 3.1.1.3 → 3.2.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 +8 -8
- data/lib/amcharts/chart.rb +1 -1
- data/lib/amcharts/version.rb +1 -1
- data/vendor/assets/javascripts/amcharts/amcharts.js +188 -185
- data/vendor/assets/javascripts/amcharts/changeLog.txt +37 -0
- data/vendor/assets/javascripts/amcharts/exporting/amexport.js +623 -0
- data/vendor/assets/javascripts/amcharts/exporting/canvg.js +2842 -0
- data/vendor/assets/javascripts/amcharts/exporting/filesaver.js +232 -0
- data/vendor/assets/javascripts/amcharts/exporting/jspdf.js +1943 -0
- data/vendor/assets/javascripts/amcharts/exporting/jspdf.plugin.addimage.js +230 -0
- data/vendor/assets/javascripts/amcharts/exporting/rgbcolor.js +288 -0
- data/vendor/assets/javascripts/amcharts/gauge.js +10 -8
- data/vendor/assets/javascripts/amcharts/pie.js +1 -1
- data/vendor/assets/javascripts/amcharts/serial.js +20 -20
- data/vendor/assets/javascripts/amcharts/thirdPartySoftwareList.txt +28 -5
- data/vendor/assets/javascripts/amcharts/xy.js +7 -6
- metadata +8 -2
@@ -1,3 +1,40 @@
|
|
1
|
+
#### 3.2.0 ####################################################################################################################
|
2
|
+
|
3
|
+
|
4
|
+
# AmCharts.makeChart(divID, chartConfig); method added. divID is id of a div where your chart should appear. chartConfig is
|
5
|
+
JSON object with chart configuration. Check examples with _JSON_ prefix in samples folder to see this in action.
|
6
|
+
|
7
|
+
# type property added to AmChart class. It is required to specify type to one of the following, when creating charts from
|
8
|
+
JSON config: serial, xy, radar, pie, gauge, funnel, map, stock
|
9
|
+
|
10
|
+
# a possibility to export charts as image/pdf/svg added for all modern browsers except IE9 (IE10 is supported). The
|
11
|
+
exporting doesn't require any server side software and is made using js libraries only. Check samples with
|
12
|
+
_exporting_ prefix to see this in action. Exporting to SVG doesn't work very properly with stock chart or charts with
|
13
|
+
legend (will offer saving multiple files).
|
14
|
+
|
15
|
+
# You can set any legend items via legend.data property, for example:
|
16
|
+
legend.data = [{title:"first", color:"#CC0000", value:50}, {title:"second", color:"#00CC00", value:100}];
|
17
|
+
This allows creating any legend items you want. Call chart.legend.validateNow(); if you change legend's data at run time.
|
18
|
+
|
19
|
+
# AmAngularGauge supports legend now
|
20
|
+
|
21
|
+
# bug fix - if a chart with scrollbar was rotated after the chart is created, the scrollbar's graph was shifted to a wrong
|
22
|
+
position.
|
23
|
+
|
24
|
+
# bug fix - column graph type wasn't displayed in chart scrollbar (since 3.1.0)
|
25
|
+
|
26
|
+
# gridAboveGraphs property added to AmCoordinate chart. This allow to show grid lines above your graphs, as world-famous
|
27
|
+
data visualization guru Edward Tufte suggests. Note, this won't work properly with 3D charts.
|
28
|
+
|
29
|
+
# negative axis labels rotation possible. You can use values from -90 to -1 for labelRotation property since now.
|
30
|
+
|
31
|
+
# bug fix: step line with changing line color was rendered incorrectly if some values were missing.
|
32
|
+
|
33
|
+
# bug fix: labelPosition "inside" and "middle" for bar charts fixed.
|
34
|
+
|
35
|
+
# bug fix: AmAngularGauge chart wasn't firing "rendered" event.
|
36
|
+
|
37
|
+
|
1
38
|
#### 3.1.1 ####################################################################################################################
|
2
39
|
|
3
40
|
# FireFox error messages about style declarations fixed
|
@@ -0,0 +1,623 @@
|
|
1
|
+
AmCharts.AmExport = AmCharts.Class({
|
2
|
+
construct: function (chart,cfg) {
|
3
|
+
var _this = this;
|
4
|
+
_this.DEBUG = false;
|
5
|
+
_this.chart = chart;
|
6
|
+
_this.canvas = null;
|
7
|
+
_this.svgs = [];
|
8
|
+
_this.cfg = {
|
9
|
+
menuTop : 'auto',
|
10
|
+
menuLeft : 'auto',
|
11
|
+
menuRight : '0px',
|
12
|
+
menuBottom : '0px',
|
13
|
+
menuItems : [{
|
14
|
+
textAlign : 'center',
|
15
|
+
icon : _this.chart.pathToImages + 'export.png',
|
16
|
+
iconTitle : 'Save chart as an image',
|
17
|
+
format : 'png'
|
18
|
+
}],
|
19
|
+
menuItemStyle : {
|
20
|
+
backgroundColor : 'transparent',
|
21
|
+
rollOverBackgroundColor : '#EFEFEF',
|
22
|
+
color : '#000000',
|
23
|
+
rollOverColor : '#CC0000',
|
24
|
+
paddingTop : '6px',
|
25
|
+
paddingRight : '6px',
|
26
|
+
paddingBottom : '6px',
|
27
|
+
paddingLeft : '6px',
|
28
|
+
marginTop : '0px',
|
29
|
+
marginRight : '0px',
|
30
|
+
marginBottom : '0px',
|
31
|
+
marginLeft : '0px',
|
32
|
+
textAlign : 'left',
|
33
|
+
textDecoration : 'none',
|
34
|
+
fontFamily : _this.chart.fontFamily,
|
35
|
+
fontSize : _this.chart.fontSize + 'px'
|
36
|
+
},
|
37
|
+
menuItemOutput : {
|
38
|
+
backgroundColor : '#FFFFFF',
|
39
|
+
fileName : 'amChart',
|
40
|
+
format : 'png',
|
41
|
+
output : 'dataurlnewwindow',
|
42
|
+
render : 'browser',
|
43
|
+
dpi : 90,
|
44
|
+
onclick : function(instance,config,event) {
|
45
|
+
instance.output(config);
|
46
|
+
}
|
47
|
+
},
|
48
|
+
removeImagery : true
|
49
|
+
};
|
50
|
+
_this.processing = {
|
51
|
+
buffer : [],
|
52
|
+
drawn : 0,
|
53
|
+
timer : 0
|
54
|
+
}
|
55
|
+
|
56
|
+
// Config dependency adaption
|
57
|
+
if ( typeof(window.canvg) != 'undefined' && typeof(window.RGBColor) != 'undefined' ) {
|
58
|
+
_this.cfg.menuItemOutput.render = 'canvg';
|
59
|
+
}
|
60
|
+
if ( typeof(window.saveAs) != 'undefined' ) {
|
61
|
+
_this.cfg.menuItemOutput.output = 'save';
|
62
|
+
}
|
63
|
+
if ( AmCharts.isIE && AmCharts.IEversion < 10 ) {
|
64
|
+
_this.cfg.menuItemOutput.output = 'dataurlnewwindow';
|
65
|
+
}
|
66
|
+
|
67
|
+
// Merge given configs
|
68
|
+
if ( cfg ) {
|
69
|
+
cfg.menuItemOutput = AmCharts.extend(_this.cfg.menuItemOutput,cfg.menuItemOutput || {});
|
70
|
+
cfg.menuItemStyle = AmCharts.extend(_this.cfg.menuItemStyle,cfg.menuItemStyle || {});
|
71
|
+
_this.cfg = AmCharts.extend(_this.cfg,cfg);
|
72
|
+
}
|
73
|
+
|
74
|
+
// Add reference to chart
|
75
|
+
_this.chart.AmExport = _this;
|
76
|
+
|
77
|
+
// Listen to the drawer
|
78
|
+
_this.chart.addListener('rendered',function() {
|
79
|
+
_this.setup();
|
80
|
+
});
|
81
|
+
|
82
|
+
// DEBUG; Public reference
|
83
|
+
if ( _this.DEBUG ) { window.AmExport = _this };
|
84
|
+
},
|
85
|
+
|
86
|
+
/*
|
87
|
+
Simple log function for internal purpose
|
88
|
+
@param **args
|
89
|
+
*/
|
90
|
+
log: function() {
|
91
|
+
console.log('AmExport: ',arguments);
|
92
|
+
},
|
93
|
+
|
94
|
+
/* PUBLIC
|
95
|
+
Prepares everything to get exported
|
96
|
+
@param none
|
97
|
+
*/
|
98
|
+
setup: function() {
|
99
|
+
var _this = this;
|
100
|
+
|
101
|
+
if ( _this.DEBUG == 10 ) { _this.log('SETUP START'); } // DEBUG
|
102
|
+
|
103
|
+
|
104
|
+
if ( !AmCharts.isIE || ( AmCharts.isIE && AmCharts.IEversion > 9 ) ) {
|
105
|
+
window.clearTimeout(_this.processing.timer);
|
106
|
+
_this.processing.timer = setTimeout(function() {
|
107
|
+
// Polify SVG; needs to wait
|
108
|
+
_this.polifySVG();
|
109
|
+
|
110
|
+
// Build Buttons
|
111
|
+
_this.generateButtons();
|
112
|
+
if ( _this.DEBUG == 10 ) { _this.log('SETUP END'); } // DEBUG
|
113
|
+
},1000);
|
114
|
+
} else {
|
115
|
+
if ( _this.DEBUG == 10 ) { _this.log('< IE10 NOT SUPPORTED'); } // DEBUG
|
116
|
+
}
|
117
|
+
},
|
118
|
+
|
119
|
+
/* PUBLIC
|
120
|
+
Decodes base64 string to binary array
|
121
|
+
@param base64_string
|
122
|
+
@copyright Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr
|
123
|
+
*/
|
124
|
+
generateBinaryArray: function(base64_string) {
|
125
|
+
var
|
126
|
+
len = base64_string.length
|
127
|
+
, buffer = new Uint8Array(len / 4 * 3 | 0)
|
128
|
+
, i = 0
|
129
|
+
, outptr = 0
|
130
|
+
, last = [0, 0]
|
131
|
+
, state = 0
|
132
|
+
, save = 0
|
133
|
+
, rank
|
134
|
+
, code
|
135
|
+
, undef
|
136
|
+
, base64_ranks = new Uint8Array([
|
137
|
+
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1
|
138
|
+
, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
139
|
+
, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
|
140
|
+
, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
|
141
|
+
, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
|
142
|
+
]);
|
143
|
+
while (len--) {
|
144
|
+
code = base64_string.charCodeAt(i++);
|
145
|
+
rank = base64_ranks[code-43];
|
146
|
+
if (rank !== 255 && rank !== undef) {
|
147
|
+
last[1] = last[0];
|
148
|
+
last[0] = code;
|
149
|
+
save = (save << 6) | rank;
|
150
|
+
state++;
|
151
|
+
if (state === 4) {
|
152
|
+
buffer[outptr++] = save >>> 16;
|
153
|
+
if (last[1] !== 61 /* padding character */) {
|
154
|
+
buffer[outptr++] = save >>> 8;
|
155
|
+
}
|
156
|
+
if (last[0] !== 61 /* padding character */) {
|
157
|
+
buffer[outptr++] = save;
|
158
|
+
}
|
159
|
+
state = 0;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
// 2/3 chance there's going to be some null bytes at the end, but that
|
164
|
+
// doesn't really matter with most image formats.
|
165
|
+
// If it somehow matters for you, truncate the buffer up outptr.
|
166
|
+
return buffer;
|
167
|
+
},
|
168
|
+
|
169
|
+
/*
|
170
|
+
Creates blob object
|
171
|
+
@param base64_datastring string
|
172
|
+
@param type string
|
173
|
+
*/
|
174
|
+
generateBlob: function(datastring,type) {
|
175
|
+
var _this = this,
|
176
|
+
header_end = datastring.indexOf(',') + 1,
|
177
|
+
header = datastring.substring(0,header_end),
|
178
|
+
data = datastring,
|
179
|
+
blob = new Blob();
|
180
|
+
|
181
|
+
if ( header.indexOf('base64') != -1 ) {
|
182
|
+
data = _this.generateBinaryArray(datastring.substring(header_end));
|
183
|
+
}
|
184
|
+
|
185
|
+
// Fake blob for IE
|
186
|
+
if ( AmCharts.isIE && AmCharts.IEversion < 10 ) {
|
187
|
+
blob.data = data;
|
188
|
+
blob.size = data.length;
|
189
|
+
blob.type = type;
|
190
|
+
blob.encoding = 'base64';
|
191
|
+
} else {
|
192
|
+
blob = new Blob([data],{type: type});
|
193
|
+
}
|
194
|
+
return blob
|
195
|
+
},
|
196
|
+
|
197
|
+
/*
|
198
|
+
Creates PDF object
|
199
|
+
@param config object
|
200
|
+
*/
|
201
|
+
generatePDF: function(cfg) {
|
202
|
+
var _this = this,
|
203
|
+
pdf = {output: function() {return ''}},
|
204
|
+
data = _this.canvas.toDataURL('image/jpeg'), // JSPDF ONLY SUPPORTS JPG
|
205
|
+
width = (_this.canvas.width * 25.4) / cfg.dpi,
|
206
|
+
height = (_this.canvas.height * 25.4) / cfg.dpi;
|
207
|
+
|
208
|
+
// Check
|
209
|
+
if ( window.jsPDF ) {
|
210
|
+
pdf = new jsPDF();
|
211
|
+
if ( pdf.addImage ) {
|
212
|
+
pdf.addImage(data, 'JPEG', 0, 0, width, height);
|
213
|
+
} else {
|
214
|
+
alert("Missing jsPDF plugin; Please add the 'addImage' plugin.");
|
215
|
+
}
|
216
|
+
} else {
|
217
|
+
alert("Missing jsPDF lib; Don't forget to add the addImage plugin.");
|
218
|
+
}
|
219
|
+
|
220
|
+
return pdf;
|
221
|
+
},
|
222
|
+
|
223
|
+
/*
|
224
|
+
Creates the CANVAS to receive the image data
|
225
|
+
@param format void()
|
226
|
+
@param callback; given callback function which returns the blob or datastring of the configured ouput type
|
227
|
+
*/
|
228
|
+
output: function(cfg,externalCallback) {
|
229
|
+
var _this = this,
|
230
|
+
cfg = AmCharts.extend(AmCharts.extend({},_this.cfg.menuItemOutput),cfg||{});
|
231
|
+
|
232
|
+
/* PRIVATE
|
233
|
+
Callback function which gets called after the drawing process is done
|
234
|
+
@param none
|
235
|
+
*/
|
236
|
+
function internalCallback() {
|
237
|
+
var data = null;
|
238
|
+
if ( _this.DEBUG == 10 ) { _this.log('OUTPUT',format); } // DEBUG
|
239
|
+
|
240
|
+
// SVG
|
241
|
+
if ( cfg.format == 'image/svg+xml' || cfg.format == 'svg' ) {
|
242
|
+
for ( var i = 0; i < _this.processing.buffer.length; i++ ) {
|
243
|
+
data = new XMLSerializer().serializeToString(_this.processing.buffer[i][0]),
|
244
|
+
blob = _this.generateBlob(data,'image/svg+xml');
|
245
|
+
|
246
|
+
if ( cfg.output == 'save' ) {
|
247
|
+
saveAs(blob, cfg.fileName + '.svg');
|
248
|
+
} else if ( cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring' ) {
|
249
|
+
blob = 'data:image/svg+xml;base64,' + btoa(data);
|
250
|
+
} else if ( cfg.output == 'dataurlnewwindow' ) {
|
251
|
+
window.open('data:image/svg+xml;base64,' + btoa(data));
|
252
|
+
} else if ( cfg.output == 'datauri' || cfg.output == 'dataurl' ) {
|
253
|
+
location.href = 'data:image/svg+xml;base64,' + btoa(data);
|
254
|
+
} else if ( cfg.output == 'datastream' ) {
|
255
|
+
location.href = 'data:image/octet-stream;base64,' + btoa(data);
|
256
|
+
}
|
257
|
+
|
258
|
+
if ( externalCallback )
|
259
|
+
externalCallback.apply(_this,[blob]);
|
260
|
+
}
|
261
|
+
// PDF
|
262
|
+
} else if ( cfg.format == 'application/pdf' || cfg.format == 'pdf' ) {
|
263
|
+
data = _this.generatePDF(cfg).output('dataurlstring'),
|
264
|
+
blob = _this.generateBlob(data,'application/pdf');
|
265
|
+
|
266
|
+
if ( cfg.output == 'save' ) {
|
267
|
+
saveAs(blob, cfg.fileName + '.pdf');
|
268
|
+
} else if ( cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring' ) {
|
269
|
+
blob = data;
|
270
|
+
} else if ( cfg.output == 'dataurlnewwindow' ) {
|
271
|
+
window.open(data);
|
272
|
+
} else if ( cfg.output == 'datauri' || cfg.output == 'dataurl' ) {
|
273
|
+
location.href = data;
|
274
|
+
} else if ( cfg.output == 'datastream' ) {
|
275
|
+
location.href = data.replace('application/pdf','application/octet-stream');
|
276
|
+
}
|
277
|
+
|
278
|
+
if ( externalCallback )
|
279
|
+
externalCallback.apply(_this,[blob]);
|
280
|
+
|
281
|
+
// PNG
|
282
|
+
} else if ( cfg.format == 'image/png' || cfg.format == 'png' ) {
|
283
|
+
data = _this.canvas.toDataURL('image/png'),
|
284
|
+
blob = _this.generateBlob(data,'image/png');
|
285
|
+
|
286
|
+
if ( cfg.output == 'save' ) {
|
287
|
+
saveAs(blob, cfg.fileName + '.png');
|
288
|
+
} else if ( cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring' ) {
|
289
|
+
blob = data;
|
290
|
+
} else if ( cfg.output == 'dataurlnewwindow' ) {
|
291
|
+
window.open(data);
|
292
|
+
} else if ( cfg.output == 'datauri' || cfg.output == 'dataurl' ) {
|
293
|
+
location.href = data;
|
294
|
+
} else if ( cfg.output == 'datastream' ) {
|
295
|
+
location.href = data.replace('image/png','image/octet-stream');
|
296
|
+
}
|
297
|
+
|
298
|
+
if ( externalCallback )
|
299
|
+
externalCallback.apply(_this,[blob]);
|
300
|
+
|
301
|
+
// JPG
|
302
|
+
} else if ( cfg.format == 'image/jpeg' || cfg.format == 'jpeg' || cfg.format == 'jpg' ) {
|
303
|
+
data = _this.canvas.toDataURL('image/jpeg'),
|
304
|
+
blob = _this.generateBlob(data,'image/jpeg');
|
305
|
+
|
306
|
+
if ( cfg.output == 'save' ) {
|
307
|
+
saveAs(blob, cfg.fileName + '.jpg');
|
308
|
+
} else if ( cfg.output == 'datastring' || cfg.output == 'datauristring' || cfg.output == 'dataurlstring' ) {
|
309
|
+
blob = data;
|
310
|
+
} else if ( cfg.output == 'dataurlnewwindow' ) {
|
311
|
+
window.open(data);
|
312
|
+
} else if ( cfg.output == 'datauri' || cfg.output == 'dataurl' ) {
|
313
|
+
location.href = data;
|
314
|
+
} else if ( cfg.output == 'datastream' ) {
|
315
|
+
location.href = data.replace('image/jpeg','image/octet-stream');
|
316
|
+
}
|
317
|
+
|
318
|
+
if ( externalCallback )
|
319
|
+
externalCallback.apply(_this,[blob]);
|
320
|
+
}
|
321
|
+
|
322
|
+
}
|
323
|
+
|
324
|
+
return _this.generateOutput(cfg,internalCallback);
|
325
|
+
},
|
326
|
+
|
327
|
+
/* PUBLIC
|
328
|
+
Polifies missing attributes to the SVG and replaces images to embedded base64 images
|
329
|
+
@param none
|
330
|
+
*/
|
331
|
+
polifySVG: function() {
|
332
|
+
var _this = this;
|
333
|
+
var svgs = _this.chart.div.getElementsByTagName('svg');
|
334
|
+
|
335
|
+
// Recursive function to force the attributes
|
336
|
+
function recursiveChange(svg,tag) {
|
337
|
+
var items = svg.getElementsByTagName(tag);
|
338
|
+
|
339
|
+
for ( var i = 0; i < items.length; i++) {
|
340
|
+
|
341
|
+
if ( _this.cfg.removeImagery ) {
|
342
|
+
items[i].parentNode.removeChild(items[i]);
|
343
|
+
|
344
|
+
} else {
|
345
|
+
var image = document.createElement('img');
|
346
|
+
var canvas = document.createElement('canvas');
|
347
|
+
var ctx = canvas.getContext('2d');
|
348
|
+
|
349
|
+
canvas.width = items[i].getAttribute('width');
|
350
|
+
canvas.height = items[i].getAttribute('height');
|
351
|
+
image.src = items[i].getAttribute('xlink:href');
|
352
|
+
image.width = items[i].getAttribute('width');
|
353
|
+
image.height = items[i].getAttribute('height');
|
354
|
+
|
355
|
+
try {
|
356
|
+
ctx.drawImage(image,0,0,image.width,image.height);
|
357
|
+
datastring = canvas.toDataURL(); // image.src; // canvas.toDataURL(); //
|
358
|
+
} catch(err) {
|
359
|
+
datastring = image.src; // image.src; // canvas.toDataURL(); //
|
360
|
+
|
361
|
+
_this.log('Tainted canvas, reached browser CORS security; origin from imagery must be equal to the server!');
|
362
|
+
throw new Error(err);
|
363
|
+
}
|
364
|
+
|
365
|
+
items[i].setAttribute('xlink:href',datastring);
|
366
|
+
}
|
367
|
+
|
368
|
+
if ( _this.DEBUG == 10 ) { _this.log('POLIFIED',items[i]); } // DEBUG
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
// Loop through svgs to add some standardization
|
373
|
+
for ( var i = 0; i < svgs.length; i++ ) {
|
374
|
+
var parent = svgs[i].parentNode;
|
375
|
+
|
376
|
+
// Put some attrs to it
|
377
|
+
/*
|
378
|
+
if ( !AmCharts.isIE ) {
|
379
|
+
svgs[i].setAttribute('xmlns','http://www.w3.org/2000/svg');
|
380
|
+
svgs[i].setAttribute('xmlns:xlink','http://www.w3.org/1999/xlink');
|
381
|
+
}
|
382
|
+
svgs[i].setAttribute('width',parent.style.width);
|
383
|
+
svgs[i].setAttribute('height',parent.style.height);
|
384
|
+
*/
|
385
|
+
|
386
|
+
if ( _this.DEBUG == 10 ) { _this.log('POLIFIED',svgs[i]); } // DEBUG
|
387
|
+
|
388
|
+
// Force link adaption
|
389
|
+
recursiveChange(svgs[i],'pattern');
|
390
|
+
recursiveChange(svgs[i],'image');
|
391
|
+
|
392
|
+
_this.svgs.push(svgs[i]);
|
393
|
+
}
|
394
|
+
|
395
|
+
return svgs;
|
396
|
+
},
|
397
|
+
|
398
|
+
/* PUBLIC
|
399
|
+
Generates the canvas with the given SVGs and configured renderer
|
400
|
+
@param callback; function(); gets called after drawing process on the canvas has been finished
|
401
|
+
*/
|
402
|
+
generateOutput: function(cfg,callback) {
|
403
|
+
var _this = this,
|
404
|
+
svgs = _this.chart.div.getElementsByTagName('svg'),
|
405
|
+
canvas = document.createElement('canvas'),
|
406
|
+
context = canvas.getContext('2d'),
|
407
|
+
offset = {
|
408
|
+
y: 0,
|
409
|
+
x: 0
|
410
|
+
},
|
411
|
+
tmp = {};
|
412
|
+
|
413
|
+
// Reset
|
414
|
+
_this.processing.buffer = [];
|
415
|
+
_this.processing.drawn = 0;
|
416
|
+
_this.canvas = canvas;
|
417
|
+
|
418
|
+
// Walkthroug SVGs
|
419
|
+
if ( _this.DEBUG == 10 ) { _this.log('START EXPORT'); } // DEBUG
|
420
|
+
if ( _this.DEBUG == 10 ) { _this.log('START BUFFERING'); } // DEBUG
|
421
|
+
for ( var i = 0; i < svgs.length; i++ ) {
|
422
|
+
var parent = svgs[i].parentNode,
|
423
|
+
svgX = Number(parent.style.left.slice(0,-2)),
|
424
|
+
svgY = Number(parent.style.top.slice(0,-2));
|
425
|
+
tmp = AmCharts.extend({},offset);
|
426
|
+
|
427
|
+
// Overtake parent position if givwn
|
428
|
+
offset.x = svgX?svgX:offset.x;
|
429
|
+
offset.y = svgY?svgY:offset.y;
|
430
|
+
|
431
|
+
_this.processing.buffer.push([svgs[i],AmCharts.extend({},offset)]);
|
432
|
+
|
433
|
+
// Put back from "cache"
|
434
|
+
if ( svgY&&svgX ) {
|
435
|
+
offset = tmp;
|
436
|
+
|
437
|
+
// New offset for next one
|
438
|
+
} else {
|
439
|
+
offset.y += svgY?0:parent.offsetHeight;
|
440
|
+
}
|
441
|
+
|
442
|
+
if ( _this.DEBUG == 10 ) { _this.log('BUFFERED',svgs[i],offset); } // DEBUG
|
443
|
+
}
|
444
|
+
if ( _this.DEBUG == 10 ) { _this.log('END BUFFERING'); } // DEBUG
|
445
|
+
|
446
|
+
// Apply background
|
447
|
+
if ( _this.DEBUG == 10 ) { _this.log('START DRAWING',cfg.render); } // DEBUG
|
448
|
+
if ( _this.DEBUG == 10 ) { _this.log('FILL BACKGROUND'); } // DEBUG
|
449
|
+
canvas.id = AmCharts.getUniqueId();
|
450
|
+
canvas.width = _this.chart.divRealWidth;
|
451
|
+
canvas.height = _this.chart.divRealHeight;
|
452
|
+
|
453
|
+
// Set given background; jpeg default
|
454
|
+
if ( cfg.backgroundColor || format == 'image/jpeg' ) {
|
455
|
+
context.fillStyle = cfg.backgroundColor || '#FFFFFF';
|
456
|
+
context.fillRect(0,0,canvas.width,canvas.height);
|
457
|
+
}
|
458
|
+
|
459
|
+
/* PRIVATE
|
460
|
+
Recursive function to draw the images to the canvas;
|
461
|
+
@param none;
|
462
|
+
*/
|
463
|
+
function drawItWhenItsLoaded() {
|
464
|
+
var img,buffer,offset,source;
|
465
|
+
|
466
|
+
// DRAWING PROCESS DONE
|
467
|
+
if ( _this.processing.buffer.length == _this.processing.drawn ) {
|
468
|
+
if ( _this.DEBUG == 10 ) { _this.log('END DRAWING'); } // DEBUG
|
469
|
+
return callback();
|
470
|
+
|
471
|
+
// LOOPING LUI
|
472
|
+
} else {
|
473
|
+
if ( _this.DEBUG == 10 ) { _this.log('DRAW',_this.processing.drawn + 1,'OF',_this.processing.buffer.length); } // DEBUG
|
474
|
+
|
475
|
+
buffer = _this.processing.buffer[_this.processing.drawn];
|
476
|
+
source = new XMLSerializer().serializeToString(buffer[0]); //source = 'data:image/svg+xml;base64,' + btoa();
|
477
|
+
offset = buffer[1];
|
478
|
+
|
479
|
+
if ( _this.DEBUG == 10 ) { _this.log('SOURCE',source); } // DEBUG
|
480
|
+
|
481
|
+
// NATIVE
|
482
|
+
if ( cfg.render == 'browser' ) {
|
483
|
+
img = new Image();
|
484
|
+
img.id = AmCharts.getUniqueId();
|
485
|
+
source = 'data:image/svg+xml;base64,' + btoa(source);
|
486
|
+
|
487
|
+
//img.crossOrigin = "Anonymous";
|
488
|
+
img.onload = function() {
|
489
|
+
context.drawImage(this,buffer[1].x,buffer[1].y);
|
490
|
+
_this.processing.drawn++;
|
491
|
+
|
492
|
+
if ( _this.DEBUG == 10 ) { _this.log('ONLOAD',this); } // DEBUG
|
493
|
+
drawItWhenItsLoaded();
|
494
|
+
}
|
495
|
+
img.onerror = function() {
|
496
|
+
if ( _this.DEBUG == 10 ) { _this.log('ONERROR',this); } // DEBUG
|
497
|
+
context.drawImage(this,buffer[1].x,buffer[1].y);
|
498
|
+
_this.processing.drawn++;
|
499
|
+
drawItWhenItsLoaded();
|
500
|
+
}
|
501
|
+
img.src = source;
|
502
|
+
|
503
|
+
if ( _this.DEBUG == 10 ) { _this.log('ADD',img); } // DEBUG
|
504
|
+
if ( img.complete || typeof(img.complete) == 'undefined' || img.complete === undefined ) {
|
505
|
+
if ( _this.DEBUG == 10 ) { _this.log('FORCE ONLOAD',img); } // DEBUG
|
506
|
+
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
|
507
|
+
img.src = source;
|
508
|
+
}
|
509
|
+
|
510
|
+
// CANVG
|
511
|
+
} else if ( cfg.render == 'canvg' ) {
|
512
|
+
canvg(canvas,source,{
|
513
|
+
offsetX : offset.x,
|
514
|
+
offsetY : offset.y,
|
515
|
+
ignoreMouse : true,
|
516
|
+
ignoreAnimation : true,
|
517
|
+
ignoreDimensions : true,
|
518
|
+
ignoreClear : true,
|
519
|
+
renderCallback : function() {
|
520
|
+
_this.processing.drawn++;
|
521
|
+
drawItWhenItsLoaded();
|
522
|
+
}
|
523
|
+
});
|
524
|
+
}
|
525
|
+
}
|
526
|
+
}
|
527
|
+
return drawItWhenItsLoaded();
|
528
|
+
},
|
529
|
+
|
530
|
+
/*
|
531
|
+
Generates the export menu to trigger the exportation
|
532
|
+
@param none;
|
533
|
+
*/
|
534
|
+
generateButtons: function() {
|
535
|
+
var _this = this,
|
536
|
+
div = document.createElement('div'),
|
537
|
+
lvl = 0;
|
538
|
+
|
539
|
+
// Push sublings
|
540
|
+
function createList(items) {
|
541
|
+
var ul = document.createElement('ul');
|
542
|
+
|
543
|
+
ul.setAttribute('style','list-style: none; margin: 0; padding: 0;');
|
544
|
+
|
545
|
+
// Walkthrough items
|
546
|
+
for ( var i = 0; i < items.length; i++ ) {
|
547
|
+
var li = document.createElement('li'),
|
548
|
+
img = document.createElement('img'),
|
549
|
+
a = document.createElement('a'),
|
550
|
+
item = items[i],
|
551
|
+
children = null,
|
552
|
+
itemStyle = AmCharts.extend(AmCharts.extend({},_this.cfg.menuItemStyle),items[i]);
|
553
|
+
|
554
|
+
// MERGE CFG
|
555
|
+
item = AmCharts.extend(AmCharts.extend({},_this.cfg.menuItemOutput),item);
|
556
|
+
|
557
|
+
// ICON
|
558
|
+
if ( item['icon'] ) {
|
559
|
+
img.alt = '';
|
560
|
+
img.src = item['icon'];
|
561
|
+
img.setAttribute('style','margin: 0 auto;border: none;outline: none');
|
562
|
+
if ( item['iconTitle'] ) {
|
563
|
+
img.title=item['iconTitle'];
|
564
|
+
}
|
565
|
+
a.appendChild(img);
|
566
|
+
}
|
567
|
+
|
568
|
+
// TITLE; STYLING
|
569
|
+
a.href = '#';
|
570
|
+
if ( item['title'] ) {
|
571
|
+
img.setAttribute('style','margin-right: 5px;');
|
572
|
+
a.innerHTML += item.title;
|
573
|
+
}
|
574
|
+
a.setAttribute('style','display: block;');
|
575
|
+
AmCharts.extend(a.style,itemStyle)
|
576
|
+
|
577
|
+
// ONCLICK
|
578
|
+
a.onclick = item.onclick.bind(a,_this,item);
|
579
|
+
li.appendChild(a);
|
580
|
+
|
581
|
+
// APPEND SIBLINGS
|
582
|
+
if ( item.items ) {
|
583
|
+
children = createList(item.items);
|
584
|
+
li.appendChild(children);
|
585
|
+
|
586
|
+
li.onmouseover = function() {
|
587
|
+
children.style.display = 'block';
|
588
|
+
}
|
589
|
+
li.onmouseout = function() {
|
590
|
+
children.style.display = 'none';
|
591
|
+
}
|
592
|
+
children.style.display = 'none';
|
593
|
+
}
|
594
|
+
|
595
|
+
// Append to parent
|
596
|
+
ul.appendChild(li);
|
597
|
+
|
598
|
+
// Apply hover
|
599
|
+
a.onmouseover = function() {
|
600
|
+
this.style.backgroundColor = itemStyle.rollOverBackgroundColor;
|
601
|
+
this.style.color = itemStyle.rollOverColor;
|
602
|
+
this.style.borderColor = itemStyle.rollOverBorderColor;
|
603
|
+
}
|
604
|
+
a.onmouseout = function() {
|
605
|
+
this.style.backgroundColor = itemStyle.backgroundColor;
|
606
|
+
this.style.color = itemStyle.color;
|
607
|
+
this.style.borderColor = itemStyle.borderColor;
|
608
|
+
}
|
609
|
+
}
|
610
|
+
lvl++;
|
611
|
+
|
612
|
+
if ( _this.DEBUG == 10 ) { _this.log('MENU',ul); } // DEBUG
|
613
|
+
|
614
|
+
return ul;
|
615
|
+
}
|
616
|
+
|
617
|
+
// Style wrapper; Push into chart div
|
618
|
+
div.setAttribute('style','position: absolute;top:'+ _this.cfg.menuTop +';right:'+ _this.cfg.menuRight +';bottom:'+ _this.cfg.menuBottom +';left:'+ _this.cfg.menuLeft +';box-shadow:0px 0px 1px 0px rgba(0,0,0,0);');
|
619
|
+
div.appendChild(createList(_this.cfg.menuItems));
|
620
|
+
_this.chart.div.style.position = 'relative';
|
621
|
+
_this.chart.div.appendChild(div);
|
622
|
+
}
|
623
|
+
});
|