Objective
Visualize a network of connected nodes in 3D space with:
- Nodes as spheres
- Connections as lines
- Simple physics (nodes repel, connections pull)
- Camera controls for rotation and zoom
Current State
Basic scene rendering with static nodes. Drag to rotate, scroll to zoom.
Demo
Code
Basic Setup
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// Scene setup
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x0a0a0a);
// Camera controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
Create Nodes
const nodeMaterial = new THREE.MeshBasicMaterial({ color: 0x4a9eff });
const nodes = [];
for (let i = 0; i < 12; i++) {
const geometry = new THREE.SphereGeometry(0.3, 16, 16);
const node = new THREE.Mesh(geometry, nodeMaterial);
node.position.x = (Math.random() - 0.5) * 10;
node.position.y = (Math.random() - 0.5) * 10;
node.position.z = (Math.random() - 0.5) * 10;
scene.add(node);
nodes.push(node);
}
Create Connections
const lineMaterial = new THREE.LineBasicMaterial({ color: 0x2a2a2a });
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
if (Math.random() > 0.7) {
const points = [nodes[i].position, nodes[j].position];
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const line = new THREE.Line(geometry, lineMaterial);
scene.add(line);
}
}
}
Animation Loop
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
Physics (Future Implementation)
// Basic node structure
class Node {
constructor(x, y, z) {
this.position = new THREE.Vector3(x, y, z);
this.velocity = new THREE.Vector3(0, 0, 0);
this.connections = [];
}
applyForce(force) {
this.velocity.add(force);
}
update() {
this.position.add(this.velocity);
this.velocity.multiplyScalar(0.95); // Damping
}
}
// Node repulsion
function applyRepulsion(nodes) {
for (let i = 0; i < nodes.length; i++) {
for (let j = i + 1; j < nodes.length; j++) {
const direction = nodes[i].position.clone().sub(nodes[j].position);
const distance = direction.length();
if (distance < 5) {
const force = direction.normalize().multiplyScalar(0.01 / distance);
nodes[i].applyForce(force);
nodes[j].applyForce(force.negate());
}
}
}
}
Next Steps
- Implement node repulsion
- Add connection spring forces
- Mouse interaction (hover, drag nodes)
- Load data from external source
- Node labels on hover
- Performance optimization for large graphs
Notes
- Using Three.js r160+
- OrbitControls for camera manipulation
- May need WebGL2 for larger datasets