Download ConnectionManager.js from richardhcli/simple_neural_network_visualizer: direct link, hf CLI and curl.
- Browser
- Download file 7.01 kB
-
https://huggingface.co/spaces/richardhcli/simple_neural_network_visualizer/resolve/main/ConnectionManager.js
- Command line
-
hf download hf://spaces/richardhcli/simple_neural_network_visualizer/ConnectionManager.js
-
curl -L -o ConnectionManager.js https://huggingface.co/spaces/richardhcli/simple_neural_network_visualizer/resolve/main/ConnectionManager.js
7.01 kB
| /** | |
| * ConnectionManager.js | |
| * Manages connections (lines) between spheres | |
| */ | |
| class ConnectionManager { | |
| constructor(scene) { | |
| this.scene = scene; | |
| this.connections = new Map(); | |
| this.connectionLines = new Map(); | |
| this.materials = new Map(); | |
| } | |
| /** | |
| * Create a connection between two spheres | |
| * @param {string} id - Unique identifier for this connection | |
| * @param {THREE.Vector3} startPos - Starting position | |
| * @param {THREE.Vector3} endPos - Ending position | |
| * @param {object} config - Configuration object | |
| * @param {string} config.color - Hex color (default: '#00ff00') | |
| * @param {number} config.lineWidth - Line width (default: 2) | |
| * @param {string} config.fromSphere - Name of source sphere | |
| * @param {string} config.toSphere - Name of target sphere | |
| * @returns {THREE.Line} The created line object | |
| */ | |
| addConnection(id, startPos, endPos, config = {}) { | |
| // Prevent duplicate IDs | |
| if (this.connections.has(id)) { | |
| console.warn(`Connection "${id}" already exists.`); | |
| return null; | |
| } | |
| const color = config.color || '#00ff00'; | |
| const lineWidth = config.lineWidth || 2; | |
| // Create geometry | |
| const geometry = new THREE.BufferGeometry(); | |
| geometry.setAttribute('position', new THREE.BufferAttribute( | |
| new Float32Array([ | |
| startPos.x, startPos.y, startPos.z, | |
| endPos.x, endPos.y, endPos.z | |
| ]), 3 | |
| )); | |
| // Create material | |
| const material = new THREE.LineBasicMaterial({ | |
| color: new THREE.Color(color), | |
| linewidth: lineWidth, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| // Create line | |
| const line = new THREE.Line(geometry, material); | |
| line.name = id; | |
| line.userData = { | |
| connectionId: id, | |
| fromSphere: config.fromSphere, | |
| toSphere: config.toSphere, | |
| color: color, | |
| lineWidth: lineWidth, | |
| startPos: startPos.clone(), | |
| endPos: endPos.clone() | |
| }; | |
| // Add to scene | |
| this.scene.add(line); | |
| this.connections.set(id, line.userData); | |
| this.connectionLines.set(id, line); | |
| this.materials.set(id, material); | |
| // console.log(`✓ Connection added: ${id} (${config.fromSphere} -> ${config.toSphere})`); | |
| return line; | |
| } | |
| /** | |
| * Remove a connection | |
| * @param {string} id - Connection ID | |
| */ | |
| removeConnection(id) { | |
| const line = this.connectionLines.get(id); | |
| if (!line) { | |
| console.warn(`Connection "${id}" not found.`); | |
| return; | |
| } | |
| // Remove from scene | |
| this.scene.remove(line); | |
| // Clean up geometry and material | |
| const geometry = line.geometry; | |
| const material = this.materials.get(id); | |
| if (geometry) geometry.dispose(); | |
| if (material) material.dispose(); | |
| // Remove from maps | |
| this.connections.delete(id); | |
| this.connectionLines.delete(id); | |
| this.materials.delete(id); | |
| // console.log(`✓ Connection removed: ${id}`); | |
| } | |
| /** | |
| * Update connection position (useful for dynamic connections) | |
| * @param {string} id - Connection ID | |
| * @param {THREE.Vector3} startPos - New start position | |
| * @param {THREE.Vector3} endPos - New end position | |
| */ | |
| updateConnectionPositions(id, startPos, endPos) { | |
| const line = this.connectionLines.get(id); | |
| if (!line) return; | |
| const positions = line.geometry.attributes.position.array; | |
| positions[0] = startPos.x; | |
| positions[1] = startPos.y; | |
| positions[2] = startPos.z; | |
| positions[3] = endPos.x; | |
| positions[4] = endPos.y; | |
| positions[5] = endPos.z; | |
| line.geometry.attributes.position.needsUpdate = true; | |
| line.userData.startPos = startPos.clone(); | |
| line.userData.endPos = endPos.clone(); | |
| } | |
| /** | |
| * Update connection color | |
| * @param {string} id - Connection ID | |
| * @param {string} newColor - New hex color | |
| */ | |
| updateConnectionColor(id, newColor) { | |
| const material = this.materials.get(id); | |
| if (!material) return; | |
| material.color.set(new THREE.Color(newColor)); | |
| this.connections.get(id).color = newColor; | |
| } | |
| /** | |
| * Get connection by ID | |
| * @param {string} id - Connection ID | |
| * @returns {Object} Connection data | |
| */ | |
| getConnection(id) { | |
| return this.connections.get(id); | |
| } | |
| /** | |
| * Get all connections | |
| * @returns {Array} Array of all connections | |
| */ | |
| getAllConnections() { | |
| return Array.from(this.connections.entries()).map(([id, data]) => ({ | |
| id, | |
| ...data, | |
| line: this.connectionLines.get(id) | |
| })); | |
| } | |
| /** | |
| * Get connections for a specific sphere | |
| * @param {string} sphereName - Name of the sphere | |
| * @returns {Array} Connections connected to this sphere | |
| */ | |
| getConnectionsForSphere(sphereName) { | |
| return Array.from(this.connections.values()).filter(conn => | |
| conn.fromSphere === sphereName || conn.toSphere === sphereName | |
| ); | |
| } | |
| /** | |
| * Remove all connections for a sphere (when sphere is deleted) | |
| * @param {string} sphereName - Name of the sphere | |
| */ | |
| removeConnectionsForSphere(sphereName) { | |
| const connectionsToRemove = Array.from(this.connections.keys()).filter(id => { | |
| const conn = this.connections.get(id); | |
| return conn.fromSphere === sphereName || conn.toSphere === sphereName; | |
| }); | |
| connectionsToRemove.forEach(id => this.removeConnection(id)); | |
| } | |
| /** | |
| * Add a pulse effect to a connection | |
| * @param {string} id - Connection ID | |
| * @param {number} duration - Duration of pulse in ms | |
| */ | |
| pulseConnection(id, duration = 500) { | |
| const material = this.materials.get(id); | |
| if (!material) return; | |
| const startOpacity = material.opacity; | |
| const startTime = Date.now(); | |
| const animate = () => { | |
| const elapsed = Date.now() - startTime; | |
| const progress = (elapsed % duration) / duration; | |
| const opacityPulse = Math.sin(progress * Math.PI * 2); | |
| material.opacity = startOpacity + opacityPulse * 0.2; | |
| if (elapsed < duration * 2) { | |
| requestAnimationFrame(animate); | |
| } else { | |
| material.opacity = startOpacity; | |
| } | |
| }; | |
| animate(); | |
| } | |
| /** | |
| * Clear all connections | |
| */ | |
| clearAll() { | |
| const ids = Array.from(this.connections.keys()); | |
| ids.forEach(id => this.removeConnection(id)); | |
| console.log('✓ All connections cleared'); | |
| } | |
| /** | |
| * Get connection count | |
| * @returns {number} | |
| */ | |
| getCount() { | |
| return this.connections.size; | |
| } | |
| } | |