diff options
| -rw-r--r-- | index.pl | 28 | ||||
| -rw-r--r-- | templates/main.html.ep | 176 | 
2 files changed, 109 insertions, 95 deletions
@@ -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 "<strong>Frequency:</strong> <span style='color:red'>" + d.avgdelay + "</span>"; -  }) - -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 "<strong>Frequency:</strong> <span style='color:red'>" + d.y + "</span>"; +    }) +   +  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  | 
