Skip to content

Instantly share code, notes, and snippets.

@anbnyc
Last active February 13, 2017 02:06
Show Gist options
  • Save anbnyc/6130f9a6a6dd82a70290e748cb5fc9db to your computer and use it in GitHub Desktop.
Save anbnyc/6130f9a6a6dd82a70290e748cb5fc9db to your computer and use it in GitHub Desktop.
Subway (1) line as network graph

#Subway (1) Line as Network Graph

Created using Vis.js

I set out to create a map of the entire subway as a network graph. I got bogged down with cleaning the data, which I drew from two NYC Open Data sets. Until I can get the full subway system working, here is what one subway line looks like.

Data sources

The subway stations data set does not indicate the order of the stations, and the lines dataset does not have the stations in it. I'm working on devising a better system of placing stations on the lines, but in the mean time I have resorted to a heuristic where a station is on a line if it is "close enough" to the line.

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.18.1/vis.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
crossorigin="anonymous"></script>
<style>
#mynetwork {
width: 900px;
height: 600px;
border: 1px solid lightgray;
}
</style>
</head>
<body>
<div id="mynetwork"></div>
</body>
<script>
var stations, lines;
$.when(
$.get('https://data.cityofnewyork.us/resource/kk4q-3rt2.json', function(response){
stations = response;
}),
$.get('https://data.cityofnewyork.us/resource/s7zz-qmyz.json', function(response){
lines = response;
})
).then(function(){
loadData(stations,lines);
})
function loadData(stations,lines){
var stationsSplit = {}
_.each(stations,function(o){
_.each(o.line.split("-"),function(line){
if(!stationsSplit[line]){
stationsSplit[line] = [];
}
var newstation = {label: o.name, id: o.objectid, coords: o.the_geom.coordinates}
stationsSplit[line].push(newstation);
});
});
linesSplit = {}
_.each(lines,function(o){
_.each(o.name.split("-"),function(line){
if(!linesSplit[line]){
linesSplit[line]=[];
}
linesSplit[line].push({id: o.id, coords: o.the_geom.coordinates})
});
});
for(var k in linesSplit){
linesSplit[k].sort(function(a,b){
return a.id - b.id;
});
var last = [];
linesSplit[k] = _.reduce(linesSplit[k],function(t,v){
if(_.isEqual(v,last)){
last = v;
return t;
} else {
last = v;
return t.concat(v.coords);
}
},[]);
}
var edges = {};
for(var k in linesSplit){
edges[k] = [];
var last = "";
for(var i = 1; i < linesSplit[k].length; i++){
_.each(stationsSplit[k],function(station){
if(isCloseEnough(station.coords,linesSplit[k][i])){
if(last !== "" && last !== station.id){
edges[k].push({from:last,to:station.id});
}
last = station.id;
}
});
}
}
function isCloseEnough(coords1,coords2,tolerance=0.00001){
return Math.abs(coords1[0] - coords2[0])/coords1[0] < tolerance &&
Math.abs(coords1[1] - coords2[1])/coords1[1] < tolerance
}
var whichline = "1";
var nodes = new vis.DataSet(stationsSplit[whichline]);
var edges = new vis.DataSet(edges[whichline]);
var container = document.getElementById("mynetwork");
var data = { nodes: nodes, edges: edges };
var network = new vis.Network(container, data, { layout: { improvedLayout: false }});
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment