Skip to content

Instantly share code, notes, and snippets.

@tuulos
Created March 10, 2012 01:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuulos/2009621 to your computer and use it in GitHub Desktop.
Save tuulos/2009621 to your computer and use it in GitHub Desktop.
Bitdeli Visualization Example: Trains arriving to BART stations in next 15 minutes

Bitdeli visualization example: Trains arriving to BART stations in next 15 minutes

This example shows how to use real-time data from the Bitdeli API to create visualizations with RaphaelJS.

The visualization shows a BART station on each column. The further the estimated time arrival is for a train, the further it is drawn from its destination station down bottom. The data is updated once a minute. Refresh the page to see the updated status.

The data originates from the BART API through this Bitdeli script.

You can view the live visualization here with bl.ocks.org.

For a detailed description, see this blog article.

Questions? Comments? Feel free to contact us.

var GROUPS_URL = "https://out.bitdeli.com/v1/data/s-04ba8cdd3ee197-2a7bff2d/groups?latest&max=100";
var STATIONS = ["12th St. Oakland City Center", "16th St. Mission", "19th St. Oakland", "24th St. Mission", "Ashby", "Balboa Park", "Bay Fair", "Castro Valley", "Coliseum/Oakland Airport", "Colma", "Concord", "Daly City", "Downtown Berkeley", "El Cerrito del Norte", "El Cerrito Plaza", "Embarcadero", "Fremont", "Fruitvale", "Glen Park", "Hayward", "Lafayette", "Lake Merritt", "MacArthur", "Millbrae", "Montgomery St.", "North Berkeley", "Orinda", "Powell St.", "Richmond", "Rockridge", "San Bruno", "San Francisco Int'l Airport", "San Leandro", "South Hayward", "South San Francisco", "Union City", "Walnut Creek", "West Oakland"];
var WIDTH = 1000;
var HEIGHT = 450;
var MARGIN_BOTTOM = 100;
var TRAIN_BOTTOM = MARGIN_BOTTOM + 15;
var MARGIN_LEFT = 10;
var STATION_WIDTH = ((WIDTH - MARGIN_LEFT * 2) / STATIONS.length);
var MAX_CARS = 11;
var FONT_SIZE = 10;
function by_stations(data)
{
var stations = {};
var items = data.items;
for (var i in items)
stations[items[i].object.station] = items[i].object.trains;
return stations;
}
function show_info(train)
{
var attributes = ['destination', 'direction', 'platform', 'minutes'];
var html = '';
for (var i in attributes)
html += '<b>' + attributes[i] + ':</b> ' + train[attributes[i]] + ' ';
$("#info").html(html);
}
function draw_train(station_idx, train, paper)
{
var car_width = STATION_WIDTH * 0.2;
var car_height = car_width * 2;
var ystep = (HEIGHT - TRAIN_BOTTOM) / 15.0;
var x = STATION_WIDTH * station_idx + MARGIN_LEFT,
y = (HEIGHT - TRAIN_BOTTOM) - (ystep * (train.minutes - 1));
var set = paper.set();
for (var i = 0; i < train.length; i++){
var car = paper.rect(x, y, car_width, car_height, 3);
if (i == 0)
car.attr({'fill': '#000'});
else
car.attr({'fill': train.hexcolor,
'fill-opacity': 0.5});
set.push(car);
y -= car_height;
}
set.click(function() { show_info(train); });
}
function draw(data, paper)
{
var stations = by_stations(data);
var x = MARGIN_LEFT;
for (var i in STATIONS){
var station = STATIONS[i];
for (var j in stations[station]){
var train = stations[station][j];
if (train.minutes < 15)
draw_train(i, train, paper);
}
var y = HEIGHT - MARGIN_BOTTOM;
var label = paper.text(x, y, station)
label.attr({'font-size': FONT_SIZE + 'px',
'text-anchor': 'start',
'fill': '#eee'});
label.rotate(90, x, y);
label.attr({x: x, y: y});
x += STATION_WIDTH;
}
}
function update(paper){
$.getJSON(GROUPS_URL, function(data){ draw(data, paper); });
}
$(document).ready(function() {
var paper = Raphael("canvas", WIDTH, HEIGHT);
update(paper);
});
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Trains arriving to BART stations in next 15 minutes</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="info">Click a train for more info</div>
<div id="canvas"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script>
<script src="bartviz.js"></script>
</body>
</html>
html, body {
font-family: Helvetica, sans-serif;
height: 100%;
background: #111;
}
#info{
margin-bottom: 10px;
color: #eee;
}
#canvas {
width: 1000px;
height: 450px;
background: #111;
padding: 5px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment