Back to catalog

graph-export

Export graph analysis to standard formats (GEXF, JSON, GraphML) for Gephi visualization or external processing. Use when user requests graph export, visualization, or archival storage.

  • Category: discovered
  • Tags: github, community
  • Version: 1.0.0
  • Author: walid
  • Downloads: 0
  • Updated: 2025-11-22

Download the latest version (v1.0.0) from this page.

SKILL.md

---
name: graph-export
description: Export graph analysis to standard formats (GEXF, JSON, GraphML) for Gephi visualization or external processing. Use when user requests graph export, visualization, or archival storage.
---

# Graph Export Skill

**Purpose:** Export graph analysis to standard formats (GEXF, JSON, GraphML) for visualization and processing

**Backend:** `backend/services/graph-exporter.cjs` (285 lines)

**Status:** ✅ Operational (implemented Phase 4)

---

## What This Skill Does

Exports graph analysis to industry-standard formats for use in external tools like Gephi, custom processors, or archival storage.

**Key Capabilities:**
- GEXF export (Gephi-compatible XML)
- JSON export (full metadata with AI insights)
- GraphML export (alternative XML format)
- Edge extraction from graphology instances
- Configurable output options

---

## When to Use This Skill

Use graph export when:
- User requests "export graph to Gephi"
- Need to visualize graph in external tool
- Archiving analysis for later review
- Integrating with custom processing pipeline
- Sharing graph structure with others

---

## Supported Formats

### 1. GEXF (Graph Exchange XML Format)

**Purpose:** Gephi visualization software compatibility

**Features:**
- Full node attributes (centrality, diversivity, cluster)
- Edge weights
- Graph-level metrics (modularity, entropy, density)
- Cognitive state metadata
- GEXF 1.3 specification compliant

**File Size:** ~3.7-4.0KB per analysis (typical)

**Usage:**
```javascript
const { exportGraph } = require('./backend/services/graph-exporter.cjs');
const gexf = exportGraph(analysis, 'gexf');
fs.writeFileSync('graph.gexf', gexf);
// Open graph.gexf in Gephi
```

**Example GEXF Structure:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://www.gexf.net/1.3" version="1.3">
  <meta lastmodifieddate="2025-11-06T...">
    <creator>Soulfield OS</creator>
    <description>Knowledge graph - Cognitive State: FOCUSED</description>
  </meta>
  <graph mode="static" defaultedgetype="undirected">
    <attributes class="node" mode="static">
      <attribute id="0" title="centrality" type="float"/>
      <attribute id="1" title="diversivity" type="float"/>
      <attribute id="2" title="cluster" type="integer"/>
    </attributes>
    <nodes>
      <node id="n0" label="marketing">
        <attvalues>
          <attvalue for="0" value="0.0608"/>
          <attvalue for="1" value="0.0608"/>
          <attvalue for="2" value="0"/>
        </attvalues>
      </node>
      ...
    </nodes>
    <edges>
      <edge id="e0" source="n0" target="n1" weight="3"/>
      ...
    </edges>
  </graph>
</gexf>
```

---

### 2. JSON (JavaScript Object Notation)

**Purpose:** Full metadata export with evolution/gaps/AI insights

**Features:**
- Complete analysis snapshot
- Cognitive state and statistics
- Clusters with concepts
- Evolution stage and actions
- Enhanced gaps with severity
- AI insights (if available)
- Optional raw graph data

**File Size:** ~2.7-2.9KB per analysis (typical)

**Usage:**
```javascript
const json = exportGraph(analysis, 'json', {
  pretty: true,
  includeEvolution: true,
  includeGaps: true,
  includeInsights: true,
  includeRaw: false  // Exclude raw graphology instance
});
fs.writeFileSync('graph.json', json);
```

**Example JSON Structure:**
```json
{
  "metadata": {
    "timestamp": "2025-11-06T18:53:33.213Z",
    "version": "1.0",
    "source": "Soulfield OS Graph Analysis"
  },
  "cognitiveState": "FOCUSED",
  "statistics": {
    "modularity": 0.269,
    "nodes": 16,
    "edges": 42,
    "density": 0.175,
    "entropy": 0.931
  },
  "nodes": ["revenue", "projections", "cost", ...],
  "edges": [
    { "source": "revenue", "target": "projections", "weight": 3 },
    ...
  ],
  "clusters": [
    {
      "id": 0,
      "size": 5,
      "concepts": ["revenue", "projections", "cost", "structure", "break"]
    },
    ...
  ],
  "evolution": {
    "stage": "Saturation",
    "intent": "link",
    "actions": ["Strengthen connections", "Add bridging concepts", ...]
  },
  "gaps": [
    {
      "from": 0,
      "to": 3,
      "score": 0.805,
      "severity": "major",
      "type": "logical"
    },
    ...
  ]
}
```

---

### 3. GraphML (Graph Markup Language)

**Purpose:** Alternative XML format with broader tool support

**Features:**
- Node centrality attributes
- Cluster membership
- Edge weights
- Simplified structure vs GEXF

**File Size:** Similar to GEXF

**Usage:**
```javascript
const graphml = exportGraph(analysis, 'graphml');
fs.writeFileSync('graph.graphml', graphml);
```

**Example GraphML Structure:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns">
  <key id="centrality" for="node" attr.name="centrality" attr.type="double"/>
  <key id="weight" for="edge" attr.name="weight" attr.type="double"/>
  <graph id="G" edgedefault="undirected">
    <node id="n0">
      <data key="centrality">0.0608</data>
    </node>
    <edge id="e0" source="n0" target="n1">
      <data key="weight">3</data>
    </edge>
  </graph>
</graphml>
```

---

## Export Options

### GEXF Options
```javascript
{
  includeMetrics: true,       // Graph-level metrics (modularity, entropy)
  includeEvolution: true,     // Evolution stage in description
  creator: 'Soulfield OS'     // Creator metadata
}
```

### JSON Options
```javascript
{
  pretty: true,               // Pretty-print JSON (2-space indent)
  includeRaw: false,          // Include raw graphology instance
  includeEvolution: true,     // Include evolution stage/actions
  includeGaps: true,          // Include enhanced gaps
  includeInsights: true       // Include AI insights
}
```

---

## Node Attributes (GEXF/GraphML)

**Centrality:**
- Betweenness centrality score (0-1)
- Extracted from `analysis.raw.centrality`
- Represents bridge/gateway importance

**Diversivity:**
- Betweenness/degree ratio
- Extracted from `analysis.diversivity`
- Represents VIP node status

**Cluster:**
- Cluster membership ID (0-indexed)
- -1 if node not in any cluster
- Extracted from `analysis.topical_clusters`

---

## Edge Extraction

**Challenge:** Graphology edges() is a method, not an array property

**Solution:**
```javascript
// Extract edges from graphology instance
const edgeIds = Array.from(analysis.raw.graph.edges());  // Call method
edgeIds.forEach(edgeId => {
  const source = analysis.raw.graph.source(edgeId);
  const target = analysis.raw.graph.target(edgeId);
  const weight = analysis.raw.graph.getEdgeAttribute(edgeId, 'weight') || 1;
  edges.push({ source, target, weight });
});
```

**Result:** 42 edges extracted (vs 1 before fix in Phase 4)

---

## Integration Points

**Called by:**
- Manual export via `exportGraph()` function
- Not called automatically by agent-graph-service.cjs
- User-initiated export workflow

**Depends on:**
- Complete graph analysis from local-graph-analysis.cjs
- Raw graphology instance for edge extraction
- Cluster information for node attributes

**Outputs:**
- GEXF XML string (Gephi compatible)
- JSON string (full metadata)
- GraphML XML string (alternative format)

---

## Performance

- **Speed:** <10ms overhead per export
- **Cost:** $0 (local computation)
- **File Sizes:**
  - GEXF: 3.7-4.0KB (typical)
  - JSON: 2.7-2.9KB (typical)
  - GraphML: Similar to GEXF

**No regression:** Export adds minimal overhead to analysis

---

## Testing

```bash
# Test GEXF export
node -e "
const { analyzeForAgent } = require('./backend/services/agent-graph-service.cjs');
const { exportGraph } = require('./backend/services/graph-exporter.cjs');
const fs = require('fs');

(async () => {
  const result = await analyzeForAgent('finance', 'revenue projections cost structure burn rate management metrics');

  // Export to GEXF
  const gexf = exportGraph(result, 'gexf');
  fs.writeFileSync('/tmp/finance-graph.gexf', gexf);
  console.log('GEXF exported:', (gexf.length / 1024).toFixed(1) + 'KB');

  // Export to JSON
  const json = exportGraph(result, 'json');
  fs.writeFileSync('/tmp/finance-graph.json', json);
  console.log('JSON exported:', (json.length / 1024).toFixed(1) + 'KB');

  // Verify edge extraction
  const parsed = JSON.parse(json);
  console.log('Edges extracted:', parsed.edges.length);
})();
"

# Expected output:
# GEXF exported: 4.0KB
# JSON exported: 2.9KB
# Edges extracted: 42
```

---

## Gephi Workflow

**Steps to visualize in Gephi:**

1. Export graph to GEXF:
   ```javascript
   const gexf = exportGraph(analysis, 'gexf');
   fs.writeFileSync('graph.gexf', gexf);
   ```

2. Open Gephi desktop application

3. File → Open → Select `graph.gexf`

4. Apply layout algorithm:
   - ForceAtlas2 (network layout)
   - Fruchterman Reingold (alternative)

5. Size nodes by:
   - Centrality (bridge importance)
   - Diversivity (VIP status)

6. Color nodes by:
   - Cluster ID (community detection)
   - Modularity class

7. Filter nodes:
   - By centrality threshold
   - By cluster membership

8. Export visualization:
   - File → Export → PNG/SVG/PDF

**Result:** Professional-grade network visualization without custom UI

---

## Real-World Examples

**@finance Analysis Export:**
```
16 nodes, 42 edges
4 clusters detected
3 gaps identified

GEXF export: 4.0KB
- Node attributes: centrality, diversivity, cluster
- Edge weights: co-occurrence strength
- Graph metrics: modularity=0.269, entropy=0.931

JSON export: 2.9KB
- Full metadata with evolution stage (Saturation)
- 3 enhanced gaps with severity
- 2 AI insights (if API key present)
```

**@marketing Analysis Export:**
```
8 nodes, 19 edges
3 clusters detected
1 gap identified

GEXF export: 3.7KB
JSON export: 2.7KB
```

**@seo Analysis Export:**
```
9 nodes, 21 edges
3 clusters detected
1 gap identified

GEXF export: 4.0KB
JSON export: 2.9KB
```

---

## Error Handling

**Edge extraction failures:**
- Catches graphology API errors
- Logs warning with error message
- Falls back to `analysis.edges` array if available
- Returns empty array if both fail

**XML escaping:**
- Escapes special characters: `&`, `<`, `>`, `"`, `'`
- Prevents malformed XML
- Handles non-string values gracefully

**Missing data:**
- Default values for missing attributes (centrality=0, cluster=-1)
- Empty arrays for missing edges/nodes
- Graceful degradation on partial data

---

## Limitations

**Current constraints:**
- No incremental export (full graph only)
- No streaming for large graphs
- No compression options
- No format conversion utilities (GEXF ↔ GraphML)
- No validation against GEXF/GraphML schemas

**Future enhancements (not implemented):**
- Compressed export (.gexf.gz)
- Streaming export for large graphs
- Format conversion tools
- Schema validation
- Export templates (custom formats)

---

## Related Skills

- **Historical Tracking** - Exports snapshots for comparison
- **AI Enhancement** - AI insights included in JSON export
- **Evolution Tracking** - Evolution stage exported in metadata

---

**Implementation:** Phase 4 (2025-11-06)
**Test Status:** ✅ Verified operational across @marketing, @seo, @finance
**Documentation:** workspace/docs/Obsidian-v2/daily/2025-11-06-PHASE4-COMPLETE.md