git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
6.8 KiB
6.8 KiB
🎨 RuVector Graph Explorer UI
Interactive web-based visualization for exploring vector embeddings as a force-directed graph.
✨ Features
- 🌐 Interactive force-directed graph with D3.js
- 🖱️ Drag, zoom, and pan controls
- 🔍 Search and filter nodes by metadata
- 🎯 Similarity queries - click to find similar nodes
- 📊 Metadata panel with detailed node information
- ⚡ Real-time updates via WebSocket
- 📸 Export as PNG or SVG
- 📱 Responsive design for mobile devices
- 🎨 Color-coded nodes by category
- 📈 Live statistics dashboard
🚀 Quick Start
Installation
npm install ruvector-extensions express ws
Basic Usage
import { RuvectorCore } from 'ruvector-core';
import { startUIServer } from 'ruvector-extensions/ui-server';
// Initialize database
const db = new RuvectorCore({ dimension: 384 });
// Add some vectors
await db.add('doc1', embedding1, { label: 'Document 1', category: 'research' });
await db.add('doc2', embedding2, { label: 'Document 2', category: 'code' });
// Start UI server on port 3000
const server = await startUIServer(db, 3000);
// Open browser at http://localhost:3000
Run Example
npm run example:ui
Then navigate to http://localhost:3000 in your browser.
📸 Screenshots
Main Interface
- Force-directed graph with interactive nodes
- Sidebar with search, filters, and statistics
- Real-time connection status indicator
Features Demo
- Search: Type in search box to filter nodes
- Select: Click any node to view metadata
- Similarity: Click "Find Similar Nodes" or double-click
- Export: Save visualization as PNG or SVG
- Mobile: Fully responsive on all devices
🎮 Controls
Mouse/Touch
- Click node: Select and show metadata
- Double-click node: Find similar nodes
- Drag node: Reposition in graph
- Scroll/Pinch: Zoom in/out
- Drag background: Pan view
Buttons
- Search: Filter nodes by ID or metadata
- Similarity slider: Adjust threshold (0-1)
- Find Similar: Query similar nodes
- Export PNG/SVG: Save visualization
- Reset View: Return to default zoom
- Zoom +/-: Zoom controls
- Fit View: Auto-fit graph to window
🌐 API Reference
REST Endpoints
# Get graph data
GET /api/graph?max=100
# Search nodes
GET /api/search?q=query
# Find similar nodes
GET /api/similarity/:nodeId?threshold=0.5&limit=10
# Get node details
GET /api/nodes/:nodeId
# Add new node
POST /api/nodes
{
"id": "node-123",
"embedding": [0.1, 0.2, ...],
"metadata": { "label": "Example" }
}
# Database statistics
GET /api/stats
# Health check
GET /health
WebSocket Events
Client → Server:
// Subscribe to updates
{ "type": "subscribe" }
// Request graph
{ "type": "request_graph", "maxNodes": 100 }
// Query similarity
{
"type": "similarity_query",
"nodeId": "node-123",
"threshold": 0.5,
"limit": 10
}
Server → Client:
// Graph data
{ "type": "graph_data", "payload": { "nodes": [...], "links": [...] }}
// Node added
{ "type": "node_added", "payload": { "id": "...", "metadata": {...} }}
// Similarity results
{ "type": "similarity_result", "payload": { "nodeId": "...", "similar": [...] }}
🎨 Customization
Node Colors
Customize in /src/ui/app.js:
getNodeColor(node) {
const colors = {
'research': '#667eea',
'code': '#f093fb',
'docs': '#4caf50',
'test': '#ff9800'
};
return colors[node.metadata?.category] || '#667eea';
}
Styling
Edit /src/ui/styles.css:
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--accent-color: #f093fb;
}
Force Layout
Adjust physics in /src/ui/app.js:
this.simulation
.force('link', d3.forceLink().distance(100))
.force('charge', d3.forceManyBody().strength(-300))
.force('collision', d3.forceCollide().radius(30));
🔧 Advanced Configuration
Custom Server
import { UIServer } from 'ruvector-extensions/ui-server';
const server = new UIServer(db, 3000);
// Custom middleware
server.app.use('/custom', customRouter);
await server.start();
Real-time Updates
// Notify clients of changes
server.notifyGraphUpdate();
// Broadcast custom event
server.broadcast({
type: 'custom_event',
payload: { data: 'value' }
});
📱 Mobile Support
The UI is fully optimized for mobile:
- ✅ Touch gestures (pinch to zoom)
- ✅ Responsive sidebar layout
- ✅ Simplified mobile controls
- ✅ Optimized performance
🚀 Performance
Large Graphs (1000+ nodes)
- Limit visible nodes to 500
- Use clustering for better performance
- Reduce force simulation iterations
- Hide labels at low zoom levels
Optimizations
// Reduce node limit
const maxNodes = 500;
// Faster convergence
this.simulation.alpha(0.5).alphaDecay(0.05);
// Conditional labels
label.style('display', d => zoom.scale() > 1.5 ? 'block' : 'none');
🌐 Browser Support
| Browser | Version | Status |
|---|---|---|
| Chrome | 90+ | ✅ Full |
| Firefox | 88+ | ✅ Full |
| Safari | 14+ | ✅ Full |
| Edge | 90+ | ✅ Full |
| Mobile Safari | 14+ | ✅ Full |
| Chrome Mobile | 90+ | ✅ Full |
📚 Documentation
- UI Guide - Complete documentation
- API Reference - REST and WebSocket API
- Examples - Usage examples
🐛 Troubleshooting
Graph not loading
- Check console for errors
- Verify database has data:
GET /api/stats - Check WebSocket connection status
Slow performance
- Reduce max nodes in sidebar
- Clear filters
- Check network tab for slow API calls
WebSocket issues
- Check firewall settings
- Verify port is accessible
- Look for server errors
📄 File Structure
src/
├── ui/
│ ├── index.html # Main UI file
│ ├── app.js # Client-side JavaScript
│ └── styles.css # Styling
├── ui-server.ts # Express server
└── examples/
└── ui-example.ts # Usage example
🤝 Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Submit a pull request
📜 License
MIT License - see LICENSE file
🙏 Acknowledgments
📞 Support
- 📖 Documentation
- 🐛 Issues
- 💬 Discussions
Built with ❤️ by the ruv.io team