All versions of this documentation
X

Minimum Spanning Tree


Open in a new window.
          <!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <script src="../build/ogma.min.js"></script>
  <style>
    #graph-container {
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      position: absolute;
      margin: 0;
      overflow: hidden;
    }

    .cleanup {
      position: absolute;
      top: 10px;
      left: 10px;
    }
  </style>
</head>

<body>
  <div id="graph-container">
  </div>
  <button class="cleanup" onclick="minimumSpanningTree()">Spanning
    Tree</button>

  <script>
    'use strict';

    const ogma = new Ogma({ container: 'graph-container' });
    const className = 'minimum-spanning-tree';
    const secondaryClassName = 'secondary';

    ogma.styles.createClass({
      name: className,
      nodeAttributes: {
        color: '#55A3E8'
      },
      edgeAttributes: {
        color: '#55A3E8',
        width: 4
      }
    });

    ogma.styles.createClass({
      name: secondaryClassName,
      edgeAttributes: {
        opacity: 0.2
      }
    });

    ogma.styles.addNodeRule({
      radius: 12
    });

    ogma.generate
      .erdosRenyi({ nodes: 150, edges: 2000 })
      .then(function (graph) {
        return ogma.setGraph(graph);
      })
      .then(function () {
        return ogma.layouts.force({ duration: 0 });
      })
      .then(function () {
        ogma.view.locateGraph({ duration: 500 });
      });

    function minimumSpanningTree() {
      const subGraphs = ogma.algorithms.minimumSpanningTree();
      const visible = {};
      subGraphs.forEach(function (subGraph) {
        subGraph.edges.forEach(function (edge) {
          visible[edge.getId()] = true;
        });
      });

      ogma.getEdges()
        .filter(function (edge) {
          return !visible[edge.getId()];
        })
        .setAttributes({ opacity: 0.2, detectable: false });

      const edges = ogma.getEdges().filter(function (edge) {
        return visible[edge.getId()];
      });
      const nodes = edges.getExtremities().dedupe();
      edges.addClass(className);
      ogma.getNodes().addClass(className);
      edges.inverse().addClass(secondaryClassName);

      return ogma.layouts.force({
        locate: true,
        gravity: 0, // to let the tree spead over the larger surface
        edges: edges // so that the secondary edges have no influence on the layout
      });
    }
  </script>
</body>

</html>