Skip to content

Commit c8b1e68

Browse files
committed
Feature to Export Multi-Series as CSV
1 parent de86e0d commit c8b1e68

File tree

3 files changed

+159
-163
lines changed

3 files changed

+159
-163
lines changed

dist/canvasjsascsv.min.js

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/example.html

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/CanvasJS As CSV.js

Lines changed: 152 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,153 @@
11
(function () {
2-
var CanvasJS = window.CanvasJS || CanvasJS ? window.CanvasJS : null;
3-
if (CanvasJS) {
4-
CanvasJS.Chart.prototype.exportAsCSV = function (fileName) {
5-
CanvasJSDataAsCSV(this, fileName);
6-
}
7-
}
8-
9-
function CanvasJSDataAsCSV(chart, fileName) {
10-
if (chart.exportEnabled) {
11-
var exportCSV = document.createElement('div');
12-
var text = document.createTextNode("Save as CSV");
13-
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColor + "; color: " + chart.toolbar.fontColor);
14-
exportCSV.appendChild(text);
15-
exportCSV.addEventListener("mouseover", function () {
16-
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColorOnHover + "; color: " + chart.toolbar.fontColorOnHover);
17-
});
18-
exportCSV.addEventListener("mouseout", function () {
19-
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColor + "; color: " + chart.toolbar.fontColor);
20-
});
21-
exportCSV.addEventListener("click", function () {
22-
parseCSV({
23-
filename: (fileName || "chart-data") + ".csv",
24-
chart: chart
25-
})
26-
});
27-
28-
chart._toolBar.lastChild.appendChild(exportCSV);
29-
} else {
30-
var base64Img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEgSURBVEhL3dM/SgNBFMfxBS8gWkYb0dJSyBGCwdIzRPAKgrZKINdIkVJB0qqteIdYCYoHEPX74P1gMszuzG5SiD/4wM6/99jJpvq3GeIVPwUu0ToLpIrVad1EB3Pp3KRLA1PcRAdyCYtLURNtziUsHMqmeGOUxnNtPs2cZNp+mk2S0eIteu7O5y5wgFN8Yw8vePZnnZVktLiDJzxi1+cOfe4GHxhhgjHOoLOSTLgYbjZz7OPaxzOc4Nif4/3JaNHe4MHpDc7xiW284R1b2IS9ka61MWpg925NrPi9z9mfx65pgC+fO0Lfn21/Nqt8RUo8XordZ9cmSjyuTfHGKH+nQe6qptiA5QqpPcbWkin5PXJNaot3Tdhk7cUVKxwUr6pfwprgQh4A9MYAAAAASUVORK5CYII=";
31-
var exportButton = document.createElement('button');
32-
33-
exportButton.style.cssText = "position:relative;display: inline-block;padding: 0px 4px;height: 27px;cursor: pointer;text-align: center;text-decoration: none;background-color:" + chart.toolbar.backgroundColor + ";border: 1px solid " + chart.toolbar.borderColor + ";left:" + (chart.container.clientWidth - (chart.options.zoomEnabled ? 115 : 60)) + "px; top: 1px";
34-
35-
var img = document.createElement("IMG");
36-
img.setAttribute("src", base64Img);
37-
exportButton.appendChild(img);
38-
exportButton.addEventListener("mouseover", function () {
39-
this.style.cssText = this.style.cssText + "background-color: " + chart.toolbar.backgroundColorOnHover;
40-
});
41-
exportButton.addEventListener("mouseout", function () {
42-
this.style.cssText = this.style.cssText + "background-color: " + chart.toolbar.backgroundColor;
43-
});
44-
exportButton.addEventListener("click", function () {
45-
parseCSV({
46-
filename: (fileName || "chart-data") + ".csv",
47-
chart: chart
48-
})
49-
});
50-
51-
chart.container.appendChild(exportButton);
52-
}
53-
}
54-
55-
function convertChartDataToCSV(args) {
56-
var result, ctr, keys, columnDelimiter, lineDelimiter, data;
57-
data = args.data || null;
58-
if (data == null || !data.length) {
59-
return null;
60-
}
61-
columnDelimiter = args.columnDelimiter || ',';
62-
lineDelimiter = args.lineDelimiter || '\n';
63-
keys = Object.keys(data[0]);
64-
result = '';
65-
result += keys.join(columnDelimiter);
66-
result += lineDelimiter;
67-
data.forEach(function (item) {
68-
ctr = 0;
69-
keys.forEach(function (key) {
70-
if (ctr > 0) result += columnDelimiter;
71-
result += (!(typeof item[key] === 'undefined' || item[key] === null) ? item[key] : "");
72-
ctr++;
73-
});
74-
result += lineDelimiter;
75-
});
76-
return result;
77-
}
78-
79-
function parseCSV(args) {
80-
var csv = "";
81-
for (var i = 0; i < args.chart.options.data.length; i++) {
82-
csv += convertChartDataToCSV({
83-
data: args.chart.options.data[i].dataPoints
84-
});
85-
}
86-
if (csv == null) return;
87-
var filename = args.filename || 'chart-data.csv';
88-
if (!csv.match(/^data:text\/csv/i)) {
89-
csv = 'data:text/csv;charset=utf-8,' + csv;
90-
}
91-
downloadFile(csv, filename);
92-
}
93-
94-
function downloadFile(extData, filename) {
95-
var data = encodeURI(extData);
96-
var link = document.createElement('a');
97-
link.setAttribute('href', data);
98-
link.setAttribute('download', filename);
99-
document.body.appendChild(link); // Required for FF
100-
link.click();
101-
document.body.removeChild(link);
102-
}
103-
104-
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
105-
module.exports = CanvasJSDataAsCSV;
106-
}
107-
else {
108-
if (typeof define === 'function' && define.amd) {
109-
define([], function () {
110-
return CanvasJSDataAsCSV;
111-
});
112-
}
113-
else {
114-
window.CanvasJSDataAsCSV = CanvasJSDataAsCSV;
115-
}
116-
}
117-
})();
2+
var CanvasJS = window.CanvasJS || CanvasJS ? window.CanvasJS : null;
3+
if (CanvasJS) {
4+
CanvasJS.Chart.prototype.exportAsCSV = function (fileName) {
5+
CanvasJSDataAsCSV(this, fileName);
6+
}
7+
}
8+
9+
function CanvasJSDataAsCSV(chart, fileName) {
10+
if (chart.exportEnabled) {
11+
var exportCSV = document.createElement('div');
12+
var text = document.createTextNode("Save as CSV");
13+
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColor + "; color: " + chart.toolbar.fontColor);
14+
exportCSV.appendChild(text);
15+
exportCSV.addEventListener("mouseover", function () {
16+
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColorOnHover + "; color: " + chart.toolbar.fontColorOnHover);
17+
});
18+
exportCSV.addEventListener("mouseout", function () {
19+
exportCSV.setAttribute("style", "padding: 12px 8px; background-color: " + chart.toolbar.backgroundColor + "; color: " + chart.toolbar.fontColor);
20+
});
21+
exportCSV.addEventListener("click", function () {
22+
parseCSV({
23+
filename: (fileName || "chart-data") + ".csv",
24+
chart: chart
25+
})
26+
});
27+
28+
chart._toolBar.lastChild.appendChild(exportCSV);
29+
} else {
30+
var base64Img = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEgSURBVEhL3dM/SgNBFMfxBS8gWkYb0dJSyBGCwdIzRPAKgrZKINdIkVJB0qqteIdYCYoHEPX74P1gMszuzG5SiD/4wM6/99jJpvq3GeIVPwUu0ToLpIrVad1EB3Pp3KRLA1PcRAdyCYtLURNtziUsHMqmeGOUxnNtPs2cZNp+mk2S0eIteu7O5y5wgFN8Yw8vePZnnZVktLiDJzxi1+cOfe4GHxhhgjHOoLOSTLgYbjZz7OPaxzOc4Nif4/3JaNHe4MHpDc7xiW284R1b2IS9ka61MWpg925NrPi9z9mfx65pgC+fO0Lfn21/Nqt8RUo8XordZ9cmSjyuTfHGKH+nQe6qptiA5QqpPcbWkin5PXJNaot3Tdhk7cUVKxwUr6pfwprgQh4A9MYAAAAASUVORK5CYII=";
31+
var exportButton = document.createElement('button');
32+
33+
exportButton.style.cssText = "position:relative;display: inline-block;padding: 0px 4px;height: 27px;cursor: pointer;text-align: center;text-decoration: none;background-color:" + chart.toolbar.backgroundColor + ";border: 1px solid " + chart.toolbar.borderColor + ";left:" + (chart.container.clientWidth - (chart.options.zoomEnabled ? 115 : 60)) + "px; top: 1px";
34+
35+
var img = document.createElement("IMG");
36+
img.setAttribute("src", base64Img);
37+
exportButton.appendChild(img);
38+
exportButton.addEventListener("mouseover", function () {
39+
this.style.cssText = this.style.cssText + "background-color: " + chart.toolbar.backgroundColorOnHover;
40+
});
41+
exportButton.addEventListener("mouseout", function () {
42+
this.style.cssText = this.style.cssText + "background-color: " + chart.toolbar.backgroundColor;
43+
});
44+
exportButton.addEventListener("click", function () {
45+
parseCSV({
46+
filename: (fileName || "chart-data") + ".csv",
47+
chart: chart
48+
})
49+
});
50+
51+
chart.container.appendChild(exportButton);
52+
}
53+
}
54+
55+
function mergeData(data) {
56+
var mergedDps = [],
57+
result = [];
58+
for (var i = 0; i < data.length; i++) {
59+
for (var j = 0; j < data[i].dataPoints.length; j++) {
60+
mergedDps.push(data[i].dataPoints[j]);
61+
}
62+
}
63+
64+
mergedDps.forEach(function (item) {
65+
var existing = result.filter(function (v, i) {
66+
return v.x == item.x;
67+
});
68+
if (existing.length) {
69+
var existingIndex = result.indexOf(existing[0]);
70+
result[existingIndex].y = result[existingIndex].y.concat(item.y);
71+
} else {
72+
if (typeof item.y == 'string' || typeof item.y == 'number')
73+
item.y = [item.y];
74+
result.push(item);
75+
}
76+
});
77+
for (var i = 0; i < result.length; i++) {
78+
for (var j = 0; j < result[i].y.length; j++) {
79+
result[i]["y" + j] = result[i].y[j];
80+
}
81+
delete result[i].y;
82+
}
83+
return result;
84+
}
85+
86+
function convertChartDataToCSV(args) {
87+
var result = '',
88+
ctr, keys, columnDelimiter, lineDelimiter, data;
89+
90+
data = args.data || null;
91+
if (data == null || !data.length) {
92+
return null;
93+
}
94+
95+
columnDelimiter = args.columnDelimiter || ',';
96+
lineDelimiter = args.lineDelimiter || '\n';
97+
98+
var mergedData = mergeData(data);
99+
100+
keys = Object.keys(mergedData[0]);
101+
result = '';
102+
result += keys.join(columnDelimiter);
103+
result += lineDelimiter;
104+
105+
mergedData.forEach(function (item) {
106+
ctr = 0;
107+
keys.forEach(function (key) {
108+
if (ctr > 0) result += columnDelimiter;
109+
result += (typeof (item[key]) != undefined ? item[key] : "");
110+
ctr++;
111+
});
112+
result += lineDelimiter;
113+
});
114+
return result;
115+
}
116+
117+
function parseCSV(args) {
118+
var csv = "";
119+
120+
csv += convertChartDataToCSV({
121+
data: args.chart.options.data
122+
});
123+
124+
if (csv == null) return;
125+
var filename = args.filename || 'chart-data.csv';
126+
if (!csv.match(/^data:text\/csv/i)) {
127+
csv = 'data:text/csv;charset=utf-8,' + csv;
128+
}
129+
downloadFile(csv, filename);
130+
}
131+
132+
function downloadFile(extData, filename) {
133+
var data = encodeURI(extData);
134+
var link = document.createElement('a');
135+
link.setAttribute('href', data);
136+
link.setAttribute('download', filename);
137+
document.body.appendChild(link); // Required for FF
138+
link.click();
139+
document.body.removeChild(link);
140+
}
141+
142+
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
143+
module.exports = CanvasJSDataAsCSV;
144+
} else {
145+
if (typeof define === 'function' && define.amd) {
146+
define([], function () {
147+
return CanvasJSDataAsCSV;
148+
});
149+
} else {
150+
window.CanvasJSDataAsCSV = CanvasJSDataAsCSV;
151+
}
152+
}
153+
})();

0 commit comments

Comments
 (0)