From caf02e60ae73ea48a3fc18bd30078247509a8d4b Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Fri, 20 Feb 2015 18:56:18 +0100 Subject: /o/ --- index.pl | 28 ++++---- templates/main.html.ep | 176 ++++++++++++++++++++++++++----------------------- 2 files changed, 109 insertions(+), 95 deletions(-) diff --git a/index.pl b/index.pl index 1d309e2..98011cd 100644 --- a/index.pl +++ b/index.pl @@ -50,36 +50,42 @@ get '/by_hour.json' => sub { return; }; -get '/by_hour.tsv' => sub { +get '/by_time.tsv' => sub { my $self = shift; + my $time = $self->param('time') // 'hour'; my $metric = $self->param('metric') // 'delay'; - my ( $query, $text ); + my $res = "x\ty\n"; + + my $query; + my $format = '%H'; + + if ($time eq 'weekday') { + $format = '%w'; + } given ($metric) { when ('delay') { - $text = "hour\tavgdelay\n"; $query = qq{ - select strftime("%H", scheduled_time, "unixepoch") as time, + select strftime("$format", scheduled_time, "unixepoch") as time, avg(delay) from $table group by time }; } when ('cancel_num') { - $text = "hour\tavgdelay\n"; $query = qq{ - select strftime("%H", scheduled_time, "unixepoch") as time, - avg(delay) as date from $table group by time + select strftime("$format", scheduled_time, "unixepoch") as time, + count(is_canceled) from $table group by time }; } } - my $res = $self->app->dbh->selectall_arrayref($query); + my $dbres = $self->app->dbh->selectall_arrayref($query); - for my $row ( @{$res} ) { - $text .= sprintf( "%s\t%s\n", @{$row} ); + for my $row ( @{$dbres} ) { + $res .= sprintf( "%s\t%s\n", @{$row} ); } - $self->render( data => $text ); + $self->render( data => $res ); return; }; diff --git a/templates/main.html.ep b/templates/main.html.ep index 6bca074..402b227 100644 --- a/templates/main.html.ep +++ b/templates/main.html.ep @@ -1,91 +1,99 @@ %= javascript begin -var margin = {top: 40, right: 20, bottom: 30, left: 40}, - width = 960 - margin.left - margin.right, - height = 500 - margin.top - margin.bottom; - -var formatPercent = d3.format(".0%"); - -var x = d3.scale.ordinal() - .rangeRoundBands([0, width], .1); - -var y = d3.scale.linear() - .range([height, 0]); - -var xAxis = d3.svg.axis() - .scale(x) - .orient("bottom"); - -var yAxis = d3.svg.axis() - .scale(y) - .orient("left"); -// .tickFormat(formatPercent); - -var tip = d3.tip() - .attr('class', 'd3-tip') - .offset([-10, 0]) - .html(function(d) { - return "Frequency: " + d.avgdelay + ""; - }) - -var svg = d3.select("body").append("svg") - .attr("width", width + margin.left + margin.right) - .attr("height", height + margin.top + margin.bottom) - .append("g") - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); - -svg.call(tip); - -d3.tsv("/by_hour.tsv", type, function(error, data) { - if (error) console.warn(error); - x.domain(data.map(function(d) { return d.hour; })); - y.domain([0, d3.max(data, function(d) { return d.avgdelay; })]); - - svg.append("g") - .attr("class", "x axis") - .attr("transform", "translate(0," + height + ")") - .call(xAxis) - .append("text") - .attr("x", width / 2) - .attr("y", 30) - .style("text-anchor", "middle") - .text("Angebrochene Stunde"); - - svg.append("g") - .attr("class", "y axis") - .call(yAxis) - .append("text") - .attr("transform", "rotate(-90)") - .attr("y", 6) - .attr("dy", ".71em") - .style("text-anchor", "end") - .text("Minuten"); - - svg.append("text") - .attr("x", (width / 2)) - .attr("y", 0 - (margin.top / 2)) - .attr("text-anchor", "middle") - .style("font-size", "16px") - .style("text-decoration", "underline") - .text("Durchschnittliche Verspätung nach Uhrzeit"); - - svg.selectAll(".bar") - .data(data) - .enter().append("rect") - .attr("class", "bar") - .attr("x", function(d) { return x(d.hour); }) - .attr("width", x.rangeBand()) - .attr("y", function(d) { return y(d.avgdelay); }) - .attr("height", function(d) { return height - y(d.avgdelay); }) - .on('mouseover', tip.show) - .on('mouseout', tip.hide) +function show_bargraph(datasource, title, xlab, ylab) { + var margin = {top: 40, right: 20, bottom: 30, left: 40}, + width = 960 - margin.left - margin.right, + height = 500 - margin.top - margin.bottom; + + var formatPercent = d3.format(".0%"); + + var x = d3.scale.ordinal() + .rangeRoundBands([0, width], .1); + + var y = d3.scale.linear() + .range([height, 0]); + + var xAxis = d3.svg.axis() + .scale(x) + .orient("bottom"); + + var yAxis = d3.svg.axis() + .scale(y) + .orient("left"); + // .tickFormat(formatPercent); + + var tip = d3.tip() + .attr('class', 'd3-tip') + .offset([-10, 0]) + .html(function(d) { + return "Frequency: " + d.y + ""; + }) + + var svg = d3.select("body").append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + svg.call(tip); + + d3.tsv(datasource, type, function(error, data) { + 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 + ")") + .call(xAxis) + .append("text") + .attr("x", width / 2) + .attr("y", 30) + .style("text-anchor", "middle") + .text(xlab); + + svg.append("g") + .attr("class", "y axis") + .call(yAxis) + .append("text") + .attr("transform", "rotate(-90)") + .attr("y", 6) + .attr("dy", ".71em") + .style("text-anchor", "end") + .text(ylab); + + svg.append("text") + .attr("x", (width / 2)) + .attr("y", 0 - (margin.top / 2)) + .attr("text-anchor", "middle") + .style("font-size", "16px") + .style("text-decoration", "underline") + .text(title); + + svg.selectAll(".bar") + .data(data) + .enter().append("rect") + .attr("class", "bar") + .attr("x", function(d) { return x(d.x); }) + .attr("width", x.rangeBand()) + .attr("y", function(d) { return y(d.y); }) + .attr("height", function(d) { return height - y(d.y); }) + .on('mouseover', tip.show) + .on('mouseout', tip.hide) + + }); + + function type(d) { + d.y = +d.y; + return d; + } +} -}); +show_bargraph('/by_time.tsv?time=hour&metric=delay', 'Durchschnittliche Verspätung nach Uhrzeit', + 'Angebrochene Stunde', 'Minuten'); -function type(d) { - d.avgdelay = +d.avgdelay; - return d; -} +show_bargraph('/by_time.tsv?time=weekday&metric=delay', 'Durchschnittliche Verspätung nach Wochentag', + 'Wochentag', 'Minuten'); % end -- cgit v1.2.3