Appearance
Timeline with node lifespans
This is the example of nodes with different lifespans in timeline mode.
ts
import Ogma from '@linkurious/ogma';
import { Controller as TimelinePlugin } from '@linkurious/ogma-timeline-plugin';
const ogma = new Ogma({
container: 'graph-container'
});
ogma.styles.addNodeRule({
innerStroke: {
color: '#555',
scalingMethod: 'fixed',
width: 1
}
});
const range = Date.now() - new Date('August 19, 1975 23:15:30').getTime();
Ogma.parse
.gexfFromUrl('files/arctic.gexf')
.then(graph => {
graph.nodes.forEach((node, i) => {
// add a random date to the node
const start = Date.now() - Math.random() * range;
const end = start + Math.random() * range;
node.data = { start, end };
});
return ogma.setGraph(
{
nodes: graph.nodes.slice(50, 100),
edges: graph.edges
},
{ ignoreInvalid: true }
);
})
.then(() => {
const container = document.getElementById('timeline');
const timelinePlugin = new TimelinePlugin(ogma, container, {
minTime: new Date('January 1, 1975 00:00:00').getTime(),
maxTime: new Date('January 1, 2022 00:00:00').getTime(),
timeBars: [
new Date('January 1, 1975 00:00:00'),
new Date('January 1, 2025 00:00:00')
],
barchart: {
nodeGroupIdFunction: node => node.getData('nodeType')
},
timeline: {
nodeGroupIdFunction: node => node.getData('nodeType')
}
});
let isSelecting = false;
timelinePlugin.on('select', ({ nodes, edges }) => {
isSelecting = true;
ogma.getNodes().setSelected(false);
ogma.getEdges().setSelected(false);
if (nodes) {
nodes.setSelected(true);
}
if (edges) {
edges.setSelected(true);
}
isSelecting = false;
});
ogma.events.on(
['nodesSelected', 'edgesSelected', 'nodesUnselected', 'edgesUnselected'],
() => {
if (isSelecting) return;
timelinePlugin.setSelection({
nodes: ogma.getSelectedNodes(),
edges: ogma.getSelectedEdges()
});
}
);
const filter = ogma.transformations.addNodeFilter({
criteria: node => {
return timelinePlugin.filteredNodes.has(node.getId());
}
});
//Hook it to the timeline events
timelinePlugin.on('timechange', () => {
filter.refresh();
});
});
html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link
href="https://cdn.jsdelivr.net/npm/vis-timeline@latest/styles/vis-timeline-graph2d.min.css"
rel="stylesheet"
type="text/css"
/>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@linkurious/ogma-timeline-plugin@latest/dist/style.css"
/>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap"
rel="stylesheet"
/>
<link type="text/css" rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="graph-container"></div>
<div id="timeline"></div>
<script src="index.ts" type="module"></script>
</body>
</html>
css
body {
display: grid;
grid-template-rows: auto 33%;
height: 100vh;
margin: 0;
padding: 0;
}
#timeline > div {
height: 100%;
}
json
{
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@linkurious/ogma": "^5.2.3",
"vis-data": "7.1.16",
"vis-timeline": "7.7.2",
"leaflet": "1.9.4",
"@linkurious/ogma-timeline-plugin": "0.2.15"
}
}