OG
JS
Docs
Demos
Examples
Data export studio
Generate portable graph data from the live typed-array store, preview it, then download it.
JSON
CSV
GraphML
GEXF
XLSX
Download generated file ↓
// The live OGJS graph is the export source of truth. Each exporter reads the same stable ids // and attributes and produces a portable format; the application chooses the format and // destination without reconstructing nodes or edges from renderer storage. import { Ogjs, parseXLSX } from '../../src/index'; const og = new Ogjs({ container: '#viz', theme: 'light' }); og.setGraph({ nodes: [ { id: 'case', x: 0, y: 0, size: 15, color: '#0f172a', label: 'Case 1042' }, { id: 'account', x: -170, y: 95, size: 10, color: '#2563eb', label: 'Account' }, { id: 'device', x: 170, y: 95, size: 10, color: '#7c3aed', label: 'Device' }, { id: 'merchant', x: 170, y: -95, size: 10, color: '#ea580c', label: 'Merchant' }, { id: 'location', x: -170, y: -95, size: 10, color: '#059669', label: 'Location' }, ], edges: [ { source: 'case', target: 'account' }, { source: 'case', target: 'device' }, { source: 'case', target: 'merchant' }, { source: 'case', target: 'location' }, ] }); og.camera.fit({ target: 'all', avoid: document.querySelector('.workflow-panel'), paddingPx: 24, maxOccupancy: .52, }); let objectUrl; async function generate(format) { // Every branch exports the same live graph. Only the serialization changes, so there is no // export-only topology that can drift from what the developer and user currently see. let content, filename, type; if (format === 'json') { content = JSON.stringify(og.export.json(), null, 2); filename = 'network.json'; type = 'application/json'; } else if (format === 'csv') { const csv = og.export.csv(); content = csv.nodes; filename = 'network-nodes.csv'; type = 'text/csv'; } else if (format === 'graphml') { content = og.export.graphml(); filename = 'network.graphml'; type = 'application/graphml+xml'; } else if (format === 'gexf') { content = og.export.gexf(); filename = 'network.gexf'; type = 'application/gexf+xml'; } else { content = og.export.xlsx(); filename = 'network.xlsx'; type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; } // OGJS produces the document bytes; the application decides how to deliver them. This page // uses a temporary browser URL and revokes the previous one to avoid retaining old blobs. const blob = new Blob([content], { type }); if (objectUrl) URL.revokeObjectURL(objectUrl); objectUrl = URL.createObjectURL(blob); const download = document.querySelector('#download'); download.href = objectUrl; download.download = filename; download.classList.add('ready'); document.querySelector('#preview').textContent = typeof content === 'string' ? content.split('\\n').slice(0, 10).join('\\n') : 'PK · Nodes + Edges · real XLSX workbook'; document.querySelector('#export-status').textContent = `${format.toUpperCase()} · ${blob.size} bytes · ${og.stats().nodes} nodes`; document.querySelectorAll('[data-export]').forEach((button) => button.setAttribute('aria-pressed', String(button.dataset.export === format))); // Round-trip the workbook as a concrete validity check that both node and edge sheets can // be consumed again, rather than assuming a completed download means a correct document. const imported = format === 'xlsx' ? await parseXLSX(content) : undefined; } document.querySelectorAll('[data-export]').forEach((button) => button.addEventListener('click', () => void generate(button.dataset.export))); void generate('json');