An extension for Three.js that turns graphs (nodes + edges) into reusable 3D geometries with a modular, extensible architecture.
- π― 14 Built-in Graph Presets: From basic shapes (cube, pyramid) to complex networks (star, lattice, paths)
- π¨ Customizable Styling: Full control over node/edge colors, sizes, and materials
- πΉ Directed Graph Support: 3D arrow visualization for directed edges
- ποΈ Interactive GUI: Real-time parameter adjustment with lil-gui integration
- π§© Modular Architecture: Clean separation of concerns with organized modules
- π§ Custom Preset System: Register your own graph generation functions
- π Per-Node Customization: Individual node radii and colors
- πͺ Path Merging: Smart vertex merging for complex path networks
npm install three-graph-geometryimport * as THREE from 'three';
import { GraphGeometry } from 'three-graph-geometry';
const scene = new THREE.Scene();
// Create a cube graph
const cubeGraph = new GraphGeometry('cube', 1, { includeFaceCenters: true }, {
nodeColor: 0x4ecdc4,
edgeColor: 0x45b7d1,
nodeRadius: 0.12,
edgeRadius: 0.02
});
scene.add(cubeGraph);
// Create a star network with custom styling
const starGraph = new GraphGeometry('star', 8, 2, {
nodeColor: 0xff6b6b,
edgeColor: 0x4ecdc4,
nodeRadius: 0.2,
directed: true
});
scene.add(starGraph);import { SceneManager } from 'three-graph-geometry/core/Scene';
import { GraphGeometry } from 'three-graph-geometry';
import { ParameterManager } from 'three-graph-geometry/gui/ParameterManager';
import { GUIController } from 'three-graph-geometry/gui/GUIController';
class GraphApp {
constructor() {
this.sceneManager = new SceneManager('canvas-id');
this.parameterManager = new ParameterManager();
this.guiController = new GUIController(
this.parameterManager,
() => this.updateGraph()
);
this.updateGraph();
this.sceneManager.start();
}
updateGraph() {
// Remove old graph
if (this.currentGraph) {
this.sceneManager.remove(this.currentGraph);
this.currentGraph.dispose();
}
// Create new graph
this.parameterManager.allocatePerNodeArrays();
const styleOptions = this.parameterManager.getStyleOptions();
const presetParams = this.parameterManager.getPresetParameters();
this.currentGraph = new GraphGeometry(
this.parameterManager.params.preset,
...presetParams,
styleOptions
);
this.sceneManager.add(this.currentGraph);
}
}
new GraphApp();new GraphGeometry(type, ...params, options)Parameters:
type(string): Preset name or registered custom preset...params: Preset-specific parametersoptions(object): Styling and rendering options
Options Object:
{
nodeRadius: 0.12, // Default node radius
edgeRadius: 0.02, // Default edge radius
nodeColor: 0x00ffff, // Default node color (hex)
edgeColor: 0xffffff, // Default edge color (hex)
nodeSegments: 16, // Node sphere detail
edgeSegments: 8, // Edge cylinder detail
directed: false, // Enable 3D arrows
arrowSize: 0.18, // Arrow size multiplier
arrowSegments: 8, // Arrow cone detail
nodeRadii: null, // Per-node radius array
nodeColors: null // Per-node color array/function
}import { registerPreset } from 'three-graph-geometry';
registerPreset('myCustomGraph', (param1, param2) => {
const nodes = [
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(param1, 0, 0),
new THREE.Vector3(0, param2, 0)
];
const edges = [[0, 1], [1, 2], [2, 0]];
return { nodes, edges };
});
// Use your custom preset
const customGraph = new GraphGeometry('myCustomGraph', 2, 3, {
nodeColor: 0xff0000
});| Preset | Parameters | Description |
|---|---|---|
cube |
size, options |
8-node cube wireframe (supports includeFaceCenters option) |
pyramid |
baseSize, height |
5-node pyramid (4 base + 1 apex) |
prism |
width, height, depth |
Rectangular prism wireframe |
octahedron |
size |
6-node octahedron |
triangle |
size |
3-node triangle |
line |
length |
2-node line segment |
cone |
radius, height, baseSegments, options |
Cone with base ring (supports includeFaceCenters option) |
| Preset | Parameters | Description |
|---|---|---|
circular |
count, radius |
Nodes in circle, connected in ring |
star |
count, radius |
Complete graph (all nodes connected) |
grid |
rows, cols, spacing |
2D grid network |
lattice |
nx, ny, nz, spacing |
3D lattice/grid |
spokes |
count, length, angleOffset |
Hub with radiating spokes |
| Preset | Parameters | Description |
|---|---|---|
polyline |
points[] |
Connected line through points |
paths |
paths[], options |
Multiple polylines with merging |
// Basic shapes
const cube = new GraphGeometry('cube', 2);
const cubeWithFaceCenters = new GraphGeometry('cube', 2, { includeFaceCenters: true });
const pyramid = new GraphGeometry('pyramid', 3, 2);
const cone = new GraphGeometry('cone', 2, 3, 8);
const coneWithBaseCenter = new GraphGeometry('cone', 2, 3, 8, { includeFaceCenters: true });
// Networks
const star = new GraphGeometry('star', 6, 2);
const grid = new GraphGeometry('grid', 3, 3, 2);
const lattice3D = new GraphGeometry('lattice', 2, 2, 2, 1.5);
// Paths
const polyline = new GraphGeometry('polyline', [
{x: 0, y: 0, z: 0},
{x: 1, y: 1, z: 0},
{x: 2, y: 0, z: 1}
]);
const paths = new GraphGeometry('paths', [
[{x: 0, y: 0, z: 0}, {x: 1, y: 0, z: 0}],
[{x: 1, y: 0, z: 0}, {x: 1, y: 1, z: 0}]
], { merge: true, mergeTolerance: 1e-6 });// Random node sizes
const nodeRadii = [0.1, 0.2, 0.15, 0.3];
// Alternating colors
const nodeColors = [0xff0000, 0x00ff00, 0xff0000, 0x00ff00];
// Color function
const nodeColors = (index) => index % 2 ? 0xff0000 : 0x0000ff;
const graph = new GraphGeometry('cube', 2, {
nodeRadii,
nodeColors
});const directedGraph = new GraphGeometry('grid', 3, 3, 2, {
directed: true,
arrowSize: 0.3,
edgeColor: 0x00ff00
});// Edges can be objects with custom properties
const customEdges = [
{a: 0, b: 1, color: 0xff0000, radius: 0.05},
{a: 1, b: 2, color: 0x00ff00, radius: 0.02}
];src/
βββ core/ # Core system modules
β βββ Scene.js # Three.js scene management
β βββ GraphRenderer.js # Graph rendering engine
β βββ PresetManager.js # Preset registration system
βββ presets/ # Graph generation presets
β βββ basic/BasicShapes.js # Geometric shapes
β βββ structures/Networks.js # Network topologies
β βββ paths/PathGeometry.js # Path-based graphs
βββ gui/ # User interface
β βββ ParameterManager.js # Parameter handling
β βββ GUIController.js # lil-gui integration
βββ materials/ # Material creation
β βββ MaterialFactory.js # Material utilities
βββ utils/ # Utility functions
β βββ MathHelpers.js # Math utilities
β βββ GeometryUtils.js # Three.js geometry helpers
βββ GraphGeometry.js # Main class
βββ main.js # Demo application
βββ index.js # Package exports
- Three.js: >=0.170.0
- lil-gui: ^0.20.0 (optional, for demo GUI)
- ES6+ Support: Uses ES modules
- WebGL: Requires WebGL-capable browser
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview build
npm run docs:dev # Start documentation
npm run docs:build # Build documentation- Separation of Concerns: Each module has a single responsibility
- Preset Pattern: All graph types follow the same
{nodes, edges}interface - Extensibility: New presets are easy to add via registration system
- Three.js Integration: Seamless integration with existing Three.js workflows
- Built-in Presets: Add to appropriate module in
src/presets/ - External Presets: Use
registerPreset()function - Return Format: Always return
{nodes: Vector3[], edges: [number, number][]}
- Use ES6+ features
- Follow existing naming conventions
- Document complex algorithms
- Keep preset functions pure (no side effects)
- Test all presets with various parameters
- Verify edge cases (empty graphs, single nodes)
- Check memory cleanup (
dispose()methods)
MIT License - see LICENSE file for details.
Gonzalo Martinesse devamartinese@gmail.com