OG
JS
Docs
Demos
Examples
Node paint order
Higher priorities paint and pick on top. Equal priorities keep stable insertion order.
Promote blue
Promote amber
Promote rose
Equal order
Top: blue · hover: none · click: none
// `paintOrder` expresses which overlapping node should appear and pick on top. // OGJS keeps equal-priority insertion order stable and applies style rules without changing // topology, so applications never reorder render buffers manually. import { Ogjs } from '../../src/index'; const og = new Ogjs({ container: '#viz', theme: 'light' }); og.setGraph({ nodes: [ { id: 'blue', x: -12, y: 0, size: 38, color: '#4f7fbf', mark: 'square', paintOrder: 7, borderWidth: 2, borderColor: '#ffffff' }, { id: 'amber', x: 0, y: 0, size: 38, color: '#d39a3c', mark: 'circle', paintOrder: 2, borderWidth: 2, borderColor: '#ffffff' }, { id: 'rose', x: 12, y: 0, size: 38, color: '#c96b78', mark: 'diamond', paintOrder: 0, borderWidth: 2, borderColor: '#ffffff' }, ], edges: [], }); og.camera.fit({ target: 'all', paddingPx: 32, maxOccupancy: .18, retain: true }); const status = document.querySelector('#order-status'); const state = { top: 'blue', hover: null, click: null, mode: 'initial' }; og.styles.addNodeRule(({ id }) => { // A larger `paintOrder` moves a node above overlapping peers for rendering and picking without // reordering or replacing the underlying graph records. if (state.mode === 'initial') return undefined; return { paintOrder: state.mode === 'tie' ? 0 : id === state.mode ? 10 : 0 }; }); const update = () => { status.textContent = `Top: ${state.top} · hover: ${state.hover ?? 'none'} · click: ${state.click ?? 'none'}`; }; for (const button of document.querySelectorAll('[data-promote]')) { button.addEventListener('click', () => { state.mode = button.dataset.promote; state.top = state.mode === 'tie' ? 'rose' : state.mode; state.hover = null; state.click = null; og.styles.apply(); for (const control of document.querySelectorAll('[data-promote]')) { control.setAttribute('aria-pressed', String(control === button)); } update(); }); } og.on('nodehover', ({ nodeIndex }) => { state.hover = String(og.graph.getNodeId(nodeIndex)); update(); }); og.on('nodeout', () => { state.hover = null; update(); }); og.on('nodeclick', ({ nodeIndex }) => { // Click evidence confirms the visually top mark is also the picked mark; OGJS keeps draw and // hit-test order under the same declarative priority. state.click = String(og.graph.getNodeId(nodeIndex)); update(); });