All versions of this documentation
X

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>