Skip to content

Instantly share code, notes, and snippets.

@tuulos tuulos/
Created Mar 10, 2012

What would you like to do?
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

For a detailed description, see this blog article.

Questions? Comments? Feel free to contact us.

var GROUPS_URL = "";
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 MARGIN_LEFT = 10;
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]] + ' ';
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'});
car.attr({'fill': train.hexcolor,
'fill-opacity': 0.5});
y -= car_height;
} { 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 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});
function update(paper){
$.getJSON(GROUPS_URL, function(data){ draw(data, paper); });
$(document).ready(function() {
var paper = Raphael("canvas", WIDTH, HEIGHT);
<!doctype html>
<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">
<div id="info">Click a train for more info</div>
<div id="canvas"></div>
<script src=""></script>
<script src=""></script>
<script src="bartviz.js"></script>
html, body {
font-family: Helvetica, sans-serif;
height: 100%;
background: #111;
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
You can’t perform that action at this time.