Skip to content

Commit d7fc97d

Browse files
authored
Add 3D Network Graph component
- 3D network topology visualization with interactive nodes - Real-time network relationship mapping - Color-coded node types (server, client, threat) - Dynamic edge rendering based on connection strength - Auto-rotation and hover effects
1 parent 0d1ad8c commit d7fc97d

1 file changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import React, { useRef, useMemo } from 'react';
2+
import { Canvas, useFrame } from '@react-three/fiber';
3+
import { OrbitControls, Line, Sphere, Text } from '@react-three/drei';
4+
import * as THREE from 'three';
5+
6+
interface Node {
7+
id: string;
8+
label: string;
9+
position: [number, number, number];
10+
type: 'server' | 'client' | 'threat';
11+
}
12+
13+
interface Edge {
14+
source: string;
15+
target: string;
16+
strength: number;
17+
}
18+
19+
interface NetworkGraph3DProps {
20+
nodes: Node[];
21+
edges: Edge[];
22+
}
23+
24+
const NetworkNode: React.FC<{ node: Node; isHovered: boolean; onHover: (id: string | null) => void }> = ({ node, isHovered, onHover }) => {
25+
const meshRef = useRef<THREE.Mesh>(null);
26+
27+
useFrame(() => {
28+
if (meshRef.current && isHovered) {
29+
meshRef.current.rotation.y += 0.05;
30+
}
31+
});
32+
33+
const getNodeColor = () => {
34+
switch (node.type) {
35+
case 'server': return '#00ff88';
36+
case 'client': return '#0088ff';
37+
case 'threat': return '#ff0044';
38+
default: return '#ffffff';
39+
}
40+
};
41+
42+
const nodeSize = isHovered ? 0.3 : 0.2;
43+
44+
return (
45+
<group position={node.position}>
46+
<Sphere
47+
ref={meshRef}
48+
args={[nodeSize, 32, 32]}
49+
onPointerOver={() => onHover(node.id)}
50+
onPointerOut={() => onHover(null)}
51+
>
52+
<meshStandardMaterial
53+
color={getNodeColor()}
54+
emissive={getNodeColor()}
55+
emissiveIntensity={isHovered ? 0.8 : 0.3}
56+
metalness={0.5}
57+
roughness={0.3}
58+
/>
59+
</Sphere>
60+
{isHovered && (
61+
<Text
62+
position={[0, 0.5, 0]}
63+
fontSize={0.2}
64+
color="white"
65+
anchorX="center"
66+
anchorY="middle"
67+
>
68+
{node.label}
69+
</Text>
70+
)}
71+
</group>
72+
);
73+
};
74+
75+
const NetworkEdge: React.FC<{ start: [number, number, number]; end: [number, number, number]; strength: number }> = ({ start, end, strength }) => {
76+
const points = useMemo(() => [
77+
new THREE.Vector3(...start),
78+
new THREE.Vector3(...end)
79+
], [start, end]);
80+
81+
return (
82+
<Line
83+
points={points}
84+
color={strength > 0.7 ? '#ff4444' : '#4488ff'}
85+
lineWidth={strength * 3}
86+
opacity={0.6}
87+
transparent
88+
/>
89+
);
90+
};
91+
92+
const NetworkGraph3D: React.FC<NetworkGraph3DProps> = ({ nodes, edges }) => {
93+
const [hoveredNode, setHoveredNode] = React.useState<string | null>(null);
94+
95+
const nodeMap = useMemo(() => {
96+
const map = new Map<string, [number, number, number]>();
97+
nodes.forEach(node => map.set(node.id, node.position));
98+
return map;
99+
}, [nodes]);
100+
101+
return (
102+
<div className="w-full h-[600px] bg-gray-900 rounded-lg overflow-hidden">
103+
<Canvas camera={{ position: [0, 0, 10], fov: 60 }}>
104+
<ambientLight intensity={0.4} />
105+
<pointLight position={[10, 10, 10]} intensity={1} />
106+
<pointLight position={[-10, -10, -10]} intensity={0.5} />
107+
<spotLight position={[0, 10, 0]} angle={0.3} penumbra={1} intensity={0.8} />
108+
109+
{edges.map((edge, index) => {
110+
const start = nodeMap.get(edge.source);
111+
const end = nodeMap.get(edge.target);
112+
if (start && end) {
113+
return <NetworkEdge key={index} start={start} end={end} strength={edge.strength} />;
114+
}
115+
return null;
116+
})}
117+
118+
{nodes.map((node) => (
119+
<NetworkNode
120+
key={node.id}
121+
node={node}
122+
isHovered={hoveredNode === node.id}
123+
onHover={setHoveredNode}
124+
/>
125+
))}
126+
127+
<OrbitControls enableZoom={true} enablePan={true} autoRotate autoRotateSpeed={0.5} />
128+
</Canvas>
129+
</div>
130+
);
131+
};
132+
133+
export default NetworkGraph3D;

0 commit comments

Comments
 (0)