OG
JS
Docs
Demos
Examples
Pattern-aware group layouts
Choose a readable local grammar from topology intent while OGJS owns every group center.
ISOLATED → TRACK · MESH → RING · STAR → ORBIT
// The application supplies group membership and a familiar local grammar, not member or // group coordinates. OGJS packs the broad view before applying each scoped layout recipe. import { Ogjs } from '../../src/index'; const og = new Ogjs({ container: '#viz', theme: 'light' }); og.animationDuration = 350; const nodes = []; const edges = []; // Membership and internal topology describe each group. Member coordinates are intentionally // absent so the local layout calls—not fixture arithmetic—own their arrangement. const isolatedSizes = [4, 6, 5, 7, 4, 6]; isolatedSizes.forEach((size, index) => nodes.push({ id: `isolated-${index}`, size, color: '#0ea5e9', label: `iso-${index}`, data: { group: 'Isolated' }, })); const meshIds = []; for (let index = 0; index < 8; index++) { meshIds.push(`mesh-${index}`); nodes.push({ id: `mesh-${index}`, size: index === 0 ? 8 : 5, color: '#8b5cf6', label: `mesh-${index}`, data: { group: 'Mesh' }, }); edges.push({ source: `mesh-${index}`, target: `mesh-${(index + 1) % 8}` }); } edges.push({ source: 'mesh-0', target: 'mesh-4' }, { source: 'mesh-2', target: 'mesh-6' }); nodes.push({ id: 'star-hub', size: 10, color: '#f97316', label: 'hub', data: { group: 'Star' }, }); const starIds = []; for (let index = 0; index < 5; index++) { const id = `star-${index}`; starIds.push(id); nodes.push({ id, size: 5, color: '#f97316', label: `leaf-${index}`, data: { group: 'Star' }, }); edges.push({ source: 'star-hub', target: id }); } og.setGraph({ nodes, edges }); // One broad grouping recipe derives group centers. Scoped recipes then express the local visual // grammar without hand-authored centers: a track, a cycle, and a degree-ranked hub orbit. og.layouts.clustered({ groupBy: ({ data }) => data.group, groupGap: 80, memberGap: 10 }); og.layouts.track({ nodeIds: isolatedSizes.map((_, index) => `isolated-${index}`), gap: 12 }); og.layouts.circular({ nodeIds: meshIds, radius: 44 }); og.layouts.orbit({ nodeIds: ['star-hub', ...starIds], ringGap: 42, nodeGap: 8 }); // Visual grouping retains member geometry and topology while adding group context around it; // it does not replace source records with aggregate meta-nodes. og.groupVisually(({ data }) => data.group, { relax:false }); og.camera.fit({ target: 'visible', avoid: document.querySelector('.panel'), paddingPx: 24 });