Last active
March 8, 2020 09:24
-
-
Save maxkfranz/cde4db55e581d10405f5 to your computer and use it in GitHub Desktop.
wine-and-cheese-demo
This file contains hidden or 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
dummy file to create gist |
This file contains hidden or 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 wine and cheese pairings. | |
*/ | |
$(function(){ | |
var layoutPadding = 50; | |
var layoutDuration = 500; | |
// get exported json from cytoscape desktop via ajax | |
var graphP = $.ajax({ | |
url: 'https://cdn.rawgit.com/maxkfranz/3d4d3c8eb808bd95bae7/raw', // wine-and-cheese.json | |
type: 'GET', | |
dataType: 'json' | |
}); | |
// also get style via ajax | |
var styleP = $.ajax({ | |
url: 'https://cdn.rawgit.com/maxkfranz/9210c03a591f8736b82d/raw', // wine-and-cheese-style.cycss | |
type: 'GET', | |
dataType: 'text' | |
}); | |
var infoTemplate = Handlebars.compile([ | |
'<p class="ac-name">{{name}}</p>', | |
'<p class="ac-node-type"><i class="fa fa-info-circle"></i> {{NodeTypeFormatted}} {{#if Type}}({{Type}}){{/if}}</p>', | |
'{{#if Milk}}<p class="ac-milk"><i class="fa fa-angle-double-right"></i> {{Milk}}</p>{{/if}}', | |
'{{#if Country}}<p class="ac-country"><i class="fa fa-map-marker"></i> {{Country}}</p>{{/if}}', | |
'<p class="ac-more"><i class="fa fa-external-link"></i> <a target="_blank" href="https://duckduckgo.com/?q={{name}}">More information</a></p>' | |
].join('')); | |
// when both graph export json and style loaded, init cy | |
Promise.all([ graphP, styleP ]).then(initCy); | |
function highlight( node ){ | |
var nhood = node.closedNeighborhood(); | |
cy.batch(function(){ | |
cy.elements().not( nhood ).removeClass('highlighted').addClass('faded'); | |
nhood.removeClass('faded').addClass('highlighted'); | |
var npos = node.position(); | |
var w = window.innerWidth; | |
var h = window.innerHeight; | |
cy.stop().animate({ | |
fit: { | |
eles: cy.elements(), | |
padding: layoutPadding | |
} | |
}, { | |
duration: layoutDuration | |
}).delay( layoutDuration, function(){ | |
nhood.layout({ | |
name: 'concentric', | |
padding: layoutPadding, | |
animate: true, | |
animationDuration: layoutDuration, | |
boundingBox: { | |
x1: npos.x - w/2, | |
x2: npos.x + w/2, | |
y1: npos.y - w/2, | |
y2: npos.y + w/2 | |
}, | |
fit: true, | |
concentric: function( n ){ | |
if( node.id() === n.id() ){ | |
return 2; | |
} else { | |
return 1; | |
} | |
}, | |
levelWidth: function(){ | |
return 1; | |
} | |
}); | |
} ); | |
}); | |
} | |
function clear(){ | |
cy.batch(function(){ | |
cy.$('.highlighted').forEach(function(n){ | |
n.animate({ | |
position: n.data('orgPos') | |
}); | |
}); | |
cy.elements().removeClass('highlighted').removeClass('faded'); | |
}); | |
} | |
function showNodeInfo( node ){ | |
$('#info').html( infoTemplate( node.data() ) ).show(); | |
} | |
function hideNodeInfo(){ | |
$('#info').hide(); | |
} | |
function initCy( then ){ | |
var loading = document.getElementById('loading'); | |
var expJson = then[0]; | |
var styleJson = then[1]; | |
var elements = expJson.elements; | |
elements.nodes.forEach(function(n){ | |
var data = n.data; | |
data.NodeTypeFormatted = data.NodeType; | |
if( data.NodeTypeFormatted === 'RedWine' ){ | |
data.NodeTypeFormatted = 'Red Wine'; | |
} else if( data.NodeTypeFormatted === 'WhiteWine' ){ | |
data.NodeTypeFormatted = 'White Wine'; | |
} | |
n.data.orgPos = { | |
x: n.position.x, | |
y: n.position.y | |
}; | |
}); | |
loading.classList.add('loaded'); | |
var cy = window.cy = cytoscape({ | |
container: document.getElementById('cy'), | |
layout: { name: 'preset', padding: layoutPadding }, | |
style: styleJson, | |
elements: elements, | |
motionBlur: true, | |
selectionType: 'single', | |
boxSelectionEnabled: false, | |
autoungrabify: true | |
}); | |
cy.on('free', 'node', function( e ){ | |
var n = e.cyTarget; | |
var p = n.position(); | |
n.data('orgPos', { | |
x: p.x, | |
y: p.y | |
}); | |
}); | |
cy.on('tap', function(){ | |
$('#search').blur(); | |
}); | |
cy.on('select', 'node', function(e){ | |
var node = this; | |
highlight( node ); | |
showNodeInfo( node ); | |
}); | |
cy.on('unselect', 'node', function(e){ | |
var node = this; | |
clear(); | |
hideNodeInfo(); | |
}); | |
} | |
$('#search').typeahead({ | |
minLength: 2, | |
highlight: true, | |
}, | |
{ | |
name: 'search-dataset', | |
source: function( query, cb ){ | |
function matches( str, q ){ | |
str = (str || '').toLowerCase(); | |
q = (q || '').toLowerCase(); | |
return str.match( q ); | |
} | |
var fields = ['name', 'NodeType', 'Country', 'Type', 'Milk']; | |
function anyFieldMatches( n ){ | |
for( var i = 0; i < fields.length; i++ ){ | |
var f = fields[i]; | |
if( matches( n.data(f), query ) ){ | |
return true; | |
} | |
} | |
return false; | |
} | |
function getData(n){ | |
var data = n.data(); | |
return data; | |
} | |
function sortByName(n1, n2){ | |
if( n1.data('name') < n2.data('name') ){ | |
return -1; | |
} else if( n1.data('name') > n2.data('name') ){ | |
return 1; | |
} | |
return 0; | |
} | |
var res = cy.nodes().stdFilter( anyFieldMatches ).sort( sortByName ).map( getData ); | |
cb( res ); | |
}, | |
templates: { | |
suggestion: infoTemplate | |
} | |
}).on('typeahead:selected', function(e, entry, dataset){ | |
var n = cy.getElementById(entry.id); | |
n.select(); | |
showNodeInfo( n ); | |
}); | |
$('#reset').on('click', function(){ | |
cy.animate({ | |
fit: { | |
eles: cy.elements(), | |
padding: layoutPadding | |
}, | |
duration: layoutDuration | |
}); | |
}); | |
$('#filters').on('click', 'input', function(){ | |
var soft = $('#soft').is(':checked'); | |
var semiSoft = $('#semi-soft').is(':checked'); | |
var na = $('#na').is(':checked'); | |
var semiHard = $('#semi-hard').is(':checked'); | |
var hard = $('#hard').is(':checked'); | |
var red = $('#red').is(':checked'); | |
var white = $('#white').is(':checked'); | |
var cider = $('#cider').is(':checked'); | |
cy.batch(function(){ | |
cy.nodes().forEach(function( n ){ | |
var type = n.data('NodeType'); | |
n.removeClass('filtered'); | |
var filter = function(){ | |
n.addClass('filtered'); | |
}; | |
if( type === 'Cheese' ){ | |
var cType = n.data('Type'); | |
if( | |
(cType === 'Soft' && !soft) | |
|| (cType === 'Semi-soft' && !semiSoft) | |
|| (cType === undefined && !na) | |
|| (cType === 'Semi-hard' && !semiHard) | |
|| (cType === 'Hard' && !hard) | |
){ | |
filter(); | |
} | |
} else if( type === 'RedWine' ){ | |
if( !red ){ filter(); } | |
} else if( type === 'WhiteWine' ){ | |
if( !white ){ filter(); } | |
} else if( type === 'Cider' ){ | |
if( !cider ){ filter(); } | |
} | |
}); | |
}); | |
}); | |
$('#filter').qtip({ | |
position: { | |
my: 'top center', | |
at: 'bottom center' | |
}, | |
show: { | |
event: 'click' | |
}, | |
hide: { | |
event: 'unfocus' | |
}, | |
style: { | |
classes: 'qtip-bootstrap', | |
tip: { | |
width: 16, | |
height: 8 | |
} | |
}, | |
content: $('#filters') | |
}); | |
}); |
This file contains hidden or 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 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>Wine and cheese</title> | |
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" /> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> | |
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">--> | |
<link href="style.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div id="cy"></div> | |
<div id="loading"> | |
<span class="fa fa-refresh fa-spin"></span> | |
</div> | |
<div id="search-wrapper"> | |
<input type="text" class="form-control" id="search" autofocus placeholder="Search"> | |
</div> | |
<div id="info"> | |
</div> | |
<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="../cytoscape.js/build/cytoscape.js"></script>--> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"></script> | |
<link href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.css" rel="stylesheet" type="text/css" /> | |
<script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-qtip/2.2.3/cytoscape-qtip.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/bluebird/1.2.2/bluebird.min.js"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.4/typeahead.bundle.js"></script> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.2/handlebars.min.js"></script> | |
<script src="demo.js"></script> | |
<button id="reset" class="btn btn-default"><i class="fa fa-arrows-h"></i></button> | |
<button id="filter" class="btn btn-default"><i class="fa fa-filter"></i></button> | |
<div id="filters"> | |
<strong>Cheese</strong> | |
<input id="soft" type="checkbox" checked></input><label for="soft">Soft</label><br /> | |
<input id="semi-soft" type="checkbox" checked></input><label for="semi-soft">Semi-soft</label><br /> | |
<input id="na" type="checkbox" checked></input><label for="na">N/A</label><br /> | |
<input id="semi-hard" type="checkbox" checked></input><label for="semi-hard">Semi-hard</label><br /> | |
<input id="hard" type="checkbox" checked></input><label for="hard">Hard</label> | |
<hr /> | |
<strong>Drink</strong> | |
<input id="white" type="checkbox" checked></input><label for="white">White wine</label><br /> | |
<input id="red" type="checkbox" checked></input><label for="red">Red wine</label><br /> | |
<input id="cider" type="checkbox" checked></input><label for="cider">Cider</label> | |
</div> | |
<a target="_blank" id="linkout" href="http://www.amazon.ca/Cheese-Connoisseurs-Guide-Worlds-Best/dp/1400050340/ref=sr_1_3?s=books&ie=UTF8&qid=1416109370&sr=1-3">Reference <i class="fa fa-external-link"></i></a> | |
</body> | |
</html> |
This file contains hidden or 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%; | |
} | |
#cy { | |
height: 100%; | |
width: 100%; | |
position: absolute; | |
left: 0; | |
top: 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; | |
} | |
#search-wrapper { | |
position: absolute; | |
left: 0; | |
top: 0; | |
z-index: 9999; | |
margin: 0.5em; | |
width: 14em; | |
} | |
#search { | |
width: 14em; | |
} | |
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; | |
} | |
.tt-dropdown-menu { | |
background: #fff; | |
width: 14em; | |
border-radius: 0.25em; | |
border: 1px solid #ccc; | |
max-height: 20em; | |
overflow: auto; | |
margin-top: 0.5em; | |
} | |
.tt-dropdown-menu * { | |
margin: 0; | |
padding: 0; | |
} | |
.tt-suggestion { | |
margin: 0; | |
padding: 0; | |
cursor: pointer; | |
} | |
.tt-suggestion + .tt-suggestion { | |
border-top: 1px solid #ccc; | |
} | |
.ac-name { | |
font-size: 1.25em; | |
} | |
.ac-node-type, | |
.ac-milk, | |
.ac-country, | |
.ac-more { | |
font-size: 0.8em; | |
} | |
#info { | |
position: absolute; | |
left: 0; | |
top: 3em; | |
margin: 0.5em; | |
background: #bbdbf7; | |
border-radius: 0.25em; | |
border: 1px solid #ccc; | |
width: 14em; | |
display: none; | |
} | |
#info p { | |
margin: 0; | |
} | |
#linkout { | |
position: absolute; | |
left: 0; | |
bottom: 0; | |
margin: 0.25em; | |
z-index: 999; | |
} | |
#reset, | |
#filter { | |
width: 3em; | |
margin: 0.5em; | |
position: absolute; | |
top: 0; | |
z-index: 999; | |
} | |
#reset { | |
right: 0; | |
} | |
#filter { | |
right: 4em; | |
} | |
#reset i { | |
transform: rotate(45deg); | |
} | |
#filters label { | |
font-weight: normal; | |
padding: 0 0.25em; | |
} | |
#filters strong { | |
display: block; | |
} | |
#filters hr { | |
margin: 0.25em 0; | |
} |
Hey I am newbee to use this, with database record of relations how to use in asp.net.
Can you help on this?
Thank you
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi your handlebar reference in the index.html file seems broken (line 39), you can update it with
https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js
I've forked to try and seems to work as expected (usually i would make a pull request but gist don't support them), thanks for the example anyway!