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>