├── LICENSE ├── README.md ├── bower.json ├── export-csv.js ├── manifest.json └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2017 Highsoft 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deprecation notice 2 | Given the popularity of this plugin, it has been taken in as a Highcharts module since v5.0.11 (2017-05-04), and 3 | development continues in the [official Highcharts repo](https://github.com/highcharts/highcharts/). This 4 | means it can be loaded from [code.highcharts.com](https://code.highcharts.com/modules/export-data.js) and 5 | is available with the [Highcharts npm package](https://www.npmjs.com/package/highcharts). Issues should now 6 | be reported in the [Highcharts repo](https://github.com/highcharts/highcharts/issues). 7 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "highcharts-export-csv", 3 | "version": "1.4.8", 4 | "description": "Highcharts plugin to export the chart data to CSV, XLS or HTML table", 5 | "keywords": [ 6 | "export", 7 | "csv", 8 | "xls" 9 | ], 10 | "authors": [ 11 | { "name": "Torstein Hønsi", "homepage": "https://github.com/highslide-software" } 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/highcharts/export-csv" 16 | }, 17 | "main": "export-csv.js", 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "README.md" 22 | ], 23 | "homepage": "http://www.highcharts.com/plugin-registry/single/7/Export-CSV" 24 | } 25 | -------------------------------------------------------------------------------- /export-csv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A Highcharts plugin for exporting data from a rendered chart as CSV, XLS or HTML table 3 | * 4 | * Author: Torstein Honsi 5 | * Licence: MIT 6 | * Version: 1.4.8 7 | */ 8 | /*global Highcharts, window, document, Blob */ 9 | (function (factory) { 10 | if (typeof module === 'object' && module.exports) { 11 | module.exports = factory; 12 | } else { 13 | factory(Highcharts); 14 | } 15 | })(function (Highcharts) { 16 | 17 | 'use strict'; 18 | 19 | var each = Highcharts.each, 20 | pick = Highcharts.pick, 21 | seriesTypes = Highcharts.seriesTypes, 22 | downloadAttrSupported = document.createElement('a').download !== undefined; 23 | 24 | Highcharts.setOptions({ 25 | lang: { 26 | downloadCSV: 'Download CSV', 27 | downloadXLS: 'Download XLS', 28 | viewData: 'View data table' 29 | } 30 | }); 31 | 32 | 33 | /** 34 | * Get the data rows as a two dimensional array 35 | */ 36 | Highcharts.Chart.prototype.getDataRows = function () { 37 | var options = (this.options.exporting || {}).csv || {}, 38 | xAxis, 39 | xAxes = this.xAxis, 40 | rows = {}, 41 | rowArr = [], 42 | dataRows, 43 | names = [], 44 | i, 45 | x, 46 | xTitle, 47 | // Options 48 | dateFormat = options.dateFormat || '%Y-%m-%d %H:%M:%S', 49 | columnHeaderFormatter = options.columnHeaderFormatter || function (item, key, keyLength) { 50 | if (item instanceof Highcharts.Axis) { 51 | return (item.options.title && item.options.title.text) || 52 | (item.isDatetimeAxis ? 'DateTime' : 'Category'); 53 | } 54 | return item ? 55 | item.name + (keyLength > 1 ? ' ('+ key + ')' : '') : 56 | 'Category'; 57 | }, 58 | xAxisIndices = []; 59 | 60 | // Loop the series and index values 61 | i = 0; 62 | each(this.series, function (series) { 63 | var keys = series.options.keys, 64 | pointArrayMap = keys || series.pointArrayMap || ['y'], 65 | valueCount = pointArrayMap.length, 66 | requireSorting = series.requireSorting, 67 | categoryMap = {}, 68 | xAxisIndex = Highcharts.inArray(series.xAxis, xAxes), 69 | j; 70 | 71 | // Map the categories for value axes 72 | each(pointArrayMap, function (prop) { 73 | categoryMap[prop] = (series[prop + 'Axis'] && series[prop + 'Axis'].categories) || []; 74 | }); 75 | 76 | if (series.options.includeInCSVExport !== false && series.visible !== false) { // #55 77 | 78 | // Build a lookup for X axis index and the position of the first 79 | // series that belongs to that X axis. Includes -1 for non-axis 80 | // series types like pies. 81 | if (!Highcharts.find(xAxisIndices, function (index) { 82 | return index[0] === xAxisIndex; 83 | })) { 84 | xAxisIndices.push([xAxisIndex, i]); 85 | } 86 | 87 | // Add the column headers, usually the same as series names 88 | j = 0; 89 | while (j < valueCount) { 90 | names.push(columnHeaderFormatter(series, pointArrayMap[j], pointArrayMap.length)); 91 | j = j + 1; 92 | } 93 | 94 | each(series.points, function (point, pIdx) { 95 | var key = requireSorting ? point.x : pIdx, 96 | prop, 97 | val; 98 | 99 | j = 0; 100 | 101 | if (!rows[key]) { 102 | // Generate the row 103 | rows[key] = []; 104 | // Contain the X values from one or more X axes 105 | rows[key].xValues = []; 106 | } 107 | rows[key].x = point.x; 108 | rows[key].xValues[xAxisIndex] = point.x; 109 | 110 | // Pies, funnels, geo maps etc. use point name in X row 111 | if (!series.xAxis || series.exportKey === 'name') { 112 | rows[key].name = point.name; 113 | } 114 | 115 | while (j < valueCount) { 116 | prop = pointArrayMap[j]; // y, z etc 117 | val = point[prop]; 118 | rows[key][i + j] = pick(categoryMap[prop][val], val); // Pick a Y axis category if present 119 | j = j + 1; 120 | } 121 | 122 | }); 123 | i = i + j; 124 | } 125 | }); 126 | 127 | // Make a sortable array 128 | for (x in rows) { 129 | if (rows.hasOwnProperty(x)) { 130 | rowArr.push(rows[x]); 131 | } 132 | } 133 | 134 | var binding, xAxisIndex, column; 135 | dataRows = [names]; 136 | 137 | i = xAxisIndices.length; 138 | while (i--) { // Start from end to splice in 139 | xAxisIndex = xAxisIndices[i][0]; 140 | column = xAxisIndices[i][1]; 141 | xAxis = xAxes[xAxisIndex]; 142 | 143 | // Sort it by X values 144 | rowArr.sort(function (a, b) { 145 | return a.xValues[xAxisIndex] - b.xValues[xAxisIndex]; 146 | }); 147 | 148 | // Add header row 149 | xTitle = columnHeaderFormatter(xAxis); 150 | //dataRows = [[xTitle].concat(names)]; 151 | dataRows[0].splice(column, 0, xTitle); 152 | 153 | // Add the category column 154 | each(rowArr, function (row) { 155 | 156 | var category = row.name; 157 | if (!category) { 158 | if (xAxis.isDatetimeAxis) { 159 | if (row.x instanceof Date) { 160 | row.x = row.x.getTime(); 161 | } 162 | category = Highcharts.dateFormat(dateFormat, row.x); 163 | } else if (xAxis.categories) { 164 | category = pick( 165 | xAxis.names[row.x], 166 | xAxis.categories[row.x], 167 | row.x 168 | ) 169 | } else { 170 | category = row.x; 171 | } 172 | } 173 | 174 | // Add the X/date/category 175 | row.splice(column, 0, category); 176 | }); 177 | } 178 | dataRows = dataRows.concat(rowArr); 179 | 180 | return dataRows; 181 | }; 182 | 183 | /** 184 | * Get a CSV string 185 | */ 186 | Highcharts.Chart.prototype.getCSV = function (useLocalDecimalPoint) { 187 | var csv = '', 188 | rows = this.getDataRows(), 189 | options = (this.options.exporting || {}).csv || {}, 190 | itemDelimiter = options.itemDelimiter || ',', // use ';' for direct import to Excel 191 | lineDelimiter = options.lineDelimiter || '\n'; // '\n' isn't working with the js csv data extraction 192 | 193 | // Transform the rows to CSV 194 | each(rows, function (row, i) { 195 | var val = '', 196 | j = row.length, 197 | n = useLocalDecimalPoint ? (1.1).toLocaleString()[1] : '.'; 198 | while (j--) { 199 | val = row[j]; 200 | if (typeof val === "string") { 201 | val = '"' + val + '"'; 202 | } 203 | if (typeof val === 'number') { 204 | if (n === ',') { 205 | val = val.toString().replace(".", ","); 206 | } 207 | } 208 | row[j] = val; 209 | } 210 | // Add the values 211 | csv += row.join(itemDelimiter); 212 | 213 | // Add the line delimiter 214 | if (i < rows.length - 1) { 215 | csv += lineDelimiter; 216 | } 217 | }); 218 | return csv; 219 | }; 220 | 221 | /** 222 | * Build a HTML table with the data 223 | */ 224 | Highcharts.Chart.prototype.getTable = function (useLocalDecimalPoint) { 225 | var html = '