zazu-app-bubble-chart
Version:
A bubble chart app for zazu dashboard engine
148 lines (113 loc) • 3.79 kB
JavaScript
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,''));
};