UNPKG

billboard.js

Version:

Re-usable easy interface JavaScript chart library, based on D3 v4+

167 lines (166 loc) • 4.17 kB
/*! * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license * * billboard.js, JavaScript chart library * https://naver.github.io/billboard.js/ * * @version 4.1.1 */ import { csvParse, csvParseRows, tsvParse, tsvParseRows } from "../../module/dsv.js"; //#region src/ChartInternal/data/convert.helper.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /***** Functions to be executed on Web Worker ***** * NOTE: Don't allowed to use * - arrow function syntax * - Utils functions */ /** * Convert Columns data * @param {object} columns * @returns {Array} * @private */ function columns(columns) { const newRows = []; columns.forEach(function(col, i) { const key = col[0]; col.forEach(function(v, j) { if (j > 0) { if (typeof newRows[j - 1] === "undefined") newRows[j - 1] = {}; if (typeof v === "undefined") throw new Error(`Source data is missing a component at (${i}, ${j})!`); newRows[j - 1][key] = v; } }); }); return newRows; } /** * Convert Rows data * @param {object} columns * @returns {Array} * @private */ function rows(rows) { const keys = rows[0]; const newRows = []; rows.forEach(function(row, i) { if (i > 0) { const newRow = {}; row.forEach(function(v, j) { if (typeof v === "undefined") throw new Error(`Source data is missing a component at (${i}, ${j})!`); newRow[keys[j]] = v; }); newRows.push(newRow); } }); return newRows; } /** * Convert JSON data * @param {object} columns * @returns {Array} * @private */ function json(json, keysParam) { const newRows = []; let targetKeys; let data; if (Array.isArray(json)) { const findValueInJson = function(object, path) { if (object[path] !== void 0) return object[path]; const pathArray = path.replace(/\[(\w+)\]/g, ".$1").replace(/^\./, "").split("."); let target = object; pathArray.some(function(k) { return !(target = target && typeof target === "object" && k in target ? target[k] : void 0); }); return target; }; if (keysParam.x) targetKeys = keysParam.value.concat(keysParam.x); else targetKeys = keysParam.value; newRows.push(targetKeys); json.forEach(function(o) { const newRow = targetKeys.map(function(key) { let v = findValueInJson(o, key); if (typeof v === "undefined") v = null; return v; }); newRows.push(newRow); }); data = rows(newRows); } else { Object.keys(json).forEach(function(key) { const tmp = [].concat(json[key]); tmp.unshift?.(key); newRows.push(tmp); }); data = columns(newRows); } return data; } /***** Functions can't be executed on Web Worker *****/ /** * Convert URL data * @param {string} url Remote URL * @param {string} mimeType MIME type string: json | csv | tsv * @param {object} headers Header object * @param {object} keys Key object * @param {function} done Callback function * @private */ function url(url, mimeType = "csv", headers, keys, done) { const req = new XMLHttpRequest(); const converter = { csv, tsv, json }; req.open("GET", url); if (headers) Object.keys(headers).forEach(function(key) { req.setRequestHeader(key, headers[key]); }); req.onreadystatechange = function() { if (req.readyState === 4) { if (req.status === 200) { const response = req.responseText; response && done.call(this, converter[mimeType](mimeType === "json" ? JSON.parse(response) : response, keys)); } else throw new Error(`${url}: Something went wrong loading!`); } }; req.send(); } /** * Convert CSV/TSV data * @param {object} parser Parser object * @param {object} xsv Data * @returns {object} * @private */ function convertCsvTsvToData(parser, xsv) { const rows = parser.rows(xsv); let d; if (rows.length === 1) { d = [{}]; rows[0].forEach((id) => { d[0][id] = null; }); } else d = parser.parse(xsv); return d; } function csv(xsv) { return convertCsvTsvToData({ rows: csvParseRows, parse: csvParse }, xsv); } function tsv(tsv) { return convertCsvTsvToData({ rows: tsvParseRows, parse: tsvParse }, tsv); } //#endregion export { columns, csv, json, rows, tsv, url };