Appearance
Force layout auto-stop
This example shows how to use the autostop
option, which makes the force layout much faster on graphs already layed out or partially layed out. It is usefull when adding or removing nodes and edges to the graph.
ts
import Ogma, { LocateOptions, RawGraph } from '@linkurious/ogma';
const ogma = new Ogma({
container: 'graph-container',
options: { interactions: { drag: { enabled: false } } }
});
const padding = 100;
const animationDuration = 300;
// disable node dragging
//ogma.setOptions({ interactions: { drag: { enabled: false }}});
// generate random graph
Ogma.parse
.jsonFromUrl('files/relativity.json')
.then(graph => {
// add some disconnected components and 'orphan' nodes
graph.nodes.forEach(node => {
delete node.attributes;
});
return ogma.setGraph(graph);
})
.then(() => ogma.view.locateGraph({ padding: 100 }))
.then(() => run({ padding: padding }));
const form = document.querySelector<HTMLFormElement>('#params')!;
let callTimer = 0;
let charge: number, gravity: number, edgeStrength: number, autoStop: boolean;
function update() {
charge = parseFloat(form['charge'].value);
gravity = parseFloat(form['gravity'].value);
edgeStrength = parseFloat(form['edgeStrength'].value);
autoStop = form['auto-stop'].checked;
document.getElementById('charge-value')!.innerHTML = charge.toString();
document.getElementById('gravity-value')!.innerHTML = gravity.toString();
document.getElementById('edgeStrength-value')!.innerHTML =
edgeStrength.toString();
}
form.addEventListener(
'input',
function () {
clearTimeout(callTimer);
update();
callTimer = setTimeout(run, 100) as unknown as number;
},
true
);
document.querySelector('#randomize')!.addEventListener('click', randomize);
document.querySelector('#run')!.addEventListener('click', function () {
run();
});
function run(locate?: LocateOptions) {
const start = Date.now();
return ogma.layouts
.force({
charge: charge,
gravity: gravity,
locate: locate,
duration: animationDuration,
edgeStrength: edgeStrength,
autoStop: autoStop
})
.then(() => {
const duration = Date.now() - start;
document.getElementById('time')!.innerHTML =
'done in ' + ((duration - animationDuration) / 1000).toFixed(2) + 's';
});
}
update();
function addSmallComponents(graph: RawGraph, n: number, m: number) {
for (let i = 0; i < n; i++) {
const baseId = graph.nodes.length;
for (let j = 0; j < m + 1; j++) {
graph.nodes.push({ id: baseId + j });
}
for (let k = 1; k < m + 1; k++) {
graph.edges.push({ source: baseId, target: baseId + k });
}
}
}
function randomize() {
ogma.getNodes().forEach(node => {
node.setAttributes({
x: Math.random() * 150,
y: Math.random() * 150
});
});
}
html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="graph-container"></div>
<form class="control" id="params">
<label>
<span id="charge-value" class="value">5</span>
<input
type="range"
min="0.5"
max="50"
value="5"
name="charge"
step="0.5"
/>
Charge
</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>
<label>
<span id="edgeStrength-value" class="value">0.75</span>
<input
type="range"
min="0.0"
max="30"
value="0.75"
name="edgeStrength"
step="0.25"
/>
Edge strength
</label>
<label>
<input type="checkbox" checked name="auto-stop" /> Auto stop
</label>
<p>
<button type="button" id="randomize">Randomize</button
><button type="button" id="run">Run</button>
</p>
<div id="time"></div>
</form>
<script type="module" src="index.ts"></script>
</body>
</html>
css
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;
}
#time {
text-align: center;
font-family: Georgia, 'Times New Roman', Times, serif;
}