Force layout large graph
Open in a new window.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../build/ogma.min.js"></script>
<style>
html, body { font-family: Helvetica, Arial, Helvetica, sans-serif; padding: 0; margin: 0; }
#graph-container { top: 0; bottom: 0; left: 0; right: 0; position: absolute; margin: 0; overflow: hidden; }
.control { position: absolute; top: 20px; right: 20px; padding: 10px; border-radius: 5px; box-shadow: 0 0 5px rgba(0,0,0,0.5); background: #fff; }
.control label { display: block; padding: 5px 0; }
.control p { text-align: center; }
.control .value { width: 50px; display: inline-block; font-family: Georgia, 'Times New Roman', Times, serif; font-weight: bold; }
.control #time { text-align: center; }
.info {
position: absolute;
color: #fff;
background: #141229;
font-size: 12px;
font-family: monospace;
padding: 5px;
}
.info.n { top: 0; left: 0; }
.info.e { top: 20px; left: 0; }
</style>
</head>
<body>
<div id="graph-container"></div>
<form class="control" id="params">
<label>
<span id="steps-value" class="value">80</span>
<input type="range" min="10" max="300" value="80" name="steps" step="10" /> Steps
</label>
<label>
<span id="charge-value" class="value">10</span>
<input type="range" min="0.5" max="50" value="10" name="charge" step="0.5" /> Charge
</label>
<label>
<span id="theta-value" class="value">0.81</span>
<input type="range" min="0.15" max="1" value="0.81" name="theta" step="0.01" /> θ (precision)
</label>
<label>
<span id="elasticity-value" class="value">0.1</span>
<input type="range" min="0" max="1.0" value="0.1" name="elasticity" step="0.01"/> Elasticity
</label>
<label>
<span id="gravity-value" class="value">0.01</span>
<input type="range" min="0.005" max="0.15" value="0.01" name="gravity" step="0.005" /> Gravity
</label>
<div id="time" data-placeholder="…">…</div>
<p><button type="button" id="randomize">Randomize</button><button type="button" id="run">Run</button></p>
</form>
<div id="n" class="info n">loading a large graph, it can take a few seconds...</div>
<div id="e" class="info e"></div>
<script>
'use strict';
var ogma = new Ogma({
container: 'graph-container',
options: { interactions: { drag: { enabled: false }}}
});
var padding = 100;
// generate random graph
ogma.parse.jsonFromUrl('files/relativity.json')
.then(function(graph) {
graph.nodes.forEach(function(node) {
node.attributes = { radius: 15, color: '#0E948A' };
});
graph.edges.forEach(function(edge) {
edge.attributes = { color: '#aaaaaa'};
});
document.getElementById('n').textContent = 'nodes: ' + graph.nodes.length;
document.getElementById('e').textContent = 'edges: ' + graph.edges.length;
return ogma.setGraph(graph);
}).then(function() {
randomize();
ogma.view.setZoom(0.1, { ignoreZoomLimits: true });
}).then(function() {
return run();
}).then(function() {
return ogma.view.locateGraph({ padding: padding });
});
var form = document.querySelector('#params');
var callTimer = 0;
var charge, gravity, theta, elasticity, steps;
function update () {
steps = parseFloat(form['steps'].value);
charge = parseFloat(form['charge'].value);
gravity = parseFloat(form['gravity'].value);
elasticity = parseFloat(form['elasticity'].value);
theta = parseFloat(form['theta'].value);
document.getElementById('steps-value').innerHTML = steps;
document.getElementById('charge-value').innerHTML = charge;
document.getElementById('gravity-value').innerHTML = gravity;
document.getElementById('elasticity-value').innerHTML = elasticity;
document.getElementById('theta-value').innerHTML = theta;
}
form.addEventListener('input', function () {
clearTimeout(callTimer);
update();
callTimer = setTimeout(run, 100);
}, true);
document.querySelector('#randomize').addEventListener('click', randomize);
document.querySelector('#run').addEventListener('click', function () { run(); });
function run (locate) {
var timeOutput = document.getElementById('time')
timeOutput.innerHTML = timeOutput.getAttribute('data-placeholder');
var start = Date.now();
return ogma.layouts.force({
steps: steps,
charge: charge,
theta: theta,
gravity: gravity,
elasticity: elasticity,
locate: locate
}).then(function () {
timeOutput.innerHTML = ((Date.now() - start) / 1000) + 's';
});
}
update();
function randomize () {
ogma.getNodes().forEach(function (node) {
node.setAttributes({
x: Math.random() * 150,
y: Math.random() * 150
});
});
}
</script>
</body>
</html>