diff --git a/website/awfy.js b/website/awfy.js
index d5f32fb..f4de1f9 100644
--- a/website/awfy.js
+++ b/website/awfy.js
@@ -9,8 +9,7 @@ AWFY.hasLegend = false;
AWFY.panes = [];
AWFY.queryParams = {};
AWFY.aggregate = null;
-AWFY.drawLegend = function () {
-}
+AWFY.xhr = [];
AWFY.request = function (files, callback) {
var url = window.location.protocol + '//' +
@@ -22,11 +21,12 @@ AWFY.request = function (files, callback) {
var count = 0;
var received = new Array(files.length);
- function done(jqXHR, textStatus) {
+ var done = (function (jqXHR, textStatus) {
count++;
if (count == files.length)
callback(received);
- }
+ this.xhr.splice(this.xhr.lastIndexOf(jqXHR), 1);
+ }).bind(this);
for (var i = 0; i < files.length; i++) {
var success = (function (index) {
@@ -39,17 +39,14 @@ AWFY.request = function (files, callback) {
success: success,
cache: false
};
- $.ajax(url + files[i] + '.json', req);
+ this.xhr.push($.ajax(url + files[i] + '.json', req));
}
}
-AWFY.onQueryFail = function () {
- if (this.refresh)
- window.setTimeout(this.query.bind(this), this.refreshTime);
-}
-
-AWFY.computeAggregate = function (xhr) {
- var blob = JSON.parse(xhr.responseText);
+AWFY.computeAggregate = function (received) {
+ var blob = typeof received[0] == "string"
+ ? JSON.parse(received[0])
+ : received[0];
// Should we handle version changes better?
if (blob.version != AWFYMaster.version) {
@@ -109,9 +106,6 @@ AWFY.computeAggregate = function (xhr) {
Display.drawLegend();
this.hasLegend = true;
}
-
- if (this.refresh)
- window.setTimeout(this.query.bind(this), this.refreshTime);
}
AWFY.mergeJSON = function (blobs) {
@@ -308,36 +302,6 @@ AWFY.findX = function (graph, time) {
return i;
}
-AWFY.query = function (name, callback) {
- var url = window.location.protocol + '//' +
- window.location.host +
- window.location.pathname;
- if (url[url.length - 1] != '/')
- url += '/';
- url += 'data/' + name;
-
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- if (xhr.readyState != 4)
- return;
-
- if (xhr.status != 200) {
- AWFY.onQueryFail();
- return;
- }
-
- callback(xhr);
- };
- xhr.open('GET', url, true);
- xhr.send();
-}
-
-AWFY.onGraphHover = function (event, pos, item) {
- var elt = $(event.target);
- var display = elt.data('awfy-display');
- display.onHover(event, pos, item);
-}
-
AWFY.requestZoom = function (display, kind, start_t, end_t) {
// Figure out the list of dates we'll need to query.
var files = [];
@@ -368,6 +332,35 @@ AWFY.requestZoom = function (display, kind, start_t, end_t) {
this.request(files, zoom.bind(this));
}
+AWFY.changeMachine = function (machine_id) {
+ this.reset();
+ this.machineId = machine_id;
+ this.request(['aggregate-' + this.machineId],
+ this.computeAggregate.bind(this));
+}
+
+AWFY.reset = function () {
+ // Reset all our state to accept our new graphs.
+ for (var i = 0; i < AWFY.panes.length; i++) {
+ var id = this.panes[i];
+ var elt = $('#' + id + '-graph');
+ var display = elt.data('awfy-display');
+ if (!display)
+ continue;
+ display.shutdown();
+ elt.data('awfy-display', null);
+ elt.empty();
+ $('
Loading...
').appendTo(elt);
+ }
+
+ this.hasLegend = false;
+ this.aggregate = null;
+
+ for (var i = 0; i < this.xhr.length; i++)
+ this.xhr[i].abort();
+ this.xhr = [];
+}
+
AWFY.startup = function () {
var query = window.location.search.substring(1);
var items = query.split('&');
@@ -381,11 +374,55 @@ AWFY.startup = function () {
else
this.machineId = 11;
- for (var i = 0; i < this.panes.length; i++) {
- var id = this.panes[i];
- $('#' + id + '-graph').bind("plothover", this.onGraphHover.bind(this));
+ this.request(['aggregate-' + this.machineId],
+ this.computeAggregate.bind(this));
+
+ // Add machine information to the menu.
+ var menu = $('#machinelist');
+ for (var id in AWFYMaster.machines) {
+ var machine = AWFYMaster.machines[id];
+ var li = $('');
+ var a = $('');
+ a.click((function (id) {
+ return (function (event) {
+ this.changeMachine(parseInt(id));
+ $('.clicked').removeClass('clicked');
+ $(event.target).addClass('clicked');
+ return false;
+ }).bind(this)
+ }).bind(this)(id));
+ if (parseInt(id) == this.machineId)
+ a.addClass('clicked');
+ a.html(machine.description);
+ a.appendTo(li);
+ li.appendTo(menu);
}
- this.query('aggregate-' + this.machineId + '.json', this.computeAggregate.bind(this));
+ // Hide it by default.
+ $('#machinedrop').click((function (event) {
+ if (!menu.is(':visible') && !$('#about').is(':visible')) {
+ menu.show();
+ } else {
+ menu.hide();
+ }
+ return false;
+ }).bind(this));
+ menu.hide();
+
+ var about = $('#aboutdrop');
+ about.click((function (event) {
+ var help = $('#about');
+ if (!help.is(':visible')) {
+ $('.graph-container').hide();
+ help.show();
+ about.text('Home');
+ } else {
+ help.hide();
+ $('.graph-container').show();
+ about.text('About');
+ }
+ menu.hide();
+ return false;
+ }));
}
diff --git a/website/frontpage.js b/website/frontpage.js
index aec455b..2a76b55 100644
--- a/website/frontpage.js
+++ b/website/frontpage.js
@@ -7,27 +7,21 @@ function Display(awfy, id, elt, graph)
this.id = id;
this.graph = graph;
this.elt = elt;
- this.elt.data('awfy-display', this);
this.zoomInfo = { prev: null,
level: 'aggregate'
};
this.selectDelay = null;
this.attachedTips = [];
+ this.elt.data('awfy-display', this);
+
// The last hovering tooltip we displayed, that has not been clicked.
this.hovering = null;
- if (graph.aggregate) {
- // Find the range of historical points.
- for (var i = 0; i < graph.timelist.length; i++) {
- if (graph.timelist[i] >= graph.earliest)
- break;
- }
-
- if (i && i != graph.timelist.length)
- this.historical = i;
- }
+ if (graph.aggregate)
+ this.setHistoricalMidpoint();
+ this.elt.bind("plothover", this.onHover.bind(this));
this.elt.bind('plotclick', this.onClick.bind(this));
this.elt.bind('plotselected', this.plotSelected.bind(this));
this.elt.bind('dblclick', (function () {
@@ -39,6 +33,25 @@ function Display(awfy, id, elt, graph)
Display.MaxPoints = 50;
Display.Months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
+Display.prototype.shutdown = function () {
+ this.elt.unbind('plothover');
+ this.elt.unbind('plotclick');
+ this.elt.unbind('plotselected');
+ this.elt.unbind('dblclick');
+ this.detachTips();
+}
+
+Display.prototype.setHistoricalMidpoint = function () {
+ // Find the range of historical points.
+ for (var i = 0; i < this.graph.timelist.length; i++) {
+ if (this.graph.timelist[i] >= this.graph.earliest)
+ break;
+ }
+
+ if (i && i != this.graph.timelist.length)
+ this.historical = i;
+}
+
// Copy flot's tick algorithm.
Display.prototype.tickSize = function (min, max) {
var noTicks = 0.3 * Math.sqrt(this.elt.width());
@@ -305,6 +318,7 @@ Display.prototype.cancelZoom = function () {
Display.prototype.unzoom = function () {
this.graph = AWFY.aggregate[this.id];
+ this.setHistoricalMidpoint();
this.draw();
this.plot.enableSelection();
this.plot.clearSelection();
@@ -415,12 +429,12 @@ Display.prototype.createToolTip = function (item, extended) {
// Format a year, if we should.
if (extended) {
var current_year = (new Date()).getFullYear();
- var datefmt = function (t, forceYear) {
+ var datefmt = function (t, forceYear, omitTime) {
var d = new Date(t * 1000);
var text = Display.Months[d.getMonth()] + ' ' + d.getDate();
if (d.getFullYear() != current_year || forceYear)
text += ', ' + d.getFullYear();
- if (d.getHours() || d.getMinutes()) {
+ if (!omitTime && (d.getHours() || d.getMinutes())) {
text += ' ';
text += pad(d.getHours()) + ':' +
pad(d.getMinutes());
@@ -430,11 +444,11 @@ Display.prototype.createToolTip = function (item, extended) {
if (point.last && x < this.graph.timelist.length - 1) {
text += so + 'tested: ' + sc +
- datefmt(this.graph.timelist[x]) + ' to ' +
- datefmt(this.graph.timelist[x + 1], true) + '
';
+ datefmt(this.graph.timelist[x], false, true) + ' to ' +
+ datefmt(this.graph.timelist[x + 1], true, true) + '
';
} else {
text += so + 'tested: ' + sc +
- datefmt(this.graph.timelist[x]) + '
';
+ datefmt(this.graph.timelist[x], false, false) + '
';
}
} else {
// Include a short timestamp if we're looking at recent changesets.
@@ -462,7 +476,7 @@ Display.prototype.createToolTip = function (item, extended) {
else
text += ' ';
}
- if (this.graph.aggregate && x >= this.historical)
+ if (!this.graph.aggregate || x >= this.historical)
text += pad(d.getHours()) + ':' + pad(d.getMinutes()) + '
';
}
@@ -541,6 +555,8 @@ Display.drawLegend = function ()
{
var legend = $("#legend");
+ legend.empty();
+
for (var modename in AWFYMaster.modes) {
var mode = AWFYMaster.modes[modename];
var vendor = AWFYMaster.vendors[mode.vendor_id];
diff --git a/website/style.css b/website/style.css
index b8f2126..b318b99 100644
--- a/website/style.css
+++ b/website/style.css
@@ -29,9 +29,9 @@ h1 {
}
.tooltip {
- -moz-border-radius:.35em;
- -webkit-border-radius:.35em;
- border-radius: .35em;
+ -moz-border-radius:.5em;
+ -webkit-border-radius:.5em;
+ border-radius: .5em;
background-color:#000;
color:#FFF;
display:none;
@@ -64,20 +64,36 @@ h1 {
.tiptext {
background: #222;
- -moz-border-radius:.35em;
- -webkit-border-radius:.35em;
- border-radius: .35em;
+ -moz-border-radius:.5em;
+ -webkit-border-radius:.5em;
+ border-radius: .5em;
padding: 10px;
clear: both;
}
-#legend {
- text-align: left;
+#navcontainer {
padding-top: 360px;
- margin-left: -20px;
display: inline;
position: absolute;
+ margin-left: -20px;
left: 0;
+}
+
+.menu {
+ text-align: left;
+ list-style-type: none;
+}
+
+.menu li a {
+ text-decoration: none;
+}
+
+.menu li a:hover {
+ text-decoration: underline;
+}
+
+#legend {
+ text-align: left;
list-style-type: none;
}
@@ -89,3 +105,13 @@ h1 {
font-size: 1.2em;
}
+#about {
+ display: none;
+ margin-left: 200px;
+ width: 700px;
+}
+
+.clicked {
+ font-weight: bold;
+}
+