Last active
April 11, 2017 18:30
-
-
Save maxkfranz/f64e811fc3311414e083 to your computer and use it in GitHub Desktop.
Tokyo railways demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="[Tokyo railways]" /> | |
<meta charset=utf-8 /> | |
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui"> | |
<title>Tokyo railways</title> | |
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" /> | |
<link href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.css" rel="stylesheet" /> | |
<link href="style.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="cy"></div> | |
<div id="loading"> | |
<span class="fa fa-refresh fa-spin"></span> | |
</div> | |
<button id="clear">CLEAR</button> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.3/fastclick.min.js"></script> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> | |
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"></script> | |
<script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-qtip/2.7.0/cytoscape-qtip.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/1.2.2/bluebird.min.js"></script> | |
<script src="tokyo-railways.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
font: 14px helvetica neue, helvetica, arial, sans-serif; | |
width: 100%; | |
height: 100%; | |
margin: 0; | |
padding: 0; | |
} | |
#cy { | |
position: absolute; | |
left: 0; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
background: #000; | |
} | |
#loading { | |
position: absolute; | |
left: 0; | |
top: 50%; | |
width: 100%; | |
text-align: center; | |
margin-top: -0.5em; | |
font-size: 2em; | |
color: #fff; | |
} | |
#loading.loaded { | |
display: none; | |
} | |
button { | |
font-size: 2em; | |
background-color: #FC4C4C; | |
color: #fff; | |
border: 0; | |
cursor: pointer; | |
border-radius: 0.25em; | |
font-family: helvetica neue, helvetica, arial, sans-serif; | |
outline: 0; | |
} | |
#clear { | |
position: absolute; | |
right: 0; | |
top: 0; | |
margin: 0.25em; | |
visibility: hidden; | |
} | |
body.has-start #clear { | |
visibility: visible; | |
} | |
#end { | |
display: none; | |
} | |
body.has-start:not(.has-end) #end { | |
display: inline; | |
} | |
body.has-start:not(.has-end) #start { | |
display: none; | |
} | |
body.calc #loading { | |
display: block; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This demo visualises the railway stations in Tokyo (東京) as a graph. | |
This demo gives examples of | |
- loading elements via ajax | |
- loading style via ajax | |
- using the preset layout with predefined positions in each element | |
- using motion blur for smoother viewport experience | |
- using `min-zoomed-font-size` to show labels only when needed for better performance | |
*/ | |
$(function(){ | |
// get exported json from cytoscape desktop via ajax | |
var graphP = $.ajax({ | |
url: 'https://cdn.rawgit.com/maxkfranz/934042c1ecc464a8de85/raw', // tokyo-railways.json | |
type: 'GET', | |
dataType: 'json' | |
}); | |
// also get style via ajax | |
var styleP = $.ajax({ | |
url: 'https://cdn.rawgit.com/maxkfranz/2c23fe9a23d0cc8d43af/raw/6b4cd5f5f9eb9390c0600ad0ca11d4f51821feaf/gistfile1.txt', // tokyo-railways-style.cycss | |
type: 'GET', | |
dataType: 'text' | |
}); | |
// when both graph export json and style loaded, init cy | |
Promise.all([ graphP, styleP ]).then(initCy); | |
function initCy( then ){ | |
var loading = document.getElementById('loading'); | |
var expJson = then[0]; | |
var styleJson = then[1]; | |
var elements = expJson.elements; | |
loading.classList.add('loaded'); | |
var cy = window.cy = cytoscape({ | |
container: document.getElementById('cy'), | |
layout: { name: 'preset' }, | |
style: styleJson, | |
elements: elements, | |
motionBlur: true, | |
selectionType: 'single', | |
boxSelectionEnabled: false | |
}); | |
mendData(); | |
bindRouters(); | |
} | |
function mendData(){ | |
// because the source data doesn't connect nodes properly, use the cytoscape api to mend it: | |
cy.startBatch(); | |
// put nodes in bins based on name | |
var nodes = cy.nodes(); | |
var bin = {}; | |
var metanames = []; | |
for( var i = 0; i < nodes.length; i++ ){ | |
var node = nodes[i]; | |
var name = node.data('station_name'); | |
var nbin = bin[ name ] = bin[ name ] || []; | |
nbin.push( node ); | |
if( nbin.length === 2 ){ | |
metanames.push( name ); | |
} | |
} | |
// connect all nodes together with walking edges | |
for( var i = 0; i < metanames.length; i++ ){ | |
var name = metanames[i]; | |
var nbin = bin[ name ]; | |
for( var j = 0; j < nbin.length; j++ ){ | |
for( var k = j + 1; k < nbin.length; k++ ){ | |
var nj = nbin[j]; | |
var nk = nbin[k]; | |
cy.add({ | |
group: 'edges', | |
data: { | |
source: nj.id(), | |
target: nk.id(), | |
is_walking: true | |
} | |
}); | |
//.css({ | |
// 'line-color': 'yellow' | |
// }); | |
} | |
} | |
} | |
cy.endBatch(); //.autolock( true ); | |
} | |
var start, end; | |
var $body = $('body'); | |
function selectStart( node ){ | |
clear(); | |
$body.addClass('has-start'); | |
start = node; | |
start.addClass('start'); | |
} | |
function selectEnd( node ){ | |
$body.addClass('has-end calc'); | |
end = node; | |
cy.startBatch(); | |
end.addClass('end'); | |
setTimeout(function(){ | |
var aStar = cy.elements().aStar({ | |
root: start, | |
goal: end, | |
weight: function( e ){ | |
if( e.data('is_walking') ){ | |
return 0.25; // assume very little time to walk inside stn | |
} | |
return e.data('is_bullet') ? 1 : 3; // assume bullet is ~3x faster | |
} | |
}); | |
if( !aStar.found ){ | |
$body.removeClass('calc'); | |
clear(); | |
cy.endBatch(); | |
return; | |
} | |
cy.elements().not( aStar.path ).addClass('not-path'); | |
aStar.path.addClass('path'); | |
cy.endBatch(); | |
$body.removeClass('calc'); | |
}, 300); | |
} | |
function clear(){ | |
$body.removeClass('has-start has-end'); | |
cy.elements().removeClass('path not-path start end'); | |
} | |
function bindRouters(){ | |
var $clear = $('#clear'); | |
cy.nodes().qtip({ | |
content: { | |
text: function(){ | |
var $ctr = $('<div class="select-buttons"></div>'); | |
var $start = $('<button id="start">START</button>'); | |
var $end = $('<button id="end">END</button>'); | |
$start.on('click', function(){ | |
var n = cy.$('node:selected'); | |
selectStart( n ); | |
n.qtip('api').hide(); | |
}); | |
$end.on('click', function(){ | |
var n = cy.$('node:selected'); | |
selectEnd( n ); | |
n.qtip('api').hide(); | |
}); | |
$ctr.append( $start ).append( $end ); | |
return $ctr; | |
} | |
}, | |
show: { | |
solo: true | |
}, | |
position: { | |
my: 'top center', | |
at: 'bottom center', | |
adjust: { | |
method: 'flip' | |
} | |
}, | |
style: { | |
classes: 'qtip-bootstrap', | |
tip: { | |
width: 16, | |
height: 8 | |
} | |
} | |
}); | |
$clear.on('click', clear); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment