jQuery SVG Railroad

Download

Fork me on GitHub

I spiked up a tool, in my first few months at WDS, that was for displaying the Kanban stories that were associated with Git commits, and which of those stories were on the various servers. To do that, I created this widget which displays a vertical tube-map (or metro map) display of events (stations).

Here's an example of the type of thing I'm talking about:

$('#demo').railroad();
$('#demo').railroad( "addEndStop", 
	"Elephant & Castle", 
	"End of the Line", "eadnc", "up");
$('#demo').railroad( "addStation", 
	"Lambeth North", "", "ln");
$('#demo').railroad( "addIntersectingLine", 
	"Jubilee Line", "", "jl", 
	"#868F98", "down" );
$('#demo').railroad( "addIntersectionStation", 
	"Waterloo", "", "wl" );
$('#demo').railroad( "addPredictedLine" );
		

You can see that the map shows main line stations, minor stations and intersections. It can be as long as you want, and include as many stations as you like in whatever order.

Creating a Railroad

So, to create one you simply create a div and apply the widget to it:

<div id="railroad"></div>
...
$('#railroad').railroad();

Note that once this is done you will not see anything, as you have to add the 'railroad blocks' to the railroad. See the following sections for the blocks available to make your railroad.

The width of the railroad can be adjusted using the railroadElementWidth initialisation option, which sets the width of the SVG element. If you adjust the station stub sizes or the intersecting station size, you may need to widen the SVG.

<div id="railroad"></div>
...
$('#railroad').railroad( { railroadElementWidth: 100 } );

End Stop

An end-of-line railroad block can be added by calling the addEndStop method. This method takes the name of the end stop, some info to place next to the stop, an identifier to add to the stop element and a direction which is either up or down.

$('#railroad').railroad("addEndStop", 
        "Station", "info", "id1", "up" );
		
$('#railroad').railroad("addEndStop", 
        "Station", "info", "id2", "down" );
		

Minor Station

To add a minor stop to the railroad call the addStation method. This method takes the name of the stop, some info to show next to the stop, and an identifier to attach to the DOM element.

$('#railroad').railroad("addStation", 
        "Station", "info", "id3" );
		

The length of the 'stub' shown on the line can be set using the stationStubLength option.

$('#railroad').railroad({ stationStubLength: 40 });
$('#railroad').railroad("addStation", 
        "Station", "info", "id3" );
		

The height of the station can also be adjusted using the stationSize option, which affects both the minor and major station sizes.

$('#railroad').railroad({ stationSize: 100 });
$('#railroad').railroad("addStation", 
        "Station", "info", "id3" );
		

Major Station

To add a major stop to the railroad call the addIntersectionStation method. This method takes the name of the stop, some info to show next to the stop, and an identifier to attach to the DOM element.

$('#railroad').railroad("addIntersectionStation", 
        "Station", "info", "id3" );
		

Predicted/Incomplete Line

To add a predicted or incomplete line into the diagram (useful where you want to the railroad to appear to continue into the distance), you can call the addPredictedLine method.

$('#railroad').railroad( "addPredictedLine" );
		

Line Intersections

You can add line intersections using the addIntersectingLine method. This method draws another railroad coming from the right and joining into the main line. This can be done in an upwards or downwards direction. It takes parameters for the name of the new line, some info about the new line, an identifier to attach to the new line's DOM element, the colour of the new line and the direction in which it should join the main line. Again, the direction can be up or down.

$('#railroad').railroad( "addIntersectingLine", "Line",
		"info", "line1", "yellow", "up" );
		
$('#railroad').railroad( "addIntersectingLine", "Line",
		"info", "line1", "yellow", "down" );
		

Colour

You've seen how to set the colour of intersecting lines, but to set the colour of the main line you can pass in an initialisation option colour. Note that this does not change the colour of the stations. You must also use stationColour if you want the stations to match the colour of the line.

$('#railroad').railroad( { 
	colour: '#AA00AA',
	stationColour: '#AA00AA'
});
$('#railroad').railroad( "addEndStop", "End", "", "", "up" );
$('#railroad').railroad( "addStation", "Station", "", "" );
		

The colour of the main intersection station can be set using the intersectionColour option, as well as the intersectionCentreColour option.

$('#railroad').railroad( { 
	intersectionColour: '#0033DD',
	intersectionCentreColour: '#00AAAA'
});
$('#railroad').railroad( "addEndStop", "End", "", "", "up" );
$('#railroad').railroad( "addIntersectionStation", "Station", "", "" );
$('#railroad').railroad( "addPredictedLine" );
		

Other Options

The description for the stations that are passed in can be strings, as we've been showing, but they can also be jQuery objects. If they are jQuery objects they are appended into the DOM where the information would normally be shown. This allows you to make the information any other widget you can think of.

However, it's possible that other widgets may be larger than the default size of the station, or they may expand while in use. Therefore, the railroad widget allows you to specify an "overflow" for the railroad track which is invisible unless the div in which the railroad block is added gets expanded. To set the size of this overflow, use the expandedTrack initialisation option which sets the overflow in pixels.

var obj = $("<div>« Click Here »"+
  "<div>Here's a load of text that "+
  "will push the widget out of it's "+
  "default sizing and show the expanded "+
  "track.</div></div>")
  .click( function(evt) { 
     evt.preventDefault();
     $(this).children('div').toggle('fast'); } )
  .width( 150 );
obj.children( "div" ).hide();
$('#railroad').railroad( { expandedTrack: 400 } );
$('#railroad').railroad( 'addStation', 
	'Station', obj, 'id' );
		

Another function which may be useful, is the function to have the railroad the other way up. So, if the initialisation option newestAtTop is set to true the railroad elements will be prepended rather than appended. However, note that this does not swap the ups and downs.

$('#demo').railroad();
$('#demo').railroad( "addStation", 
	"Lambeth North", "", "ln");
$('#demo').railroad( "addIntersectingLine", 
	"Jubilee Line", "", "jl", 
	"#868F98", "down" );
$('#demo').railroad( "addIntersectionStation", 
	"Waterloo", "", "wl" );
$('#demo').railroad( "addPredictedLine" );
		
$('#demo').railroad({ newestAtTop: true });
$('#demo').railroad( "addStation", 
	"Lambeth North", "", "ln");
$('#demo').railroad( "addIntersectingLine", 
	"Jubilee Line", "", "jl", 
	"#868F98", "down" );
$('#demo').railroad( "addIntersectionStation", 
	"Waterloo", "", "wl" );
$('#demo').railroad( "addPredictedLine" );
		

Just one last thing is that the width of the railroad can be altered with the width property.

$('#demo').railroad({ width: 2 });
$('#demo').railroad( "addStation", 
	"Lambeth North", "", "ln");
$('#demo').railroad( "addIntersectingLine", 
	"Jubilee Line", "", "jl", 
	"#868F98", "down" );
$('#demo').railroad( "addPredictedLine" );
		

Installation

This component is available via the bower repository, so it's as easy as 1-2-3 to install:

	bower install jquery.railroad --save

Alternatively, just download the files you need: jquery.railroad.js and jquery.railroad.css.

Then just include the script tags in your HTML:

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="bower/jquery.railroad/js/jquery.railroad.js"></script>

Contributing

You can fork the code on Github (just hit the ribbon at the top).

Licensing

The code is released under the MIT license, which basically means you can do whatever you like except pretend it's yours.

Comments