Skip to main content

GEXF Format

Convert graphs to and from GEXF (Graph Exchange XML Format), designed for network analysis and visualization.

Features

  • Compound graphs: Via @pid attribute and nesting
  • Viz module: Color, position, size attributes
  • Gephi compatible: Primary format for Gephi network analysis
  • Typed attributes: Custom node/edge attributes
  • Hierarchical nesting: Supports nested node structures

Installation

Requires the fast-xml-parser peer dependency:
pnpm add fast-xml-parser

Import

import { toGEXF, fromGEXF, gexfConverter } from '@statelyai/graph';
// Or from subpath:
import { toGEXF } from '@statelyai/graph/gexf';

toGEXF()

Converts a graph to GEXF XML string.
import { createGraph, toGEXF } from '@statelyai/graph';

const graph = createGraph({
  id: 'Network',
  nodes: [
    { 
      id: 'a', 
      label: 'Node A', 
      x: 0, 
      y: 0,
      width: 20,
      color: '#ff6666'
    },
    { 
      id: 'b', 
      label: 'Node B', 
      x: 100, 
      y: 100,
      parentId: 'container'
    },
    { id: 'container', label: 'Container' }
  ],
  edges: [
    { id: 'e0', sourceId: 'a', targetId: 'b', label: 'link' }
  ]
});

const xml = toGEXF(graph);
Result:
<?xml version="1.0" encoding="UTF-8"?>
<gexf xmlns="http://gexf.net/1.3" xmlns:viz="http://gexf.net/1.3/viz" version="1.3">
  <graph defaultedgetype="directed" id="Network">
    <attributes class="node">
      <attribute id="a_parentId" title="parentId" type="string"/>
      <attribute id="a_initialNodeId" title="initialNodeId" type="string"/>
      <attribute id="a_data" title="data" type="string"/>
      <attribute id="a_shape" title="shape" type="string"/>
    </attributes>
    <attributes class="edge">
      <attribute id="a_edgeData" title="data" type="string"/>
    </attributes>
    <nodes>
      <node id="a" label="Node A">
        <viz:color r="255" g="102" b="102"/>
        <viz:position x="0" y="0"/>
        <viz:size value="20"/>
      </node>
      <node id="b" label="Node B" pid="container">
        <attvalues>
          <attvalue for="a_parentId" value="container"/>
        </attvalues>
        <viz:position x="100" y="100"/>
      </node>
      <node id="container" label="Container"/>
    </nodes>
    <edges>
      <edge id="e0" source="a" target="b" label="link"/>
    </edges>
  </graph>
</gexf>

Type Signature

function toGEXF(graph: Graph): string

Parameters

graph
Graph
required
The graph to convert to GEXF

Returns

A GEXF 1.3 XML string.

Viz Module Properties

Graph PropertyGEXF Viz ElementNotes
node.x, node.y<viz:position x="..." y="..."/>Node position
node.width or node.height<viz:size value="..."/>Node size (uses width, or height if width missing)
node.color<viz:color r="..." g="..." b="..."/>RGB color from hex
edge.color<viz:color r="..." g="..." b="..."/>Edge color

Attribute Mapping

Graph PropertyGEXF AttributeType
node.parentId@pid + a_parentIdstring
node.initialNodeIda_initialNodeIdstring
node.dataa_datastring (JSON)
node.shapea_shapestring
edge.dataa_edgeDatastring (JSON)

fromGEXF()

Parses a GEXF XML string into a graph.
import { fromGEXF } from '@statelyai/graph';

const graph = fromGEXF(`
  <?xml version="1.0"?>
  <gexf xmlns="http://gexf.net/1.3" version="1.3">
    <graph defaultedgetype="directed">
      <nodes>
        <node id="a" label="Node A"/>
        <node id="b" label="Node B" pid="a"/>
      </nodes>
      <edges>
        <edge id="e0" source="a" target="b"/>
      </edges>
    </graph>
  </gexf>
`);

Type Signature

function fromGEXF(xml: string): Graph

Parameters

xml
string
required
GEXF XML string to parse

Returns

A Graph object.

Hierarchy Handling

GEXF supports three ways to express hierarchy:
  1. @pid attribute (GEXF 1.2+):
    <node id="child" pid="parent"/>
    
  2. Nested <node> elements (GEXF 1.2+):
    <node id="parent">
      <nodes>
        <node id="child"/>
      </nodes>
    </node>
    
  3. Custom attribute:
    <node id="child">
      <attvalues>
        <attvalue for="parentId" value="parent"/>
      </attvalues>
    </node>
    
The parser handles all three, with @pid taking precedence.

Error Handling

try {
  const graph = fromGEXF('<invalid>');
} catch (error) {
  console.error(error.message);
  // "GEXF: invalid XML — ..."
}

fromGEXF('text'); // Error: GEXF: missing <gexf> root element
fromGEXF(123); // Error: GEXF: expected a string

gexfConverter

Bidirectional converter object.
import { createGraph, gexfConverter } from '@statelyai/graph';

const graph = createGraph({
  nodes: [{ id: 'a' }, { id: 'b' }],
  edges: [{ sourceId: 'a', targetId: 'b' }]
});

const xml = gexfConverter.to(graph);
const roundTripped = gexfConverter.from(xml);

Type

const gexfConverter: GraphFormatConverter<string>

Usage with Gephi

GEXF is the native format for Gephi network analysis:
import { toGEXF } from '@statelyai/graph';
import { writeFileSync } from 'fs';

const xml = toGEXF(graph);
writeFileSync('network.gexf', xml);

// Open in Gephi:
// File → Open → network.gexf

Color Conversion

Colors are converted between hex and RGB:
import { createGraph, toGEXF } from '@statelyai/graph';

const graph = createGraph({
  nodes: [
    { id: 'a', color: '#ff6666' },  // Red-ish
    { id: 'b', color: '#66ff66' },  // Green-ish
    { id: 'c', color: '#6666ff' }   // Blue-ish
  ]
});

const xml = toGEXF(graph);
// <viz:color r="255" g="102" b="102"/>
// <viz:color r="102" g="255" b="102"/>
// <viz:color r="102" g="102" b="255"/>
Parsing converts RGB back to hex:
import { fromGEXF } from '@statelyai/graph';

const graph = fromGEXF(xml);
graph.nodes[0].color; // '#ff6666'

Compound Graph Example

import { createGraph, toGEXF } from '@statelyai/graph';

const graph = createGraph({
  nodes: [
    { id: 'company', label: 'ACME Corp' },
    { id: 'dept1', label: 'Engineering', parentId: 'company' },
    { id: 'dept2', label: 'Sales', parentId: 'company' },
    { id: 'alice', label: 'Alice', parentId: 'dept1' },
    { id: 'bob', label: 'Bob', parentId: 'dept1' },
    { id: 'charlie', label: 'Charlie', parentId: 'dept2' }
  ],
  edges: [
    { sourceId: 'alice', targetId: 'bob', label: 'works with' },
    { sourceId: 'alice', targetId: 'charlie', label: 'collaborates' }
  ]
});

const xml = toGEXF(graph);
// Uses @pid attribute for parent-child relationships

Custom Data Example

import { createGraph, toGEXF, fromGEXF } from '@statelyai/graph';

const graph = createGraph({
  nodes: [
    { 
      id: 'person1',
      label: 'Alice',
      data: {
        age: 30,
        department: 'Engineering',
        skills: ['TypeScript', 'React']
      },
      shape: 'circle',
      color: '#4a90e2'
    }
  ]
});

const xml = toGEXF(graph);
// Custom data is JSON-serialized in attributes

const parsed = fromGEXF(xml);
parsed.nodes[0].data; // { age: 30, department: 'Engineering', skills: [...] }
parsed.nodes[0].shape; // 'circle'
parsed.nodes[0].color; // '#4a90e2'

Undirected Graphs

import { createGraph, toGEXF } from '@statelyai/graph';

const graph = createGraph({
  type: 'undirected',
  nodes: [{ id: 'a' }, { id: 'b' }],
  edges: [{ sourceId: 'a', targetId: 'b' }]
});

const xml = toGEXF(graph);
// <graph defaultedgetype="undirected">

Tool Compatibility

GEXF is supported by:
  • Gephi - Network analysis and visualization (primary tool)
  • Sigma.js - JavaScript graph visualization library
  • NetworkX - Python library (via read_gexf/write_gexf)
  • Cytoscape - Via GEXF import plugin

Advanced Example

import { createGraph, toGEXF } from '@statelyai/graph';
import { writeFileSync } from 'fs';

const graph = createGraph({
  id: 'CitationNetwork',
  nodes: [
    { 
      id: 'paper1',
      label: 'Machine Learning Basics',
      data: { year: 2020, citations: 150, authors: ['Smith', 'Jones'] },
      x: 0,
      y: 0,
      width: 30,
      color: '#e74c3c'
    },
    { 
      id: 'paper2',
      label: 'Deep Learning Advanced',
      data: { year: 2021, citations: 89, authors: ['Johnson'] },
      x: 100,
      y: 50,
      width: 25,
      color: '#3498db'
    },
    { 
      id: 'paper3',
      label: 'Neural Networks Today',
      data: { year: 2022, citations: 45, authors: ['Williams', 'Brown'] },
      x: 200,
      y: 0,
      width: 20,
      color: '#2ecc71'
    }
  ],
  edges: [
    { 
      sourceId: 'paper2', 
      targetId: 'paper1',
      label: 'cites',
      data: { context: 'builds upon' }
    },
    { 
      sourceId: 'paper3', 
      targetId: 'paper2',
      label: 'cites',
      data: { context: 'extends' }
    }
  ]
});

const xml = toGEXF(graph);
writeFileSync('citations.gexf', xml);
console.log('Open citations.gexf in Gephi for analysis');

See Also

Build docs developers (and LLMs) love