All versions of this documentation
X

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" /> &theta; (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="&hellip;">&hellip;</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>