var ajax_site = 'ajax';
var refresh_rate = 3000;
var send_timeout = 20000;
var retry_rate = 3000;
function Blocker(sleeper) {
this.counter = 0;
this.waiting = false;
this.sleeper = sleeper;
}
Blocker.prototype.setHook = function() {
var blocker = this;
return function() {
blocker.counter++;
}
}
Blocker.prototype.setNotifier = function(cb) {
var blocker = this;
return function() {
cb.apply(this, arguments);
if (--blocker.counter == 0 && blocker.waiting)
blocker.sleeper();
}
};
Blocker.prototype.go = function() {
if (this.counter == 0)
this.sleeper();
this.waiting = true;
}
function send_request(on_success) {
$.ajax({
url: ajax_site,
type: 'GET',
cache: false,
dataType: 'json',
async: true,
success: on_success,
timeout: send_timeout,
error: function(a, b, c) {
console.log("failed while connecting, reason: " + b);
setTimeout(function() {
send_request(on_success);
}, retry_rate);
}
});
}
function hex(x) {
return ("0" + parseInt(x).toString(16)).slice(-2);
}
function random_range(min, max) {
return Math.random() * (max - min) + min;
}
function random_color() {
var r = (random_range(0, 200) + 150) / 2;
var g = (random_range(0, 200) + 150) / 2;
var b = (random_range(0, 200) + 150) / 2;
return "#" + hex(r) + hex(g) + hex(b);
}
function LineGraph() {}
LineGraph.prototype.recalc_y_domain = function(data) {
var min = d3.min(data, function(d) { return d.y; });
var max = d3.max(data, function(d) { return d.y; });
var delta = max - min;
this.y.domain([min - delta / 2.0, max + delta / 3.0]);
}
LineGraph.prototype.recalc_domain = function(data) {
this.x.domain(d3.extent(data, function(d) { return d.x; }));
this.recalc_y_domain(data);
}
LineGraph.prototype.parse_data = function(d) {
var data = [];
for (var i = 0; i < d.records.length; i++)
{
var rec = d.records[i];
data.push({x: i, y: +rec.rec[0], rid: rec.rid});
}
return data;
}
LineGraph.prototype.update = function(d, i, b) {
var graph = this;
var data = this.parse_data(d);
if (data.length == 0) return;
var pdata = this.pdata;
var svg = d3.select(this.elem).select("svg");
var path = svg.select(".line");
var shift = pdata.length ? data[0].rid - pdata[0].rid : 0;
var add = pdata.length ? data[data.length - 1].rid - pdata[pdata.length - 1].rid : 0;
if (pdata.length == 0 || pdata[pdata.length - 1].rid < data[0].rid ||
pdata[0] > data[data.length - 1].rid || shift < 0 || add < 0)
{
if (data.length == 1)
{
data = [];
console.log("clear");
}
this.recalc_domain(data);
path.transition()
.duration(200)
.style("opacity", 1e-6)
.transition()
.attr("d", graph.valueline(data))
.transition()
.duration(200)
.style("opacity", 1)
.each(b.setHook())
.each("end", b.setNotifier(function() {
graph.pdata = data;
console.log("refresh complete");
}));
console.log("refresh started");
}
else
{
this.recalc_domain(pdata);
//console.log("shift: " + shift + "add: " + add);
data = this.pdata.concat(data.slice(data.length - add, data.length));
for (var i = 0; i < data.length; i++)
data[i].x = i;
this.recalc_y_domain(data);
path.transition().duration(750)
.attr("d", graph.valueline(data))
.transition()
.duration(750)
.attr("transform", "translate(" + this.x(-shift) + ")")
.each(b.setHook())
.each("end", b.setNotifier(function() {
for (var i = 0; i < shift; i++)
data.shift();
for (var i = 0; i < data.length; i++)
data[i].x = i;
graph.pdata = data;
d3.select(this).attr("d", graph.valueline(data))
.attr("transform", "translate(" + graph.x(0) + ")");
}));
}
svg.transition()
.duration(750)
.select(".x.axis")
.call(this.xAxis);
svg.transition()
.duration(750)
.select(".y.axis")
.call(this.yAxis);
}
LineGraph.prototype.setup = function(elem, d, i, b) {
var graph = this;
var data = this.parse_data(d);
this.elem = elem;
var margin = {top: 10, right: 0, bottom: 50, left: 30};
// Adds the svg canvas
var svg = d3.select(this.elem)
.append("svg")
.attr("width", "100%")
.attr("height", "100%")
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var width = 500 - margin.left - margin.right;
var height = 250 - margin.top - margin.bottom;
// Set the ranges
this.x = d3.scale.linear().range([0, width]);
this.y = d3