Skip to content
  1. Examples

Cycle detection

This example shows how to use the detectCycle algorithm. It makes it pulse, remove one of the edges and iterates until it has found all the cycles in the graph.

ts
import Ogma, { RawEdge } from '@linkurious/ogma';

const ogma = new Ogma({
  container: 'graph-container'
});

// show directions
ogma.styles.addEdgeRule({
  shape: 'arrow'
});

let removedEdges: RawEdge[] = [];

const showCycles = function () {
  const cycle = ogma.algorithms.detectCycle();
  if (cycle) {
    // highlight cycle
    const edges = cycle.getAdjacentEdges({ bothExtremities: true });
    cycle.addClass('cycle');
    edges.addClass('cycle');

    // break cycle after a delay
    setTimeout(() => {
      const edge = edges.get(0);

      // store edge to re-add it later
      removedEdges.push({
        source: edge.getSource().getId(),
        target: edge.getTarget().getId()
      });

      ogma.removeEdge(edges.get(0));
      cycle.removeClass('cycle');
      edges.removeClass('cycle');
      setTimeout(showCycles, 1000);
    }, 5000);
  } else {
    // no more cycles, re-add the removed edges
    ogma.addEdges(removedEdges);
    removedEdges = [];
    showCycles();
  }
};

// pulsing style for the cycles
ogma.styles.createClass({
  name: 'cycle',
  edgeAttributes: {
    color: 'red'
  },
  nodeAttributes: {
    color: 'red',
    pulse: {
      enabled: true,
      width: 10,
      startColor: 'inherit'
    }
  }
});

const graph = await Ogma.parse.jsonFromUrl('cycles.json');
await ogma.setGraph(graph);
await ogma.view.locateGraph();
showCycles();
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>
    <script type="module" src="index.ts"></script>
  </body>
</html>
css
#graph-container {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  position: absolute;
  margin: 0;
  overflow: hidden;
}
json
{
  "nodes": [
    {
      "id": "n200",
      "attributes": {
        "x": 39.142436225018,
        "y": -0.5842154660450447,
        "color": "grey",
        "radius": 5,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n0",
      "attributes": {
        "x": 56.74036116600037,
        "y": 97.1378225505352,
        "color": "grey",
        "radius": 11.448061400989705,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n1",
      "attributes": {
        "x": 92.22722430229187,
        "y": 34.1048425257206,
        "color": "grey",
        "radius": 7.283320680384795,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n2",
      "attributes": {
        "x": 37.531802129745486,
        "y": 52.45390073657036,
        "color": "grey",
        "radius": 13.114531802522045,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n3",
      "attributes": {
        "x": 91.67253193440872,
        "y": -51.54897544412437,
        "color": "grey",
        "radius": 5.531087259776539,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n4",
      "attributes": {
        "x": 62.30529743653053,
        "y": -43.91224828014665,
        "color": "grey",
        "radius": 13.401302636442988,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n5",
      "attributes": {
        "x": 10.324941574145008,
        "y": -31.101552464394146,
        "color": "grey",
        "radius": 11.30766775542554,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n6",
      "attributes": {
        "x": -20.354295778274533,
        "y": 5.0308317363262205,
        "color": "grey",
        "radius": 12.418940800685958,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n7",
      "attributes": {
        "x": -9.95489315986633,
        "y": 35.512355130910876,
        "color": "grey",
        "radius": 5.136967034694411,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n8",
      "attributes": {
        "x": 17.32530016899109,
        "y": 94.18722669482231,
        "color": "grey",
        "radius": 8.505061178641835,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": "n9",
      "attributes": {
        "x": 122.99585343445878,
        "y": -0.37240507928022737,
        "color": "grey",
        "radius": 11.02846944582491,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": 1243635270482804,
      "attributes": {
        "x": 69.94264680827793,
        "y": -21.971145698419313,
        "color": "grey",
        "radius": 5,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": 3588424111560522,
      "attributes": {
        "x": 68.33605427665405,
        "y": 19.069990791245083,
        "color": "grey",
        "radius": 5,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": 1792267149295216,
      "attributes": {
        "x": 80.45852519708873,
        "y": -89.30197816011074,
        "color": "grey",
        "radius": 5,
        "shape": "circle",
        "text": null
      }
    },
    {
      "id": 1406349046144336,
      "attributes": {
        "x": 20.23903582396599,
        "y": 22.860775518622443,
        "color": "grey",
        "radius": 5,
        "shape": "circle",
        "text": null
      }
    }
  ],
  "edges": [
    {
      "id": "e0",
      "source": "n2",
      "target": "n0",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e1",
      "source": "n9",
      "target": "n1",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e2",
      "source": "n6",
      "target": "n7",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e3",
      "source": "n2",
      "target": "n1",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e4",
      "source": "n7",
      "target": "n2",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e5",
      "source": "n4",
      "target": "n3",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e6",
      "source": "n5",
      "target": "n4",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e7",
      "source": "n8",
      "target": "n2",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e8",
      "source": "n0",
      "target": "n8",
      "attributes": {
        "color": "grey",
        "width": 1,
        "text": null
      }
    },
    {
      "id": "e9",
      "so

...