Initial checkin.

This commit is contained in:
Ian Gulliver
2016-01-24 22:16:49 -08:00
parent 5fd0d0768e
commit 65c37d7a9a
8 changed files with 1322 additions and 0 deletions

175
console/console.js Normal file
View File

@@ -0,0 +1,175 @@
var Console = function(container) {
this.container_ = container;
this.client_ = new TSDBClient();
this.loadJSAPI_();
};
Console.prototype.loadJSAPI_ = function() {
google.load('visualization', '1.1', {
packages: ['corechart'],
callback: this.jsapiLoaded_.bind(this),
});
};
Console.prototype.jsapiLoaded_ = function() {
var exprContainer = document.createElement('div');
exprContainer.className = 'expr';
this.container_.appendChild(exprContainer);
var form = document.createElement('form');
exprContainer.appendChild(form);
this.exprInput_ = document.createElement('input');
form.appendChild(this.exprInput_);
form.addEventListener('submit', this.onExprChange_.bind(this));
var chartContainer = document.createElement('div');
this.container_.appendChild(chartContainer);
this.charts_ = [
{
'title': 'Last 20 minutes',
'seconds': 120 * 10,
'resolution': 'full',
},
{
'title': 'Last 2 hours',
'seconds': 120 * 60,
'resolution': 'minute',
},
{
'title': 'Last 5 days',
'seconds': 120 * 60 * 60,
'resolution': 'hour',
},
{
'title': 'Last 120 days',
'seconds': 120 * 60 * 60 * 24,
'resolution': 'day',
},
];
for (var i = 0; i < this.charts_.length; i++) {
var obj = this.charts_[i];
obj.container = document.createElement('div');
obj.container.className = 'chart';
chartContainer.appendChild(obj.container);
}
this.expr_ = decodeURIComponent(window.location.hash.substring(1));
// Ensure that the URL is properly encoded for copy & paste.
window.location.hash = encodeURIComponent(this.expr_);
this.exprInput_.value = this.expr_;
window.addEventListener('hashchange', this.onHashChange_.bind(this));
this.loadCharts_();
};
Console.prototype.onExprChange_ = function(e) {
window.location.hash = encodeURIComponent(this.exprInput_.value);
e.preventDefault();
};
Console.prototype.onHashChange_ = function(e) {
this.expr_ = decodeURIComponent(window.location.hash.substring(1));
this.exprInput_.value = this.expr_;
this.loadCharts_();
};
Console.prototype.loadCharts_ = function() {
if (!this.expr_) {
return;
}
for (var i = 0; i < this.charts_.length; i++) {
var options = this.charts_[i];
if (options.instance) {
options.instance.destroy();
}
options.instance = new Chart(this.client_, this.expr_, options);
}
};
var Chart = function(client, expr, options) {
this.options_ = options;
this.watch_ = client.watch(
expr, this.options_.seconds, this.options_.resolution,
this.drawChart_.bind(this));
};
Chart.prototype.drawChart_ = function(data) {
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('date', 'Timestamp');
for (var i = data.length - 1; i >= 0; i--) {
var ts = data[i];
if (!ts.timestamps_values.length) {
data.splice(i, 1);
continue;
}
var tags = [];
for (var key in ts.tags) {
tags.push(key + '=' + ts.tags[key]);
}
dataTable.addColumn('number', tags.join(','));
}
for (var i = 0; i < data.length; i++) {
var ts = data[i];
for (var j = 0; j < ts.timestamps_values.length; j++) {
var row = [new Date(ts.timestamps_values[j][0] * 1000)];
for (var k = 0; k < i; k++) {
row.push(null);
}
row.push(ts.timestamps_values[j][1]);
for (var k = i + 1; k < data.length; k++) {
row.push(null);
}
dataTable.addRow(row);
}
};
var options = {
title: this.options_.title,
legend: {
position: 'bottom'
},
hAxis: {
gridlines: {
count: -1,
},
},
explorer: {
actions: [
'dragToZoom',
'rightClickToReset',
],
},
};
// It'd be great to use the material design charts here, but they fail to load
// ~25% of the time, which is a non-starter.
if (this.chartObj_) {
this.chartObj_.clearChart();
}
this.chartObj_ = new google.visualization.LineChart(this.options_.container);
this.chartObj_.draw(dataTable, options);
};
Chart.prototype.destroy = function() {
this.watch_.destroy();
if (this.chartObj_) {
this.chartObj_.clearChart();
}
};
document.addEventListener('DOMContentLoaded', function(e) {
new Console(document.getElementById('container'));
});