[submodule "js/flotr2"] | [submodule "js/flotr2"] |
path = js/flotr2 | path = js/flotr2 |
url = https://github.com/HumbleSoftware/Flotr2.git | url = https://github.com/HumbleSoftware/Flotr2.git |
[submodule "js/FlashCanvas"] | [submodule "js/FlashCanvas"] |
path = js/FlashCanvas | path = js/FlashCanvas |
url = https://github.com/timcameronryan/FlashCanvas | url = https://github.com/timcameronryan/FlashCanvas |
[submodule "lib/amon-php"] | [submodule "lib/amon-php"] |
path = lib/amon-php | path = lib/amon-php |
url = https://github.com/martinrusev/amon-php.git | url = https://github.com/martinrusev/amon-php.git |
[submodule "js/yepnope"] | [submodule "js/yepnope"] |
path = js/yepnope | path = js/yepnope |
url = https://github.com/SlexAxton/yepnope.js.git | url = https://github.com/SlexAxton/yepnope.js.git |
[submodule "javascripts/tesseract"] | |
path = javascripts/tesseract | |
url = https://github.com/square/tesseract.git | |
[submodule "javascripts/d3"] | |
path = javascripts/d3 | |
url = https://github.com/mbostock/d3.git |
<?php | <?php |
/* | /* |
* Copyright 2010,2011 Alexander Sadleir | * Copyright 2010,2011 Alexander Sadleir |
Licensed under the Apache License, Version 2.0 (the "License"); | Licensed under the Apache License, Version 2.0 (the "License"); |
you may not use this file except in compliance with the License. | you may not use this file except in compliance with the License. |
You may obtain a copy of the License at | You may obtain a copy of the License at |
http://www.apache.org/licenses/LICENSE-2.0 | http://www.apache.org/licenses/LICENSE-2.0 |
Unless required by applicable law or agreed to in writing, software | Unless required by applicable law or agreed to in writing, software |
distributed under the License is distributed on an "AS IS" BASIS, | distributed under the License is distributed on an "AS IS" BASIS, |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
See the License for the specific language governing permissions and | See the License for the specific language governing permissions and |
limitations under the License. | limitations under the License. |
*/ | */ |
if (isset($_REQUEST['firstLetter'])) { | if (isset($_REQUEST['firstLetter'])) { |
$firstLetter = filter_var($_REQUEST['firstLetter'], FILTER_SANITIZE_STRING); | $firstLetter = filter_var($_REQUEST['firstLetter'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['bysuburbs'])) { | if (isset($_REQUEST['bysuburbs'])) { |
$bysuburbs = true; | $bysuburbs = true; |
} | } |
if (isset($_REQUEST['bynumber'])) { | if (isset($_REQUEST['bynumber'])) { |
$bynumber = true; | $bynumber = true; |
} | } |
if (isset($_REQUEST['allstops'])) { | if (isset($_REQUEST['allstops'])) { |
$allstops = true; | $allstops = true; |
} | } |
if (isset($_REQUEST['nearby'])) { | if (isset($_REQUEST['nearby'])) { |
$nearby = true; | $nearby = true; |
} | |
if (isset($_REQUEST['labs'])) { | |
$labs = true; | |
} | } |
if (isset($_REQUEST['suburb'])) { | if (isset($_REQUEST['suburb'])) { |
$suburb = $_REQUEST['suburb']; | $suburb = $_REQUEST['suburb']; |
} | } |
if (isset($_REQUEST['pageKey'])) { | if (isset($_REQUEST['pageKey'])) { |
$pageKey = filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); | $pageKey = filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['lat'])) { | if (isset($_REQUEST['lat'])) { |
$lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); |
} | } |
if (isset($_REQUEST['lon'])) { | if (isset($_REQUEST['lon'])) { |
$lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); |
} | } |
if (isset($_REQUEST['radius'])) { | if (isset($_REQUEST['radius'])) { |
$max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT); | $max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['numberSeries'])) { | if (isset($_REQUEST['numberSeries'])) { |
$numberSeries = filter_var($_REQUEST['numberSeries'], FILTER_SANITIZE_NUMBER_INT); | $numberSeries = filter_var($_REQUEST['numberSeries'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['routeDestination'])) { | if (isset($_REQUEST['routeDestination'])) { |
$routeDestination = urldecode(filter_var($_REQUEST['routeDestination'], FILTER_SANITIZE_ENCODED)); | $routeDestination = urldecode(filter_var($_REQUEST['routeDestination'], FILTER_SANITIZE_ENCODED)); |
} | } |
if (isset($_REQUEST['routename'])) { | if (isset($_REQUEST['routename'])) { |
$routename = urldecode(filter_var($_REQUEST['routename'], FILTER_SANITIZE_ENCODED)); | $routename = urldecode(filter_var($_REQUEST['routename'], FILTER_SANITIZE_ENCODED)); |
} | } |
if (isset($_REQUEST['stopcode'])) { | if (isset($_REQUEST['stopcode'])) { |
$stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING); | $stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['stopids'])) { | if (isset($_REQUEST['stopids'])) { |
$stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING)); | $stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING)); |
} | } |
if (isset($_REQUEST['filterIncludeRoutes'])) { | if (isset($_REQUEST['filterIncludeRoutes'])) { |
$filterIncludeRoutes = explode(",", filter_var($_REQUEST['filterIncludeRoutes'], FILTER_SANITIZE_STRING)); | $filterIncludeRoutes = explode(",", filter_var($_REQUEST['filterIncludeRoutes'], FILTER_SANITIZE_STRING)); |
} | } |
if (isset($_REQUEST['filterHasStop'])) { | if (isset($_REQUEST['filterHasStop'])) { |
$filterHasStop = filter_var($_REQUEST['filterHasStop'], FILTER_SANITIZE_STRING); | $filterHasStop = filter_var($_REQUEST['filterHasStop'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['tripid'])) { | if (isset($_REQUEST['tripid'])) { |
$tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_STRING); | $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['routeid'])) { | if (isset($_REQUEST['routeid'])) { |
$routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_STRING); | $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['directionid'])) { | if (isset($_REQUEST['directionid'])) { |
$directionid = filter_var($_REQUEST['directionid'], FILTER_SANITIZE_STRING); | $directionid = filter_var($_REQUEST['directionid'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['stopid'])) { | if (isset($_REQUEST['stopid'])) { |
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); | $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['geolocate'])) { | if (isset($_REQUEST['geolocate'])) { |
$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); | $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); |
} | } |
<?php | |
setlocale(LC_CTYPE, 'C'); | |
// source: http://stackoverflow.com/questions/81934/easy-way-to-export-a-sql-table-without-access-to-the-server-or-phpmyadmin#81951 | |
include ('../include/common.inc.php'); | |
$query = $conn->prepare(' | |
SELECT * from myway_timingdeltas' | |
, array(PDO::ATTR_CURSOR => PDO::FETCH_ORI_NEXT)); | |
$query->execute(); | |
$errors = $conn->errorInfo(); | |
if ($errors[2] != "") { | |
die("Export terminated, db error" . print_r($errors, true)); | |
} | |
$headers = Array("date", "delay", "distance", "origin", "destination"); | |
$fp = fopen('php://output', 'w'); | |
if ($fp && $query) { | |
//header('Content-Type: text/csv'); | |
header('Pragma: no-cache'); | |
header('Expires: 0'); | |
fputcsv($fp, $headers); | |
while ($r = $query->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) { | |
$row = Array(); | |
foreach ($headers as $i => $fieldName) { | |
switch ($fieldName) { | |
case "date": | |
$row[] = date("r",strtotime($r['date']." ".$r['time'])); | |
break; | |
case "delay": | |
$row[] = $r['timing_delta']; | |
break; | |
case "distance": | |
$row[] = $r['stop_sequence']; | |
break; | |
case "origin": | |
$row[] = $r['myway_stop']; | |
break; | |
case "destination": | |
$row[] = $r['route_name']; | |
break; | |
default: | |
break; | |
} | |
} | |
fputcsv($fp, array_values($row)); | |
} | |
die; | |
} | |
?> | |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<title>Tesseract</title> | |
<style> | |
#charts { | |
padding: 10px 0; | |
} | |
.chart { | |
display: inline-block; | |
height: 151px; | |
margin-bottom: 20px; | |
} | |
.reset { | |
padding-left: 1em; | |
font-size: smaller; | |
color: #ccc; | |
} | |
.background.bar { | |
fill: #ccc; | |
} | |
.foreground.bar { | |
fill: steelblue; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.brush rect.extent { | |
fill: steelblue; | |
fill-opacity: .125; | |
} | |
.brush .resize path { | |
fill: #eee; | |
stroke: #666; | |
} | |
#hour-chart { | |
width: 260px; | |
} | |
#delay-chart { | |
width: 230px; | |
} | |
#distance-chart { | |
width: 420px; | |
} | |
#date-chart { | |
width: 920px; | |
} | |
#flight-list { | |
min-height: 1024px; | |
} | |
#flight-list .date, | |
#flight-list .day { | |
margin-bottom: .4em; | |
} | |
#flight-list .flight { | |
line-height: 1.5em; | |
background: #eee; | |
width: 640px; | |
margin-bottom: 1px; | |
} | |
#flight-list .time { | |
color: #999; | |
} | |
#flight-list .flight div { | |
display: inline-block; | |
width: 100px; | |
} | |
#flight-list div.distance, | |
#flight-list div.delay { | |
width: 160px; | |
padding-right: 10px; | |
text-align: right; | |
} | |
#flight-list .early { | |
color: green; | |
} | |
aside { | |
position: absolute; | |
left: 740px; | |
font-size: smaller; | |
width: 220px; | |
} | |
</style> | |
<div id="charts"> | |
<div id="hour-chart" class="chart"> | |
<div class="title">Time of Day</div> | |
</div> | |
<div id="delay-chart" class="chart"> | |
<div class="title">Arrival Delay (min.)</div> | |
</div> | |
<div id="distance-chart" class="chart"> | |
<div class="title">Distance (mi.)</div> | |
</div> | |
<div id="date-chart" class="chart"> | |
<div class="title">Date</div> | |
</div> | |
</div> | |
<aside id="totals"><span id="active">-</span> of <span id="total">-</span> flights selected.</aside> | |
<div id="lists"> | |
<div id="flight-list" class="list"></div> | |
</div> | |
</div> | |
<script src="../js/tesseract/tesseract.min.js"></script> | |
<script src="../js/d3/d3.v2.min.js"></script> | |
<script> | |
d3.csv("busdelay.csv.php", function(flights) { | |
// Various formatters. | |
var formatNumber = d3.format(",d"), | |
formatChange = d3.format("+,d"), | |
formatDate = d3.time.format("%B %d, %Y"), | |
formatTime = d3.time.format("%I:%M %p"); | |
// A nest operator, for grouping the flight list. | |
var nestByDate = d3.nest() | |
.key(function(d) { return d3.time.day(d.date); }); | |
// A little coercion, since the CSV is untyped. | |
flights.forEach(function(d, i) { | |
d.index = i; | |
d.date = parseDate(d.date); | |
d.delay = +d.delay; | |
d.distance = +d.distance; | |
}); | |
// Create the tesseract and relevant dimensions and groups. | |
flight = tesseract(flights), | |
all = flight.groupAll(), | |
date = flight.dimension(function(d) { return d3.time.day(d.date); }), | |
dates = date.group(), | |
hour = flight.dimension(function(d) { return d.date.getHours() + d.date.getMinutes() / 60; }), | |
hours = hour.group(Math.floor), | |
//delay = flight.dimension(function(d) { return Math.max(-60, Math.min(149, d.delay)); }), | |
delay = flight.dimension(function(d) { return d.delay; }), | |
delays = delay.group(function(d) { return Math.floor(d / 10) * 10; }), | |
distance = flight.dimension(function(d) { return Math.min(60, d.distance); }), | |
distances = distance.group(function(d) { return Math.floor(d / 50) * 50; }); | |
var charts = [ | |
barChart() | |
.dimension(hour) | |
.group(hours) | |
.x(d3.scale.linear() | |
.domain([0, 24]) | |
.rangeRound([0, 10 * 24])), | |
barChart() | |
.dimension(delay) | |
.group(delays) | |
.x(d3.scale.linear() | |
.domain([-650, 650]) | |
.rangeRound([0, 10 * 21])), | |
barChart() | |
.dimension(distance) | |
.group(distances) | |
.x(d3.scale.linear() | |
.domain([0, 60]) | |
.rangeRound([0, 10 * 40])), | |
barChart() | |
.dimension(date) | |
.group(dates) | |
.round(d3.time.day.round) | |
.x(d3.time.scale() | |
.domain([new Date(2011, 4, 1), new Date(2012, 1, 4)]) | |
.rangeRound([0, 10 * 90])) | |
.filter([new Date(2011, 4, 4), new Date(2012, 4, 4)]) | |
]; | |
// Given our array of charts, which we assume are in the same order as the | |
// .chart elements in the DOM, bind the charts to the DOM and render them. | |
// We also listen to the chart's brush events to update the display. | |
var chart = d3.selectAll(".chart") | |
.data(charts) | |
.each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); }); | |
// Render the initial lists. | |
var list = d3.selectAll(".list") | |
.data([flightList]); | |
// Render the total. | |
d3.selectAll("#total") | |
.text(formatNumber(flight.size())); | |
renderAll(); | |
// Renders the specified chart or list. | |
function render(method) { | |
d3.select(this).call(method); | |
} | |
// Whenever the brush moves, re-rendering everything. | |
function renderAll() { | |
chart.each(render); | |
list.each(render); | |
d3.select("#active").text(formatNumber(all.value())); | |
} | |
// Like d3.time.format, but faster. | |
function parseDate(d) { | |
return new Date(d); | |
} | |
window.filter = function(filters) { | |
filters.forEach(function(d, i) { charts[i].filter(d); }); | |
renderAll(); | |
}; | |
window.reset = function(i) { | |
charts[i].filter(null); | |
renderAll(); | |
}; | |
function flightList(div) { | |
var flightsByDate = nestByDate.entries(date.top(40)); | |
div.each(function() { | |
var date = d3.select(this).selectAll(".date") | |
.data(flightsByDate, function(d) { return d.key; }); | |
date.enter().append("div& |