Hierarchical advanced
The selected node is used as top of the hierarchy: click to change it dynamically.
Click an edge to make its extremities the top of the layout.
Play with the parameters of the layout to tweak the final result:
- Regulate the vertical and horizontal distance of the layout
- Chose the orientation of the layout with the direction select box
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;
}
#ui {
font-family: Helvetica, Arial, sans-serif;
}
h4 {
margin: 15px 5px 5px 5px;
}
.toolbar {
display: block;
position: absolute;
top: 20px;
right: 20px;
padding: 0 10px 10px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
border-radius: 4px;
background: #ffffff;
color: #222222;
font-weight: 300;
}
.toolbar .section {
position: relative;
display: block;
}
.toolbar .section h4 {
display: block;
font-weight: 300;
border-bottom: 1px solid #ddd;
color: #606060;
font-size: 1rem;
}
.controls {
margin-top: 15px;
clear: both;
}
.controls select {
width: 100%;
clear: both;
}
</style>
</head>
<body>
<div id="graph-container"></div>
<div class="toolbar" id="ui">
<div class="section">
<h4>Layout parameters</h4>
<div class="controls">
<label for="vertical">Level Distance</label>
<input type="range" id="vertical" name="levelDistance" min="25" max="100" value="50">
</div>
<div class="controls">
<label for="horizontal">Node Distance</label>
<input type="range" id="horizontal" name="nodeDistance" min="25" max="100" value="50">
</div>
<div class="controls">
<label for="horizontal">Component Distance</label>
<input type="range" id="component" name="componentDistance" min="1" max="100" value="25">
</div>
<div class="controls">
<label>Change Direction:</label>
<select name="directionMode" id="directionMode">
<option value="TB">Top Down</option>
<option value="BT">Bottom Up</option>
<option value="LR">Left to Right</option>
<option value="RL">Right to Left</option>
</select>
</div>
<div class="controls">
<label>Arrange Components:</label>
<select name="arrangeMode" id="arrangeMode">
<option value="fit">Fit</option>
<option value="grid">Grid</option>
<option value="singleLine">Single Line</option>
</select>
</div>
</div>
</div>
<script>
'use strict';
var ogma = new Ogma({
container: 'graph-container',
});
var defaultLayoutOptions = {
direction: 'TB', // Direction of the layout. Can be TB, BT, LR, or RL,
// where T = top, B = bottom, L = left, and R = right.
duration: 300, // Duration of the animation
nodeDistance: 50, // Number of pixels that separate nodes horizontally in the layout.
levelDistance: 50, // Number of pixels between each layer in the layout.
componentDistance: 50, // Number of pixels between each component in the layout.
arrangeComponents: 'fit'
};
ogma.generate.balancedTree({
children: 2,
height: 5
}).then(function (graph) {
// add some extra nodes to show multi-component packing
var extraNodes = Array.from({ length: 25 }).map(function (_, i) {
return { id: 1000 + i };
});
graph.nodes = graph.nodes.concat(extraNodes);
return ogma.setGraph(graph);
}).then(function () {
ogma.getNode(0).setSelected(true);
runWithUIParameters();
});
function runLayout(options) {
// Run layout
ogma.layouts.hierarchical(options)
.then(function () {
console.log('done');
ogma.view.locateGraph({
easing: 'linear',
duration: 300
});
});
}
ogma.events.onClick(function (evt) {
var target = evt.target;
// If the user clicked a node set it as root,
// otherwise pick the link ends and make them roots
if (target) {
if (target.isNode) {
target.setSelected(true);
} else {
target.getExtremities().setSelected(true);
}
}
runWithUIParameters();
});
// UI controls
var horizontalDistanceInput = document.getElementById('horizontal');
var verticalDistanceInput = document.getElementById('vertical');
var directionSelectInput = document.getElementById('directionMode');
var arrangeSelectInput = document.getElementById('arrangeMode');
var componentDistanceInput = document.getElementById('component');
horizontalDistanceInput.addEventListener('change', runWithUIParameters);
verticalDistanceInput.addEventListener('change', runWithUIParameters);
componentDistanceInput.addEventListener('change', runWithUIParameters);
directionSelectInput.addEventListener('change', runWithUIParameters);
arrangeSelectInput.addEventListener('change', runWithUIParameters);
function runWithUIParameters() {
// create fresh new options
var newOptions = {};
for (var prop in defaultLayoutOptions) {
newOptions[prop] = defaultLayoutOptions[prop];
}
// pass the roots to the layout
newOptions.roots = ogma.getSelectedNodes();
// now add the chosen one
newOptions.direction = directionSelectInput.value;
newOptions.nodeDistance = + horizontalDistanceInput.value;
newOptions.levelDistance = + verticalDistanceInput.value;
newOptions.componentDistance = + componentDistanceInput.value;
newOptions.arrangeComponents = arrangeSelectInput.value;
runLayout(newOptions);
}
</script>
</body>
</html>