Appearance
Show Overlaping Nodes
This example shows how to display nodes in geo mode when they have the same coordinates. Hover a cluster to show the underlying nodes. It uses two instances of Ogma: one in geo mode, the other one in regular mode.
ts
import Ogma from '@linkurious/ogma';
// @ts-expect-error
Ogma.libraries['leaflet'] = L;
const graph = {
nodes: new Array(10)
.fill(0)
.map((_, i) => ({
id: i,
data: { latitude: 48.858838, longitude: 2.343436 },
attributes: { radius: 10, text: 'Paris', x: 0, y: 0 }
}))
.concat(
new Array(10).fill(0).map((_, i) => ({
id: i + 10,
data: { latitude: 51.509615, longitude: -0.134514 },
attributes: { radius: 10, text: 'London', x: 0, y: 0 }
}))
),
edges: new Array(20).fill(0).map((_, i) => ({
id: i,
source: Math.floor(Math.random() * 20),
target: Math.floor(Math.random() * 20)
}))
};
const ogma = new Ogma({
graph,
container: 'graph-container'
});
ogma.styles.addNodeRule(n => n.isVirtual(), {
radius: 10,
badges: {
topRight: {
scale: 0.6,
stroke: {
width: 0.5
},
text: n => `${n.getSubNodes()?.size}`
}
}
});
ogma.transformations.addNodeGrouping({
selector: node => node.getData('latitude'),
groupIdFunction: node => {
const { longitude, latitude } = node.getData();
return `${latitude}-${longitude}`;
},
nodeGenerator: (nodes, id) => {
const [latitude, longitude] = id.split('-').map(e => +e);
return {
data: {
latitude,
longitude
}
};
}
});
const hoverOgmaContainer = document.querySelector(
'.hoverogma'
) as HTMLDivElement;
const hoverOgma = new Ogma({
container: hoverOgmaContainer,
options: {
width: 150,
height: 150,
backgroundColor: 'rgba(250,250,250,0.75)'
}
});
ogma.events.on('mouseover', ({ target }) => {
if (!target || !target.isNode || !target.isVirtual()) return;
const subNodes = target.getSubNodes()!;
const subEdges = subNodes.getAdjacentEdges({
filter: 'all',
bothExtremities: true
});
hoverOgmaContainer.classList.remove('hidden');
hoverOgma
.setGraph({ nodes: subNodes.toJSON(), edges: subEdges.toJSON() })
.then(() => hoverOgma.layouts.force({ locate: true }));
const { x, y } = target.getPositionOnScreen();
hoverOgmaContainer.style.left = `${x + 50}px`;
hoverOgmaContainer.style.top = `${y}px`;
});
ogma.events.on(['click', 'dragStart', 'viewChanged'], () => {
hoverOgmaContainer.classList.add('hidden');
});
ogma.geo
.toggle({
duration: 0
})
.then(() => ogma.geo.setView(50, 1, 6))
.then(() => {
ogma.geo.getMap()!.getContainer().appendChild(hoverOgmaContainer);
});
html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.3/leaflet.js"></script>
<link type="text/css" rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="graph-container"></div>
<div class="hoverogma hidden"></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;
}
.hoverogma{
border-radius: 50%;
position: absolute;
z-index: 10000;
transform: translate(0,-50%);
overflow: hidden;
border: 1px dashed black;
}
.hidden{
display: none;
}