UNPKG

zazu-app-bubble-chart

Version:
148 lines (113 loc) 3.79 kB
module.exports = BubbleChartApp; var q = require('q'), debug = require('debug')('zazu:app:bubble-chart'), util = require('util'), csvParse = require('csv-parse'); function BubbleChartApp(config, router) { if (!config.limit) { config.limit = 10; } this.config = config; this.dataCache = null; this.request = require('request').defaults({ auth: config.authUser && config.authPass ? { user: config.authUser, pass: config.authPass }: null, headers: { 'Accept': 'text/' + config.fileFormat } }); router.get('/config', function (req, res) { return res.json({ reloadInterval: config.reloadInterval }); }); var func; switch(config.fileFormat) { case 'csv': func = this.getCsv; break; case 'json': func = this.getJson; break; default: throw new Error(util.format('Invalid fileFormat "%s"', config.fileFormat)); } router.get('/data', func.bind(this)); this.interval = setInterval(this.reloadData.bind(this), config.reloadInterval || 600000); } BubbleChartApp.prototype.reloadData = function () { return q.Promise(function (resolve, reject) { this.request.get(this.config.fileUrl, function (error, response, body) { if (error) { return reject(error); } this.dataCache = body; resolve(body); }.bind(this)); }.bind(this)); }; BubbleChartApp.prototype.getData = function () { return q.Promise(function (resolve, reject) { if (this.dataCache) { resolve(this.dataCache); } else { this.reloadData().then(resolve, reject); } }.bind(this)); }; BubbleChartApp.prototype.getCsv = function (req, res) { this.getData().then(function (data) { debug('Got data: ', data); csvParse(data, {delimiter: this.config.delimiter, comment: '#'}, function (err, data) { if (err) { res.status(500).send(err); } if (!data) { return res.status(404).send('no data returned'); } debug('Parsed data: ', data); res.json(this.formatData(data)); }.bind(this)); }.bind(this), function (error) { res.status(500).send(error.toString()); }.bind(this)); }; BubbleChartApp.prototype.getJson = function (req, res) { this.getData().then(function (data) { debug('Got data: ', data); try { var parsed = JSON.parse(data); } catch (e) { res.status(500).send(e.toString()); } debug('Parsed data: ', parsed); if (!parsed) { return res.status(404).send('no data returned'); } res.json(this.formatData(parsed)); }.bind(this), function (error) { res.status(500).send(error.toString()); }.bind(this)); }; BubbleChartApp.prototype.formatData = function (data) { var result = []; data.forEach(function (row, index) { if (this.config.firstLineContainHeader && index === 0 || this.config.lastLineContainSum && index === data.length - 1) { return; } result.push({ key: row[this.config.labelKey], values: [{ x: this.parseFloat(row[this.config.xKey]), y: this.parseFloat(row[this.config.yKey]), size: this.parseFloat(row[this.config.zKey]) }] }); }.bind(this)); return result; }; BubbleChartApp.prototype.parseFloat = function (val) { return parseFloat(val.toString().replace(/[^0-9\.]+/g, '').replace(/\s/g,'')); };