diff options
author | Dan McGee <dan@archlinux.org> | 2012-11-10 17:09:51 -0600 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-11-11 14:36:14 -0600 |
commit | a358e132886972dc4e9f1f546e36a5f3a2218a39 (patch) | |
tree | 5443b12922e987f9a9afee5492703cbdce516e13 /mirrors | |
parent | aeeb4718e83cd2f82d94b1aa0c0ba36ba21a2b37 (diff) |
Mirror status graph, now with points AND lines
We might have to tweak the interpolation method once we see this with
real data, but for now it looks really pretty locally.
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'mirrors')
-rw-r--r-- | mirrors/static/mirror_status.js | 58 | ||||
-rw-r--r-- | mirrors/views.py | 3 |
2 files changed, 44 insertions, 17 deletions
diff --git a/mirrors/static/mirror_status.js b/mirrors/static/mirror_status.js index 277d3c88..d107d7d1 100644 --- a/mirrors/static/mirror_status.js +++ b/mirrors/static/mirror_status.js @@ -6,7 +6,7 @@ function mirror_status(chart_id, data_url) { width = jq_div.width() - margin.left - margin.right, height = jq_div.height() - margin.top - margin.bottom; - var color = d3.scale.category20(), + var color = d3.scale.category10(), x = d3.time.scale.utc().range([0, width]), y = d3.scale.linear().range([height, 0]), x_axis = d3.svg.axis().scale(x).orient("bottom"), @@ -20,8 +20,14 @@ function mirror_status(chart_id, data_url) { .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - x.domain(d3.extent(data, function(d) { return d.check_time; })).nice(d3.time.hour); - y.domain(d3.extent(data, function(d) { return d.duration; })).nice(); + x.domain([ + d3.min(data, function(c) { return d3.min(c.logs, function(v) { return v.check_time; }); }), + d3.max(data, function(c) { return d3.max(c.logs, function(v) { return v.check_time; }); }) + ]); + y.domain([ + d3.min(data, function(c) { return d3.min(c.logs, function(v) { return v.duration; }); }), + d3.max(data, function(c) { return d3.max(c.logs, function(v) { return v.duration; }); }) + ]); /* build the axis lines... */ svg.append("g") @@ -46,12 +52,32 @@ function mirror_status(chart_id, data_url) { .style("text-anchor", "end") .text("Duration (seconds)"); - /* ...then the points themselves. */ - svg.selectAll(".dot") + var line = d3.svg.line() + .interpolate("basis") + .x(function(d) { return x(d.check_time); }) + .y(function(d) { return y(d.duration); }); + + /* ...then the points and lines between them. */ + var urls = svg.selectAll(".url") .data(data) .enter() + .append("g") + .attr("class", "url"); + + urls.append("path") + .attr("class", "url-line") + .attr("d", function(d) { return line(d.logs); }) + .style("stroke", function(d) { return color(d.url); }); + + urls.selectAll("circle") + .data(function(u) { + return jQuery.map(u.logs, function(l, i) { + return {url: u.url, check_time: l.check_time, duration: l.duration}; + }); + }) + .enter() .append("circle") - .attr("class", "dot") + .attr("class", "url-dot") .attr("r", 3.5) .attr("cx", function(d) { return x(d.check_time); }) .attr("cy", function(d) { return y(d.duration); }) @@ -81,16 +107,16 @@ function mirror_status(chart_id, data_url) { /* invoke the data-fetch + first draw */ var cached_data = null; d3.json(data_url, function(json) { - cached_data = jQuery.map(json['urls'], - function(url, i) { - return jQuery.map(url['logs'], - function(log, j) { - return { - url: url['url'], - duration: log['duration'], - check_time: new Date(log['check_time']) - }; - }); + cached_data = jQuery.map(json.urls, function(url, i) { + return { + url: url.url, + logs: jQuery.map(url.logs, function(log, j) { + return { + duration: log.duration, + check_time: new Date(log.check_time) + }; + }) + }; }); draw_graph(cached_data); }); diff --git a/mirrors/views.py b/mirrors/views.py index 4b9721dc..be01e919 100644 --- a/mirrors/views.py +++ b/mirrors/views.py @@ -267,7 +267,8 @@ class ExtendedMirrorStatusJSONEncoder(MirrorStatusJSONEncoder): if isinstance(obj, MirrorUrl): data = super(ExtendedMirrorStatusJSONEncoder, self).default(obj) cutoff = now() - DEFAULT_CUTOFF - data['logs'] = obj.logs.filter(check_time__gte=cutoff) + data['logs'] = obj.logs.filter( + check_time__gte=cutoff).order_by('check_time') return data if isinstance(obj, MirrorLog): data = dict((attr, getattr(obj, attr)) |