Five silhouettes share one instanced render path and the same exact pointer geometry.
Hover a mark · none active
CIRCLE · SQUARE · DIAMOND · TRIANGLE · HEXAGON
// A node's `mark` selects its silhouette while all other graph behavior stays identical.
// OGJS uses the same renderer and exact hit geometry for every shape, so applications do
// not maintain separate drawing or pointer code for circles, diamonds, or polygons.
import { Ogjs } from '../../src/index';
// Mark names are graph data, so one dataset can mix silhouettes without installing custom
// drawing callbacks or changing how nodes are selected and addressed.
const marks = ['circle', 'square', 'diamond', 'triangle', 'hexagon'];
const colors = ['#5b7fba', '#8064b5', '#c96b78', '#d49a3f', '#4f9477'];
const og = new Ogjs({ container: '#viz', theme: 'light' });
og.setGraph({
nodes: marks.map((mark, index) => ({
id: mark,
label: mark[0].toUpperCase() + mark.slice(1),
x: (index - 2) * 125,
y: 0,
size: 32,
color: colors[index],
mark,
borderWidth: 2,
borderColor: '#ffffff',
})),
edges: [],
});
og.camera.fit({ target: 'all', paddingPx: 24, maxOccupancy: .64 });
const status = document.querySelector('#mark-status');
const state = { marks, colors, hover: null };
og.on('nodehover', ({ nodeIndex }) => {
// Hover returns the normal graph index for every silhouette. OGJS performs exact shape hit
// testing and the application continues to work with stable node ids.
state.hover = String(og.graph.getNodeId(nodeIndex));
status.textContent = `Hover a mark · ${state.hover} active`;
});
og.on('nodeout', () => {
state.hover = null;
status.textContent = 'Hover a mark · none active';
});