Appearance
Set data
This example shows how to set the nodes and edges data and how to use it to style your vizualisation. Click on a node or an edge to modify the content of its data object. If you set the right key/value pairs, you will see the icons, texts and colors getting updated.
js
import Ogma from '@linkurious/ogma';
const ogma = new Ogma({
container: 'graph-container'
});
// Add multiple nodes
ogma.addNodes([{ id: 'n1' }, { id: 'n2' }]);
ogma.addEdge({ id: 'e1', source: 'n1', target: 'n2' });
ogma.layouts.force({ locate: true });
//create the UI with tweakpane to edit data
const overlay = document.getElementById('overlay');
let pane;
function createUI(element) {
closeUI();
overlay.classList.remove('hidden');
pane = new Tweakpane({ container: document.getElementById('gui-container') });
const close = pane.addButton({ title: 'close', label: 'close' });
close.on('click', () => {
closeUI();
});
const data = element.getData() || {};
const styledKeys = {
name: {
found: false,
default: element.isNode ? 'Mr Washerman' : '1M suspicious transaction'
},
type: {
found: false,
default: element.isNode ? 'agent' : 'transaction'
}
};
Object.keys(data).forEach(key => {
pane.addInput(data, key);
if (styledKeys[key] !== undefined) {
styledKeys[key].found = true;
}
});
// finds out which suggestion to put
const [defaultKey, defaultValue] = Object.entries(styledKeys).reduce(
(suggested, [key, value]) => {
if (value.found) return suggested;
return [key, value.default];
},
['key', 'value']
);
const newRaw = {
key: defaultKey,
value: defaultValue
};
// add a form to add new keys
pane.addSeparator();
pane.addInput(newRaw, 'key');
pane.addInput(newRaw, 'value');
const button = pane.addButton({ title: '+', label: '+' });
button.on('click', () => {
let newData = {};
newData[newRaw.key] = newRaw.value;
newData = {
...element.getData(),
...newData
};
element.setData(newData);
createUI(element);
});
}
overlay.addEventListener('click', () => closeUI());
function closeUI() {
if (pane) {
pane.dispose();
}
pane = null;
overlay.classList.add('hidden');
}
// link the UI to Ogma events
ogma.events.on('click', ({ target }) => {
if (!target) {
return closeUI();
}
createUI(target);
});
// add some styleRule to illustrate the power of data
const nodeStylePerType = {
agent: {
color: 'gold',
icon: {
content: '\uF007'
}
},
money: {
color: 'green',
icon: {
content: '\uF53a'
}
},
default: {
color: 'grey',
icon: {
font: 'Font Awesome 5 Free',
color: 'black',
style: 'bold'
}
}
};
const edgeStylePerType = {
transaction: {
shape: {
head: 'arrow'
},
color: 'green'
}
};
ogma.styles.addRule({
nodeAttributes: node => {
const style = nodeStylePerType[node.getData('type')] || {};
return { ...nodeStylePerType.default, ...style };
},
edgeAttributes: edge => {
const style = edgeStylePerType[edge.getData('type')] || {};
return { ...edgeStylePerType.default, ...style };
}
});
ogma.styles.addNodeRule({
text: node => node.getData('name') || 'unnamed'
});
ogma.styles.addEdgeRule({
text: edge => edge.getData('name') || 'unnamed'
});
html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="styles.css" />
<script src="https://cdn.jsdelivr.net/npm/tweakpane@1.5.7/dist/tweakpane.min.js"></script>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/solid.min.css"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
</head>
<body>
<div id="graph-container"></div>
<div id="overlay" class="hidden"></div>
<div id="gui-container"></div>
<script src="index.js"></script>
</body>
</html>
css
#graph-container {
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: 0;
overflow: hidden;
}
#overlay{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0.5;
background-color: #888;
}
#gui-container {
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 100;
opacity: 1;
}
.hidden{
display: none;
}