<?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 | <?php |
setlocale(LC_CTYPE, 'C'); | 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 | // 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'); | include ('../include/common.inc.php'); |
$query = $conn->prepare(' | $query = $conn->prepare(' |
SELECT * from myway_timingdeltas' | SELECT * from myway_timingdeltas' |
, array(PDO::ATTR_CURSOR => PDO::FETCH_ORI_NEXT)); | , array(PDO::ATTR_CURSOR => PDO::FETCH_ORI_NEXT)); |
$query->execute(); | $query->execute(); |
$errors = $conn->errorInfo(); | $errors = $conn->errorInfo(); |
if ($errors[2] != "") { | if ($errors[2] != "") { |
die("Export terminated, db error" . print_r($errors, true)); | die("Export terminated, db error" . print_r($errors, true)); |
} | } |
$headers = Array("date", "delay", "distance", "origin", "destination"); | $headers = Array("date", "delay", "distance", "origin", "destination"); |
$fp = fopen('php://output', 'w'); | $fp = fopen('php://output', 'w'); |
if ($fp && $query) { | if ($fp && $query) { |
//header('Content-Type: text/csv'); | //header('Content-Type: text/csv'); |
header('Pragma: no-cache'); | header('Pragma: no-cache'); |
header('Expires: 0'); | header('Expires: 0'); |
fputcsv($fp, $headers); | fputcsv($fp, $headers); |
while ($r = $query->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) { | while ($r = $query->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) { |
$row = Array(); | $row = Array(); |
foreach ($headers as $i => $fieldName) { | foreach ($headers as $i => $fieldName) { |
switch ($fieldName) { | switch ($fieldName) { |
case "date": | case "date": |
$row[] = date("dm",strtotime($r['date'])).date("Hi",strtotime($r['time'])); | $row[] = date("r",strtotime($r['date']." ".$r['time'])); |
break; | break; |
case "delay": | case "delay": |
$row[] = $r['timing_delta']; | $row[] = $r['timing_delta']; |
break; | break; |
case "distance": | case "distance": |
$row[] = $r['stop_sequence']; | $row[] = $r['stop_sequence']; |
break; | break; |
case "origin": | case "origin": |
$row[] = $r['myway_stop']; | $row[] = $r['myway_stop']; |
break; | break; |
case "destination": | case "destination": |
$row[] = $r['route_name']; | $row[] = $r['route_name']; |
break; | break; |
default: | default: |
break; | break; |
} | } |
} | } |
fputcsv($fp, array_values($row)); | fputcsv($fp, array_values($row)); |
} | } |
die; | die; |
} | } |
?> | ?> |
<!DOCTYPE html> | <!DOCTYPE html> |
<meta charset="utf-8"> | <meta charset="utf-8"> |
<title>Tesseract</title> | <title>Tesseract</title> |
<style> | <style> |
#charts { | #charts { |
padding: 10px 0; | padding: 10px 0; |
} | } |
.chart { | .chart { |
display: inline-block; | display: inline-block; |
height: 151px; | height: 151px; |
margin-bottom: 20px; | margin-bottom: 20px; |
} | } |
.reset { | .reset { |
padding-left: 1em; | padding-left: 1em; |
font-size: smaller; | font-size: smaller; |
color: #ccc; | color: #ccc; |
} | } |
.background.bar { | .background.bar { |
fill: #ccc; | fill: #ccc; |
} | } |
.foreground.bar { | .foreground.bar { |
fill: steelblue; | fill: steelblue; |
} | } |
.axis path, .axis line { | .axis path, .axis line { |
fill: none; | fill: none; |
stroke: #000; | stroke: #000; |
shape-rendering: crispEdges; | shape-rendering: crispEdges; |
} | } |
.axis text { | .axis text { |
font: 10px sans-serif; | font: 10px sans-serif; |
} | } |
.brush rect.extent { | .brush rect.extent { |
fill: steelblue; | fill: steelblue; |
fill-opacity: .125; | fill-opacity: .125; |
} | } |
.brush .resize path { | .brush .resize path { |
fill: #eee; | fill: #eee; |
stroke: #666; | stroke: #666; |
} | } |
#hour-chart { | #hour-chart { |
width: 260px; | width: 260px; |
} | } |
#delay-chart { | #delay-chart { |
width: 230px; | width: 230px; |
} | } |
#distance-chart { | #distance-chart { |
width: 420px; | width: 420px; |
} | } |
#date-chart { | #date-chart { |
width: 920px; | width: 920px; |
} | } |
#flight-list { | #flight-list { |
min-height: 1024px; | min-height: 1024px; |
} | } |
#flight-list .date, | #flight-list .date, |
#flight-list .day { | #flight-list .day { |
margin-bottom: .4em; | margin-bottom: .4em; |
} | } |
#flight-list .flight { | #flight-list .flight { |
line-height: 1.5em; | line-height: 1.5em; |
background: #eee; | background: #eee; |
width: 640px; | width: 640px; |
margin-bottom: 1px; | margin-bottom: 1px; |
} | } |
#flight-list .time { | #flight-list .time { |
color: #999; | color: #999; |
} | } |
#flight-list .flight div { | #flight-list .flight div { |
display: inline-block; | display: inline-block; |
width: 100px; | width: 100px; |
} | } |
#flight-list div.distance, | #flight-list div.distance, |
#flight-list div.delay { | #flight-list div.delay { |
width: 160px; | width: 160px; |
padding-right: 10px; | padding-right: 10px; |
text-align: right; | text-align: right; |
} | } |
#flight-list .early { | #flight-list .early { |
color: green; | color: green; |
} | } |
aside { | aside { |
position: absolute; | position: absolute; |
left: 740px; | left: 740px; |
font-size: smaller; | font-size: smaller; |
width: 220px; | width: 220px; |
} | } |
</style> | </style> |
<div id="charts"> | <div id="charts"> |
<div id="hour-chart" class="chart"> | <div id="hour-chart" class="chart"> |
<div class="title">Time of Day</div> | <div class="title">Time of Day</div> |
</div> | </div> |
<div id="delay-chart" class="chart"> | <div id="delay-chart" class="chart"> |
<div class="title">Arrival Delay (min.)</div> | <div class="title">Arrival Delay (min.)</div> |
</div> | </div> |
<div id="distance-chart" class="chart"> | <div id="distance-chart" class="chart"> |
<div class="title">Distance (mi.)</div> | <div class="title">Distance (mi.)</div> |
</div> | </div> |
<div id="date-chart" class="chart"> | <div id="date-chart" class="chart"> |
<div class="title">Date</div> | <div class="title">Date</div> |
</div> | </div> |
</div> | </div> |
<aside id="totals"><span id="active">-</span> of <span id="total">-</span> flights selected.</aside> | <aside id="totals"><span id="active">-</span> of <span id="total">-</span> flights selected.</aside> |
<div id="lists"> | <div id="lists"> |
<div id="flight-list" class="list"></div> | <div id="flight-list" class="list"></div> |
</div> | </div> |
</div> | </div> |
<script src="../js/tesseract/tesseract.min.js"></script> | <script src="../js/tesseract/tesseract.min.js"></script> |
<script src="../js/d3/d3.v2.min.js"></script> | <script src="../js/d3/d3.v2.min.js"></script> |
<script> | <script> |
d3.csv("busdelay.csv.php", function(flights) { | d3.csv("busdelay.csv.php", function(flights) { |
// Various formatters. | // Various formatters. |
var formatNumber = d3.format(",d"), | var formatNumber = d3.format(",d"), |
formatChange = d3.format("+,d"), | formatChange = d3.format("+,d"), |
formatDate = d3.time.format("%B %d, %Y"), | formatDate = d3.time.format("%B %d, %Y"), |
formatTime = d3.time.format("%I:%M %p"); | formatTime = d3.time.format("%I:%M %p"); |
// A nest operator, for grouping the flight list. | // A nest operator, for grouping the flight list. |
var nestByDate = d3.nest() | var nestByDate = d3.nest() |
.key(function(d) { return d3.time.day(d.date); }); | .key(function(d) { return d3.time.day(d.date); }); |
// A little coercion, since the CSV is untyped. | // A little coercion, since the CSV is untyped. |
flights.forEach(function(d, i) { | flights.forEach(function(d, i) { |
d.index = i; | d.index = i; |
d.date = parseDate(d.date); | d.date = parseDate(d.date); |
d.delay = +d.delay; | d.delay = +d.delay; |
d.distance = +d.distance; | d.distance = +d.distance; |
}); | }); |
// Create the tesseract and relevant dimensions and groups. | // Create the tesseract and relevant dimensions and groups. |
flight = tesseract(flights), | flight = tesseract(flights), |
all = flight.groupAll(), | all = flight.groupAll(), |
date = flight.dimension(function(d) { return d3.time.day(d.date); }), | date = flight.dimension(function(d) { return d3.time.day(d.date); }), |
dates = date.group(), | dates = date.group(), |
hour = flight.dimension(function(d) { return d.date.getHours() + d.date.getMinutes() / 60; }), | hour = flight.dimension(function(d) { return d.date.getHours() + d.date.getMinutes() / 60; }), |
hours = hour.group(Math.floor), | 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 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; }), | delays = delay.group(function(d) { return Math.floor(d / 10) * 10; }), |
distance = flight.dimension(function(d) { return Math.min(90, d.distance); }), | distance = flight.dimension(function(d) { return Math.min(60, d.distance); }), |
distances = distance.group(function(d) { return Math.floor(d / 50) * 50; }); | distances = distance.group(function(d) { return Math.floor(d / 50) * 50; }); |
var charts = [ | var charts = [ |
barChart() | barChart() |
.dimension(hour) | .dimension(hour) |
.group(hours) | .group(hours) |
.x(d3.scale.linear() | .x(d3.scale.linear() |
.domain([0, 24]) | .domain([0, 24]) |
.rangeRound([0, 10 * 24])), | .rangeRound([0, 10 * 24])), |
barChart() | barChart() |
.dimension(delay) | .dimension(delay) |
.group(delays) | .group(delays) |
.x(d3.scale.linear() | .x(d3.scale.linear() |
.domain([-60, 150]) | .domain([-650, 650]) |
.rangeRound([0, 10 * 21])), | .rangeRound([0, 10 * 21])), |
barChart() | barChart() |
.dimension(distance) | .dimension(distance) |
.group(distances) | .group(distances) |
.x(d3.scale.linear() | .x(d3.scale.linear() |
.domain([0, 90]) | .domain([0, 60]) |
.rangeRound([0, 10 * 40])), | .rangeRound([0, 10 * 40])), |
barChart() | barChart() |
.dimension(date) | .dimension(date) |
.group(dates) | .group(dates) |
.round(d3.time.day.round) | .round(d3.time.day.round) |
.x(d3.time.scale() | .x(d3.time.scale() |
.domain([new Date(2001, 0, 1), new Date(2001, 3, 1)]) | .domain([new Date(2011, 4, 1), new Date(2012, 1, 4)]) |
.rangeRound([0, 10 * 90])) | .rangeRound([0, 10 * 90])) |
.filter([new Date(2001, 1, 1), new Date(2001, 2, 1)]) | .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 | // 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. | // .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. | // We also listen to the chart's brush events to update the display. |
var chart = d3.selectAll(".chart") | var chart = d3.selectAll(".chart") |
.data(charts) | .data(charts) |
.each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); }); | .each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); }); |
// Render the initial lists. | // Render the initial lists. |
var list = d3.selectAll(".list") | var list = d3.selectAll(".list") |
.data([flightList]); | .data([flightList]); |
// Render the total. | // Render the total. |
d3.selectAll("#total") | d3.selectAll("#total") |
.text(formatNumber(flight.size())); | .text(formatNumber(flight.size())); |
renderAll(); | renderAll(); |
// Renders the specified chart or list. | // Renders the specified chart or list. |
function render(method) { | function render(method) { |
d3.select(this).call(method); | d3.select(this).call(method); |
} | } |
// Whenever the brush moves, re-rendering everything. | // Whenever the brush moves, re-rendering everything. |
function renderAll() { | function renderAll() { |
chart.each(render); | chart.each(render); |
list.each(render); | list.each(render); |
d3.select("#active").text(formatNumber(all.value())); | d3.select("#active").text(formatNumber(all.value())); |
} | } |
// Like d3.time.format, but faster. | // Like d3.time.format, but faster. |
function parseDate(d) { | function parseDate(d) { |
return new Date(2001, | return new Date(d); |
d.substring(0, 2) - 1, | |
d.substring(2, 4), | |
d.substring(4, 6), | |
d.substring(6, 8)); | |
} | } |
window.filter = function(filters) { | window.filter = function(filters) { |
filters.forEach(function(d, i) { charts[i].filter(d); }); | filters.forEach(function(d, i) { charts[i].filter(d); }); |
renderAll(); | renderAll(); |
}; | }; |
window.reset = function(i) { | window.reset = function(i) { |
charts[i].filter(null); | charts[i].filter(null); |
renderAll(); | renderAll(); |
}; | }; |
function flightList(div) { | function flightList(div) { |
var flightsByDate = nestByDate.entries(date.top(40)); | var flightsByDate = nestByDate.entries(date.top(40)); |
div.each(function() { | div.each(function() { |
var date = d3.select(this).selectAll(".date") | var date = d3.select(this).selectAll(".date") |
.data(flightsByDate, function(d) { return d.key; }); | .data(flightsByDate, function(d) { return d.key; }); |
date.enter().append("div") | date.enter().append("div") |
.attr("class", "date") | .attr("class", "date") |
.append("div") | .append("div") |
.attr("class", "day") | .attr("class", "day") |
.text(function(d) { return formatDate(d.values[0].date); }); | .text(function(d) { return formatDate(d.values[0].date); }); |
date.exit().remove(); | date.exit().remove(); |
var flight = date.order().selectAll(".flight") | var flight = date.order().selectAll(".flight") |
.data(function(d) { return d.values; }, function(d) { return d.index; }); | .data(function(d) { return d.values; }, function(d) { return d.index; }); |
var flightEnter = flight.enter().append("div") | var flightEnter = flight.enter().append("div") |
.attr("class", "flight"); | .attr("class", "flight"); |
flightEnter.append("div") | flightEnter.append("div") |
.attr("class", "time") | .attr("class", "time") |
.text(function(d) { return formatTime(d.date); }); | .text(function(d) { return formatTime(d.date); }); |
flightEnter.append("div") | flightEnter.append("div") |
.attr("class", "origin") | .attr("class", "origin") |
.text(function(d) { return d.origin; }); | .text(function(d) { return d.origin; }); |
flightEnter.append("div") | flightEnter.append("div") |
.attr("class", "destination") | .attr("class", "destination") |
.text(function(d) { return d.destination; }); | .text(function(d) { return d.destination; }); |
flightEnter.append("div") | flightEnter.append("div") |
.attr("class", "distance") | .attr("class", "distance") |
.text(function(d) { return formatNumber(d.distance) + " mi."; }); | .text(function(d) { return formatNumber(d.distance) + " mi."; }); |
flightEnter.append("div") | flightEnter.append("div") |
.attr("class", "delay") | .attr("class", "delay") |
.classed("early", function(d) { return d.delay < 0; }) | .classed("early", function(d) { return d.delay < 0; }) |
.text(function(d) { return formatChange(d.delay) + " min."; }); | .text(function(d) { return formatChange(d.delay) + " min."; }); |
flight.exit().remove(); | flight.exit().remove(); |
flight.order(); | flight.order(); |
}); | }); |
} | } |
function barChart() { | function barChart() { |
if (!barChart.id) barChart.id = 0; | if (!barChart.id) barChart.id = 0; |
var margin = {top: 10, right: 10, bottom: 20, left: 10}, | var margin = {top: 10, right: 10, bottom: 20, left: 10}, |
x, | x, |
y = d3.scale.linear().range([100, 0]), | y = d3.scale.linear().range([100, 0]), |
id = barChart.id++, | id = barChart.id++, |
axis = d3.svg.axis().orient("bottom"), | axis = d3.svg.axis().orient("bottom"), |
brush = d3.svg.brush(), | brush = d3.svg.brush(), |
brushDirty, | brushDirty, |
dimension, | dimension, |
group, | group, |
round; | round; |
function chart(div) { | function chart(div) { |
var width = x.range()[1], | var width = x.range()[1], |
height = y.range()[0]; | height = y.range()[0]; |
y.domain([0, group.top(1)[0].value]); | y.domain([0, group.top(1)[0].value]); |
div.each(function() { | div.each(function() { |
var div = d3.select(this), | var div = d3.select(this), |
g = div.select("g"); | g = div.select("g"); |
// Create the skeletal chart. | // Create the skeletal chart. |
if (g.empty()) { | if (g.empty()) { |
div.select(".title").append("a") | div.select(".title").append("a") |
.attr("href", "javascript:reset(" + id + ")") | .attr("href", "javascript:reset(" + id + ")") |
.attr("class", "reset") | .attr("class", "reset") |
.text("reset") | .text("reset") |
.style("display", "none"); | .style("display", "none"); |
g = div.append("svg") | g = div.append("svg") |
.attr("width", width + margin.left + margin.right) | .attr("width", width + margin.left + margin.right) |
.attr("height", height + margin.top + margin.bottom) | .attr("height", height + margin.top + margin.bottom) |
.append("g") | .append("g") |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
g.append("clipPath") | g.append("clipPath") |
.attr("id", "clip-" + id) | .attr("id", "clip-" + id) |
.append("rect") | .append("rect") |
.attr("width", width) | .attr("width", width) |
.attr("height", height); | .attr("height", height); |
g.selectAll(".bar") | g.selectAll(".bar") |
.data(["background", "foreground"]) | .data(["background", "foreground"]) |
.enter().append("path") | .enter().append("path") |
.attr("class", function(d) { return d + " bar"; }) | .attr("class", function(d) { return d + " bar"; }) |
.datum(group.all()); | .datum(group.all()); |
g.selectAll(".foreground.bar") | g.selectAll(".foreground.bar") |
.attr("clip-path", "url(#clip-" + id + ")"); | .attr("clip-path", "url(#clip-" + id + ")"); |
g.append("g") | g.append("g") |
.attr("class", "axis") | .attr("class", "axis") |
.attr("transform", "translate(0," + height + ")") | .attr("transform", "translate(0," + height + ")") |
.call(axis); | .call(axis); |
// Initialize the brush component with pretty resize handles. | // Initialize the brush component with pretty resize handles. |
var gBrush = g.append("g").attr("class", "brush").call(brush); | var gBrush = g.append("g").attr("class", "brush").call(brush); |
gBrush.selectAll("rect").attr("height", height); | gBrush.selectAll("rect").attr("height", height); |
gBrush.selectAll(".resize").append("path").attr("d", resizePath); | gBrush.selectAll(".resize").append("path").attr("d", resizePath); |
} | } |
// Only redraw the brush if set externally. | // Only redraw the brush if set externally. |
if (brushDirty) { | if (brushDirty) { |
brushDirty = false; | brushDirty = false; |
g.selectAll(".brush").call(brush); | g.selectAll(".brush").call(brush); |
div.select(".title a").style("display", brush.empty() ? "none" : null); | div.select(".title a").style("display", brush.empty() ? "none" : null); |
if (brush.empty()) { | if (brush.empty()) { |
g.selectAll("#clip-" + id + " rect") | g.selectAll("#clip-" + id + " rect") |
.attr("x", 0) | .attr("x", 0) |
.attr("width", width); | .attr("width", width); |
} else { | } else { |
var extent = brush.extent(); | var extent = brush.extent(); |
g.selectAll("#clip-" + id + " rect") | g.selectAll("#clip-" + id + " rect") |
.attr("x", x(extent[0])) | .attr("x", x(extent[0])) |
.attr("width", x(extent[1]) - x(extent[0])); | .attr("width", x(extent[1]) - x(extent[0])); |
} | } |
} | } |
g.selectAll(".bar").attr("d", barPath); | g.selectAll(".bar").attr("d", barPath); |
}); | }); |
function barPath(groups) { | function barPath(groups) { |
var path = [], | var path = [], |
i = -1, | i = -1, |
n = groups.length, | n = groups.length, |
d; | d; |
while (++i < n) { | while (++i < n) { |
d = groups[i]; | d = groups[i]; |
path.push("M", x(d.key), ",", height, "V", y(d.value), "h9V", height); | path.push("M", x(d.key), ",", height, "V", y(d.value), "h9V", height); |
} | } |
return path.join(""); | return path.join(""); |
} | } |
function resizePath(d) { | function resizePath(d) { |
var e = +(d == "e"), | var e = +(d == "e"), |
x = e ? 1 : -1, | x = e ? 1 : -1, |
y = height / 3; | y = height / 3; |
return "M" + (.5 * x) + "," + y | return "M" + (.5 * x) + "," + y |
+ "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) | + "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) |
+ "V" + (2 * y - 6) | + "V" + (2 * y - 6) |
+ "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y) | + "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y) |
+ "Z" | + "Z" |
+ "M" + (2.5 * x) + "," + (y + 8) | + "M" + (2.5 * x) + "," + (y + 8) |
+ "V" + (2 * y - 8) | + "V" + (2 * y - 8) |
+ "M" + (4.5 * x) + "," + (y + 8) | + "M" + (4.5 * x) + "," + (y + 8) |
+ "V" + (2 * y - 8); | + "V" + (2 * y - 8); |
} | } |
} | } |
brush.on("brushstart.chart", function() { | brush.on("brushstart.chart", function() { |
var div = d3.select(this.parentNode.parentNode.parentNode); | var div = d3.select(this.parentNode.parentNode.parentNode); |
div.select(".title a").style("display", null); | div.select(".title a").style("display", null); |
}); | }); |
brush.on("brush.chart", function() { | brush.on("brush.chart", function() { |
var g = d3.select(this.parentNode), | var g = d3.select(this.parentNode), |
extent = brush.extent(); | extent = brush.extent(); |
if (round) g.select(".brush") | if (round) g.select(".brush") |
.call(brush.extent(extent = extent.map(round))) | .call(brush.extent(extent = extent.map(round))) |
.selectAll(".resize") | .selectAll(".resize") |
.style("display", null); | .style("display", null); |
g.select("#clip-" + id + " rect") | g.select("#clip-" + id + " rect") |
.attr("x", x(extent[0])) | .attr("x", x(extent[0])) |
.attr("width", x(extent[1]) - x(extent[0])); | .attr("width", x(extent[1]) - x(extent[0])); |
dimension.filterRange(extent); | dimension.filterRange(extent); |
}); | }); |
brush.on("brushend.chart", function() { | brush.on("brushend.chart", function() { |
if (brush.empty()) { | if (brush.empty()) { |
var div = d3.select(this.parentNode.parentNode.parentNode); | var div = d3.select(this.parentNode.parentNode.parentNode); |
div.select(".title a").style("display", "none"); | div.select(".title a").style("display", "none"); |
div.select("#clip-" + id + " rect").attr("x", null).attr("width", "100%"); | div.select("#clip-" + id + " rect").attr("x", null).attr("width", "100%"); |
dimension.filterAll(); | dimension.filterAll(); |
} | } |
}); | }); |
chart.margin = function(_) { | chart.margin = function(_) { |
if (!arguments.length) return margin; | if (!arguments.length) return margin; |
margin = _; | margin = _; |
return chart; | return chart; |
}; | }; |
chart.x = function(_) { | chart.x = function(_) { |
if (!arguments.length) return x; | if (!arguments.length) return x; |
x = _; | x = _; |
axis.scale(x); | axis.scale(x); |
brush.x(x); | brush.x(x); |
return chart; | return chart; |
}; | }; |
chart.y = function(_) { | chart.y = function(_) { |
if (!arguments.length) return y; | if (!arguments.length) return y; |
y = _; | y = _; |
return chart; | return chart; |
}; | }; |
chart.dimension = function(_) { | chart.dimension = function(_) { |
if (!arguments.length) return dimension; | if (!arguments.length) return dimension; |
dimension = _; | dimension = _; |
return chart; | return chart; |
}; | }; |
chart.filter = function(_) { | chart.filter = function(_) { |
if (_) { | if (_) { |
brush.extent(_); | brush.extent(_); |
dimension.filterRange(_); | dimension.filterRange(_); |
} else { | } else { |
brush.clear(); | brush.clear(); |
dimension.filterAll(); | dimension.filterAll(); |
} | } |
brushDirty = true; | brushDirty = true; |
return chart; | return chart; |
}; | }; |
chart.group = function(_) { | chart.group = function(_) { |
if (!arguments.length) return group; | if (!arguments.length) return group; |
group = _; | group = _; |
return chart; | return chart; |
}; | }; |
chart.round = function(_) { | chart.round = function(_) { |
if (!arguments.length) return round; | if (!arguments.length) return round; |
round = _; | round = _; |
return chart; | return chart; |
}; | }; |
return d3.rebind(chart, brush, "on"); | return d3.rebind(chart, brush, "on"); |
} | } |
}); | }); |
</script> | </script> |
<?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. |
*/ | */ |
include ('include/common.inc.php'); | include ('include/common.inc.php'); |
if (isset($stopid)) { | if (isset($stopid)) { |
$stop = getStop($stopid); | $stop = getStop($stopid); |
} | } |
/* if ($stopcode != "" && $stop[5] != $stopcode) { | /* if ($stopcode != "" && $stop[5] != $stopcode) { |
$url = $APIurl . "/json/stopcodesearch?q=" . $stopcode; | $url = $APIurl . "/json/stopcodesearch?q=" . $stopcode; |
$stopsearch = json_decode(getPage($url)); | $stopsearch = json_decode(getPage($url)); |
$stopid = $stopsearch[0][0]; | $stopid = $stopsearch[0][0]; |
$url = $APIurl . "/json/stop?stop_id=" . $stopid; | $url = $APIurl . "/json/stop?stop_id=" . $stopid; |
$stop = json_decode(getPage($url)); | $stop = json_decode(getPage($url)); |
} | } |
if (!startsWith($stop[5], "Wj") && strpos($stop[1], "Platform") === false) { | if (!startsWith($stop[5], "Wj") && strpos($stop[1], "Platform") === false) { |
// expand out to all platforms | // expand out to all platforms |
} */ | } */ |
$stops = Array(); | $stops = Array(); |
$stopPositions = Array(); | $stopPositions = Array(); |
$stopNames = Array(); | $stopNames = Array(); |
$tripStopNumbers = Array(); | $tripStopNumbers = Array(); |
$allStopsTrips = Array(); | $allStopsTrips = Array(); |
$fetchedTripSequences = Array(); | $fetchedTripSequences = Array(); |
$stopLinks = ""; | $stopLinks = ""; |
if (isset($stopids)) { | if (isset($stopids)) { |
foreach ($stopids as $sub_stopid) { | foreach ($stopids as $sub_stopid) { |
$stops[] = getStop($sub_stopid); | $stops[] = getStop($sub_stopid); |
} | } |
$stop = $stops[0]; | $stop = $stops[0]; |
$stopid = $stops[0]["stop_id"]; | $stopid = $stops[0]["stop_id"]; |
$stopLinks.= "Individual stop pages: <br>"; | $stopLinks.= "Individual stop pages: <br>"; |
foreach ($stops as $key => $sub_stop) { | foreach ($stops as $key => $sub_stop) { |
$stopNames[$key] = $sub_stop["stop_name"]; | $stopNames[$key] = $sub_stop["stop_name"]; |
$stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . '</a> '; | $stopLinks.= '<a href="stop.php?stopid=' . $sub_stop["stop_id"] . '&stopcode=' . $sub_stop["stop_code"] . '">' . $sub_stop["stop_name"] . '</a> '; |
$stopPositions[$key] = Array( | $stopPositions[$key] = Array( |
$sub_stop["stop_lat"], | $sub_stop["stop_lat"], |
$sub_stop["stop_lon"] | $sub_stop["stop_lon"] |
); | ); |
$trips = getStopTrips($sub_stop["stop_id"]); | $trips = getStopTrips($sub_stop["stop_id"]); |
$tripSequence = ""; | $tripSequence = ""; |
foreach ($trips as $trip) { | foreach ($trips as $trip) { |
$tripSequence.= "{$trip['trip_id']},"; | $tripSequence.= "{$trip['trip_id']},"; |
$tripStopNumbers[$trip['trip_id']][] = $key; | $tripStopNumbers[$trip['trip_id']][] = $key; |
} | } |
if (!in_array($tripSequence, $fetchedTripSequences)) { | if (!in_array($tripSequence, $fetchedTripSequences)) { |
// only fetch new trip sequences | // only fetch new trip sequences |
$fetchedTripSequences[] = $tripSequence; | $fetchedTripSequences[] = $tripSequence; |
$trips = getStopTripsWithTimes($sub_stop["stop_id"]); | $trips = getStopTripsWithTimes($sub_stop["stop_id"]); |
foreach ($trips as $trip) { | foreach ($trips as $trip) { |
if (!isset($allStopsTrips[$trip["trip_id"]])) | if (!isset($allStopsTrips[$trip["trip_id"]])) |
$allStopsTrips[$trip["trip_id"]] = $trip; | $allStopsTrips[$trip["trip_id"]] = $trip; |
} | } |
} | } |
//else { | //else { |
// echo "skipped sequence $tripSequence"; | // echo "skipped sequence $tripSequence"; |
//} | //} |
} | } |
} | } |
if (sizeof($stops) > 0) { | if (sizeof($stops) > 0) { |
$stopDescParts = explode("<br>", $stop['stop_desc']); | $stopDescParts = explode("<br>", $stop['stop_desc']); |
include_header(trim(str_replace("Street: ", "", $stopDescParts[0])), "stop"); | include_header(trim(str_replace("Street: ", "", $stopDescParts[0])), "stop"); |
} else { | } else { |
include_header($stop['stop_name'], "stop"); | include_header($stop['stop_name'], "stop"); |
} | } |
/* $serviceAlerts = json_decode(getPage(curPageURL() . "/servicealerts_api.php?filter_class=stop&filter_id=".$stopid) , true); | /* $serviceAlerts = json_decode(getPage(curPageURL() . "/servicealerts_api.php?filter_class=stop&filter_id=".$stopid) , true); |
foreach($serviceAlerts['entities'] as $serviceAlert) { | foreach($serviceAlerts['entities'] as $serviceAlert) { |
echo '<div id="servicewarning">'.$serviceAlert['alert']['description']['translation'].'</div>'; | echo '<div id="servicewarning">'.$serviceAlert['alert']['description']['translation'].'</div>'; |
} */ | } */ |
echo '<div class="content-secondary">'; | echo '<div class="content-secondary">'; |
echo $stopLinks; | echo $stopLinks; |
if (sizeof($stops) > 0) { | if (sizeof($stops) > 0) { |
trackEvent("View Stops", "View Combined Stops", $stop["stop_name"], $stop["stop_id"]); | trackEvent("View Stops", "View Combined Stops", $stop["stop_name"], $stop["stop_id"]); |
echo staticmap($stopPositions); | echo staticmap($stopPositions); |
} else { | } else { |
trackEvent("View Stops", "View Single Stop", $stop["stop_name"], $stop["stop_id"]); | trackEvent("View Stops", "View Single Stop", $stop["stop_name"], $stop["stop_id"]); |
echo staticmap(Array( | echo staticmap(Array( |
0 => Array( | 0 => Array( |
$stop["stop_lat"], | $stop["stop_lat"], |
$stop["stop_lon"] | $stop["stop_lon"] |
) | ) |
)); | )); |
} | } |
timeSettings(); | timeSettings(); |
echo '</div><div class="content-primary">'; | echo '</div><div class="content-primary">'; |
echo ' <ul data-role="listview" data-inset="true">'; | echo ' <ul data-role="listview" data-inset="true">'; |
if (sizeof($allStopsTrips) > 0) { | if (sizeof($allStopsTrips) > 0) { |
sktimesort($allStopsTrips, "arrival_time", true); | sktimesort($allStopsTrips, "arrival_time", true); |
$trips = $allStopsTrips; | $trips = $allStopsTrips; |
} else { | } else { |
$trips = getStopTripsWithTimes($stopid, "", "", "", (isset($filterIncludeRoutes) || isset($filterHasStop) ? "75" : "")); | $trips = getStopTripsWithTimes($stopid, "", "", "", (isset($filterIncludeRoutes) || isset($filterHasStop) ? "75" : "")); |
} | } |
echo "<div class='ui-header' style='overflow: visible; height: 2.5em'>"; | echo "<div class='ui-header' style='overflow: visible; height: 2.5em'>"; |
// if we have too many trips, cut down to size. | // if we have too many trips, cut down to size. |
if (!isset($filterIncludeRoutes) && !isset($filterHasStop) && sizeof($trips) > 10) { | if (!isset($filterIncludeRoutes) && !isset($filterHasStop) && sizeof($trips) > 10) { |
$trips = array_splice($trips, 0, 10); | $trips = array_splice($trips, 0, 10); |
} | } |
// later/earlier button setup | // later/earlier button setup |
if (sizeof($trips) == 0) { | if (sizeof($trips) == 0) { |
$time = isset($_REQUEST['time']) ? strtotime($_REQUEST['time']) : time(); | $time = isset($_REQUEST['time']) ? strtotime($_REQUEST['time']) : time(); |
$earlierTime = $time - (90 * 60); | $earlierTime = $time - (90 * 60); |
$laterTime = $time + (90 * 60); | $laterTime = $time + (90 * 60); |
} else { | } else { |
$tripsKeys = array_keys($trips); | $tripsKeys = array_keys($trips); |
$earlierTime = strtotime($trips[$tripsKeys[0]]['arrival_time']) - (90 * 60); | $earlierTime = strtotime($trips[$tripsKeys[0]]['arrival_time']) - (90 * 60); |
$laterTime = strtotime($trips[$tripsKeys[sizeof($trips) - 1]]['arrival_time']) - 60; | $laterTime = strtotime($trips[$tripsKeys[sizeof($trips) - 1]]['arrival_time']) - 60; |
} | } |
if (isset($stopids) && sizeof($stopids) > 0) { | if (isset($stopids) && sizeof($stopids) > 0) { |
$stopidurl = "stopids=" . implode(",", $stopids); | $stopidurl = "stopids=" . implode(",", $stopids); |
} else { | } else { |
$stopidurl = "stopid=$stopid"; | $stopidurl = "stopid=$stopid"; |
} | } |
if (sizeof($trips) >= 10) { | if (sizeof($trips) >= 10) { |
echo '<a href="stop.php?' . $stopidurl . '&service_period=' . service_period() . '&time=' . date("H:i", $laterTime) . '" data-icon="arrow-r" class="ui-btn-right">Later Trips</a>'; | echo '<a href="stop.php?' . $stopidurl . '&service_period=' . service_period() . '&time=' . date("H:i", $laterTime) . '" data-icon="arrow-r" class="ui-btn-right">Later Trips</a>'; |
} | } |
echo '<a href="stop.php?' . $stopidurl . '&service_period=' . service_period() . '&time=' . date("H:i", $earlierTime) . '" data-icon="arrow-l" class="ui-btn-left">Earlier Trips</a>'; | echo '<a href="stop.php?' . $stopidurl . '&service_period=' . service_period() . '&time=' . date("H:i", $earlierTime) . '" data-icon="arrow-l" class="ui-btn-left">Earlier Trips</a>'; |
echo "</div>"; | echo "</div>"; |
if (sizeof($trips) == 0) { | if (sizeof($trips) == 0) { |
echo "<li style='text-align: center;'>No trips in the near future.</li>"; | echo "<li style='text-align: center;'>No trips in the near future.</li>"; |
} else { | } else { |
if ($labs) { | |
// ETA calculation | |
$tripETA = Array(); | |
// max/min delay instead of stddev? | |
$query = $query = "select 'lol', avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas where extract(hour from time) between ".date("H", $earlierTime)." and ".date("H", $laterTime); | |
//select 'lol', stop_id,extract(hour from time), avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas where stop_id = '5501' group by stop_id, extract(hour from time) order by extract(hour from time) | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
$ETAparams = Array(); | |
foreach ($query->fetchAll() as $row) { | |
$ETAparams[$row[0]] = Array("avg"=> $row[1], "stddev"=>floor($row[2]),"count"=>$row[3]); | |
}; | |
//print_r($ETAparams); | |
foreach ($trips as $trip) { | |
$tripETA[$trip['trip_id']] = date("H:i",strtotime($trip['arrival_time']." - ".(floor($ETAparams['lol']['stddev']))." seconds"))." to ". | |
date("H:i",strtotime($trip['arrival_time']." + ".(floor($ETAparams['lol']['stddev']))." seconds")); | |
} | |
//print_r($tripETA); | |
} | |
foreach ($trips as $trip) { | foreach ($trips as $trip) { |
if ( | if ( |
isset($filterHasStop) && (getTripHasStop($trip['trip_id'], $filterHasStop) == 1) | isset($filterHasStop) && (getTripHasStop($trip['trip_id'], $filterHasStop) == 1) |
|| (isset($filterIncludeRoutes) && in_array($trip["route_short_name"], $filterIncludeRoutes)) | || (isset($filterIncludeRoutes) && in_array($trip["route_short_name"], $filterIncludeRoutes)) |
|| (!isset($filterIncludeRoutes) && !isset($filterHasStop)) | || (!isset($filterIncludeRoutes) && !isset($filterHasStop)) |
) { | ) { |
echo '<li>'; | echo '<li>'; |
$destination = getTripDestination($trip['trip_id']); | $destination = getTripDestination($trip['trip_id']); |
echo '<a href="trip.php?stopid=' . $stopid . '&tripid=' . $trip['trip_id'] . '"><h3>' . $trip['route_short_name'] . " towards " . $destination['stop_name'] . "</h3><p>"; | echo '<a href="trip.php?stopid=' . $stopid . '&tripid=' . $trip['trip_id'] . '"><h3>' . $trip['route_short_name'] . " towards " . $destination['stop_name'] . "</h3><p>"; |
$viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']); | $viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']); |
if ($labs) { | |
echo '<br><span class="eta">ETA: ' . $tripETA[$trip['trip_id']] . '</span>'; | |
} | |
if ($viaPoints != "") | if ($viaPoints != "") |
echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>'; | echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>'; |
if (sizeof($tripStopNumbers) > 0) { | if (sizeof($tripStopNumbers) > 0) { |
echo '<br><small>Boarding At: '; | echo '<br><small>Boarding At: '; |
if (sizeof($tripStopNumbers[$trip['trip_id']]) == sizeof($stopids)) { | if (sizeof($tripStopNumbers[$trip['trip_id']]) == sizeof($stopids)) { |
echo "All Stops"; | echo "All Stops"; |
} else { | } else { |
foreach ($tripStopNumbers[$trip['trip_id']] as $key) { | foreach ($tripStopNumbers[$trip['trip_id']] as $key) { |
echo $stopNames[$key] . ', '; | echo $stopNames[$key] . ', '; |
} | } |
} | } |
echo '</small>'; | echo '</small>'; |
} | } |
echo '</p>'; | echo '</p>'; |
echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>'; | echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>'; |
echo '</a></li>'; | echo '</a></li>'; |
flush(); | flush(); |
@ob_flush(); | @ob_flush(); |
} | } |
} | } |
} | } |
echo '</ul>'; | echo '</ul>'; |
echo '</div>'; | echo '</div>'; |
include_footer(); | include_footer(); |
?> | ?> |