summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--index.pl17
-rw-r--r--public/css/default.css5
-rw-r--r--public/js/d3funcs.js35
3 files changed, 50 insertions, 7 deletions
diff --git a/index.pl b/index.pl
index 6e3df19..4c8c75a 100644
--- a/index.pl
+++ b/index.pl
@@ -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)
+ }
+
});