diff options
-rw-r--r-- | index.pl | 17 | ||||
-rw-r--r-- | public/css/default.css | 5 | ||||
-rw-r--r-- | public/js/d3funcs.js | 35 |
3 files changed, 50 insertions, 7 deletions
@@ -321,7 +321,7 @@ get '/2ddata.tsv' => sub { my $where_clause = '1 = 1'; my $join_clause = q{}; - my $res = "x\ty\ty_total\ty_stddev\ty_matched\n"; + my $res; my $query; my $format = 'extract(hour from scheduled_time at time zone \'GMT\')'; @@ -354,6 +354,7 @@ get '/2ddata.tsv' => sub { given ($metric) { when ('avg_delay') { + $res = "x\ty\ty_total\ty_stddev\n"; $query = qq{ select $format as aggregate, avg(delay), count(delay), stddev_samp(delay) @@ -365,6 +366,7 @@ get '/2ddata.tsv' => sub { }; } when ('cancel_num') { + $res = "x\ty\ty_total\n"; $query = qq{ select $format as aggregate, count(*), count(*) from departures @@ -375,9 +377,10 @@ get '/2ddata.tsv' => sub { }; } when ('cancel_rate') { + $res = "x\ty\ty_total\ty_matched\n"; $query = qq{ select $format as aggregate, avg(is_canceled::int), count(is_canceled), - stddev_samp(is_canceled::int), sum(is_canceled::int) + sum(is_canceled::int) from departures $join_clause where $where_clause @@ -386,9 +389,10 @@ get '/2ddata.tsv' => sub { }; } when ('delay0_rate') { + $res = "x\ty\ty_total\ty_matched\n"; $query = qq{ select $format as aggregate, avg((delay < 1)::int), count(delay), - stddev_samp((delay < 1)::int), sum((delay < 1)::int) + sum((delay < 1)::int) from departures $join_clause where $where_clause @@ -397,9 +401,10 @@ get '/2ddata.tsv' => sub { }; } when ('delay5_rate') { + $res = "x\ty\ty_total\ty_matched\n"; $query = qq{ select $format as aggregate, avg((delay > 5)::int), count(delay), - stddev_samp((delay < 1)::int), sum((delay > 5)::int) + sum((delay > 5)::int) from departures $join_clause where $where_clause @@ -408,10 +413,10 @@ get '/2ddata.tsv' => sub { }; } when ('message_rate') { + $res = "x\ty\ty_total\ty_matched\n"; $query = qq{ select $format as aggregate, avg((msgtable.train_id is not null)::int), count(*), - stddev_samp((msgtable.train_id is not null)::int), sum((msgtable.train_id is not null)::int) from departures $join_clause @@ -422,10 +427,10 @@ get '/2ddata.tsv' => sub { }; } when ('realtime_rate') { + $res = "x\ty\ty_total\ty_matched\n"; $query = qq{ select $format as aggregate, avg((delay is not null)::int), count(*), - stddev_samp((delay is not null)::int), sum((delay is not null)::int) from departures $join_clause diff --git a/public/css/default.css b/public/css/default.css index cdbcf82..974e421 100644 --- a/public/css/default.css +++ b/public/css/default.css @@ -65,6 +65,11 @@ arc path { fill: orange; } +.stddev { + stroke: #000; + shape-rendering: crispEdges; +} + .bar:hover { fill: orangered ; } diff --git a/public/js/d3funcs.js b/public/js/d3funcs.js index fb50345..50a95f2 100644 --- a/public/js/d3funcs.js +++ b/public/js/d3funcs.js @@ -25,6 +25,8 @@ show_bargraph = function(datasource, title, xLabel, yLabel, yFormat, width, heig .scale(y) .orient("left"); + var stddev_fact = 5; + if (yFormat) { yAxis = yAxis.tickFormat(d3.format(yFormat)); } @@ -54,7 +56,7 @@ show_bargraph = function(datasource, title, xLabel, yLabel, yFormat, width, heig if (error) console.warn(error); x.domain(data.map(function(d) { return d.x; })); y.domain([0, d3.max(data, function(d) { return d.y; })]); - + svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") @@ -93,6 +95,37 @@ show_bargraph = function(datasource, title, xLabel, yLabel, yFormat, width, heig .attr("height", function(d) { return height - y(d.y); }) .on('mouseover', tip.show) .on('mouseout', tip.hide) + + if (data[0].y_stddev !== undefined) { + svg.selectAll(".stddev") + .data(data) + .enter().append("line") + .attr("class", "stddev") + .attr("x1", function(d) { return x(d.x) + x.rangeBand() / 2; }) + .attr("x2", function(d) { return x(d.x) + x.rangeBand() / 2; }) + .attr("y1", function(d) { return y(d.y) - y(d.y_stddev); }) + .attr("y2", function(d) { return y(d.y) + y(d.y_stddev); }) + .attr("stroke-width", 1) + svg.selectAll(".placeholder") + .data(data) + .enter().append("line") + .attr("class", "stddev") + .attr("x1", function(d) { return x(d.x) + x.rangeBand() / 2 - 4; }) + .attr("x2", function(d) { return x(d.x) + x.rangeBand() / 2 + 3; }) + .attr("y1", function(d) { return y(d.y) - y(d.y_stddev); }) + .attr("y2", function(d) { return y(d.y) - y(d.y_stddev); }) + .attr("stroke-width", 1) + svg.selectAll(".placeholder") + .data(data) + .enter().append("line") + .attr("class", "stddev") + .attr("x1", function(d) { return x(d.x) + x.rangeBand() / 2 - 4; }) + .attr("x2", function(d) { return x(d.x) + x.rangeBand() / 2 + 3; }) + .attr("y1", function(d) { return y(d.y) + y(d.y_stddev); }) + .attr("y2", function(d) { return y(d.y) + y(d.y_stddev); }) + .attr("stroke-width", 1) + } + }); |