toovio-playground
by peteorpeter
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/2.7.15/cytoscape.min.js"></script>
<script src="https://rawgit.com/tgdwyer/WebCola/master/WebCola/cola.min.js"></script>
<script src="https://rawgit.com/cytoscape/cytoscape.js-cola/master/cytoscape-cola.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"></script>
<div id="cy"></div>
<ul id="detail" style="display: none"></ul>
CSS
#cy {
width: 100vw;
height: 100vh;
background: white;
}
html * {
box-sizing: border-box;
}
#detail {
position: fixed;
bottom: 10px;
left: 20px;
background: rgba(0, 0, 0, .7);
color: white;
font-family: sans-serif;
padding: 10px;
border-radius: 10px;
}
#detail li {
display: block;
}
#detail em {
display: inline-block;
padding: 5px;
font-weight: lighter;
width: 100px;
text-align: right;
}
#detail strong {
padding: 5px;
}
JavaScript
function roll(fraction) {
return Math.random() < fraction;
}
function rando(min, max) {
return min + (Math.random() * (max - min));
}
// Generate some data
function generateElements() {
var elements = {
nodes: [],
edges: []
}
var MODEL_COUNT = 40;
var SEGMENT_COUNT = 20;
var EDGE_LIKELIHOOD = 0.1;
var models = [];
var segments = [];
_.times(MODEL_COUNT, function(i) {
models.push({
data: {
id: 'm' + i,
title: 'Model ' + i,
lift: rando(4, 8),
accept_rate: rando(1, 12),
volume: rando(500, 3000)
},
classes: 'model'
});
})
// Sort by... acc rate?
models = _.sortBy(models, function(model){
return model.data.accept_rate;
});
_.times(SEGMENT_COUNT, function(i) {
segments.push({
data: {
id: 's' + i,
title: 'Data ' + i,
},
classes: 'segment'
});
})
elements.nodes = models.concat(segments);
_.each(segments, function(source) {
_.each(models, function(target) {
if (roll(EDGE_LIKELIHOOD) && source.data.id !== target.data.id) {
elements.edges.push({
data: {
source: source.data.id,
target: target.data.id,
id: source.data.id + target.data.id,
boost: rando(1, 10)
}
});
}
})
});
console.log('generateElements', elements);
return elements;
}
var LAYOUT = {
name: 'concentric',
fit: true, // whether to fit the viewport to the graph
padding: 30, // the padding on fit
startAngle: 1 / 2 * Math.PI, // where nodes start in radians
sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)
clockwise: false, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
equidistant: false, // whether levels have an equal radial distance betwen them, may cause bounding box overflow
minNodeSpacing: 10, // min spacing between...