Animate to bounds
This example shows how you can animate the transition of camera to parts of the
graph so that the user doesn't lose focus. You can control the animation easing
and the replay.
Open in a new window.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../build/ogma.min.js"></script>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/solid.min.css"
rel="stylesheet">
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/fontawesome.min.css"
rel="stylesheet">
<style>
#graph-container {
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: 0;
overflow: hidden;
}
#controls {
font-family: Georgia, 'Times New Roman', Times, serif;
position: absolute;
background: #ffffff;
padding: 15px;
top: 20px;
right: 20px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
border-radius: 5px;
}
</style>
</head>
<body>
<div id="graph-container"></div>
<div id="controls">
<label>Easing
<select id="easing">
<option value="linear">linear</option>
<option value="quadraticIn">quadraticIn</option>
<option value="quadraticOut">quadraticOut</option>
<option value="quadraticInOut">quadraticInOut</option>
<option value="cubicIn">cubicIn</option>
<option value="cubicOut">cubicOut</option>
<option value="cubicInOut">cubicInOut</option>
</select>
</label>
<p>
<label><input type="checkbox" id="play-button" checked>Repeat</label>
<button id="step-button" disabled><i
class="fas fa-step-forward"></i></button>
</p>
</div>
<script>
'use strict';
const ogma = new Ogma({
container: 'graph-container'
});
function zoomToRandomHub() {
// get the list of big hubs
const nodes = ogma.getNodes();
const highDegreeNodes = ogma.getNodes().filter(function (n) {
return n.getDegree() > 15;
});
const root = highDegreeNodes.get(
Math.floor(Math.random() * highDegreeNodes.size)
);
// get a random hub
const randomHub = root
.getAdjacentNodes()
.filter(function (n) {
return n.getDegree() === 1;
})
.concat(root);
// highlight the hub
nodes.setSelected(false);
randomHub.setSelected(true);
// animate to it
return ogma.view.moveToBounds(randomHub.getBoundingBox(), {
easing: document.getElementById('easing').value
});
}
ogma.generate
.barabasiAlbert({
nodes: 1600,
m0: 10,
m: 1
})
.then(ogma.setGraph)
.then(function () {
return ogma.layouts.force({
autoStop: true,
gravity: 0.001,
duration: 0
});
})
.then(ogma.view.locateGraph)
.then(function () {
return setTimeout(startAnimation, 500);
});
const playButton = document.getElementById('play-button');
const stepButton = document.getElementById('step-button');
let timer = 0;
let animating = playButton.checked;
function animate() {
if (animating) {
zoomToRandomHub().then(function () {
timer = setTimeout(animate, 1000);
});
}
}
function startAnimation() {
if (!animating) {
animating = true;
animate();
stepButton.setAttribute('disabled', 'disabled');
} else {
clearTimeout(timer);
animating = false;
stepButton.removeAttribute('disabled');
}
}
function step() {
zoomToRandomHub();
}
playButton.addEventListener('click', startAnimation);
stepButton.addEventListener('click', step);
startAnimation();
</script>
</body>
</html>