OG
JS
Docs
Demos
Examples
Edge filter pipeline
Compose relationship predicates without rebuilding the graph or overwriting edge styles.
Relationship kind
All
Payment
Device
Minimum risk
0
5
8
Clear filters
Payment
Device
7 / 7 visible
0 predicates · complete data retained
// Each filter is a relationship predicate over public edge data. OGJS composes predicates // against the retained graph and updates visibility without deleting topology or replacing // style rules, so clearing filters restores the original graph exactly. import { Ogjs } from '../../src/index'; const og = new Ogjs({ container: '#viz', theme: 'light', accessibility: { label: 'Edge filter pipeline' }, labels: { minZoom: 0 }, }); og.setGraph({ nodes: [ { id: 'case', x: -180, y: -80, size: 15, color: '#0f172a', label: 'Case' }, { id: 'account', x: -60, y: 100, size: 12, color: '#2563eb', label: 'Account' }, { id: 'device', x: -20, y: -120, size: 12, color: '#7c3aed', label: 'Device' }, { id: 'merchant', x: 80, y: 70, size: 13, color: '#ea580c', label: 'Merchant' }, { id: 'beneficiary', x: 180, y: -40, size: 12, color: '#059669', label: 'Beneficiary' }, { id: 'identity', x: 160, y: 130, size: 11, color: '#0891b2', label: 'Identity' }, ], edges: [ { source: 'case', target: 'account', width: 3, color: '#f59e0b', arrow: true, data: { kind: 'payment', risk: 9 } }, { source: 'case', target: 'device', width: 3, color: '#7c3aed', arrow: true, data: { kind: 'device', risk: 8 } }, { source: 'account', target: 'merchant', width: 3, color: '#f59e0b', arrow: true, data: { kind: 'payment', risk: 7 } }, { source: 'device', target: 'merchant', width: 3, color: '#7c3aed', arrow: true, data: { kind: 'device', risk: 6 } }, { source: 'merchant', target: 'beneficiary', width: 3, color: '#f59e0b', arrow: true, data: { kind: 'payment', risk: 4 } }, { source: 'beneficiary', target: 'identity', width: 3, color: '#7c3aed', arrow: true, data: { kind: 'device', risk: 3 } }, { source: 'account', target: 'identity', width: 3, color: '#f59e0b', arrow: true, data: { kind: 'payment', risk: 2 } }, ], }); og.camera.fit(); const kind = document.querySelector('#kind'); const risk = document.querySelector('#risk'); const count = document.querySelector('[data-testid="edge-count"]'); const predicates = document.querySelector('#predicates'); function apply() { // Rebuild the predicate set from the current controls. Clearing first makes repeated Apply // actions deterministic while the retained edge records remain untouched. og.transformations.clearEdgeFilters(); let active = 0; if (kind.value !== 'all') { const selected = kind.value; // Predicates receive public relationship data, so filtering never depends on renderer // indices or requires the application to copy the graph into another collection. og.transformations.addEdgeFilter(({ data }) => data.kind === selected); active++; } const minimum = Number(risk.value); if (minimum > 0) { og.transformations.addEdgeFilter(({ data }) => data.risk >= minimum); active++; } // Stable statistics report the composed result without exposing dense renderer flags. const { visibleEdges: visible, edges: total } = og.stats(); count.textContent = `${visible} / ${total} visible`; predicates.textContent = `${active} predicate${active === 1 ? '' : 's'} · complete data retained`; } kind.addEventListener('change', apply); risk.addEventListener('change', apply); document.querySelector('#clear').addEventListener('click', () => { kind.value = 'all'; risk.value = '0'; apply(); }); apply();