Real-World Duct UI: Interactive Data Visualization
See how Duct UI powers an interactive single-page application with dynamic SVG visualizations, observable state management, and reactive architecture. A compelling example of building data-rich experiences with sophisticated state synchronization.
π¨ Live Example: eoeo.one
Website: https://eoeo.one/
Source Code: https://github.com/navilan/eoeo
This interactive visualization app showcases Duct UIβs power for building complex, stateful applications that go beyond traditional websites. The entire experience is a single-page application that dynamically generates and updates SVG visualizations based on user interactions through a sophisticated observable state management system.
β¨ Key Features Demonstrated
1. Dynamic SVG Visualization
The core feature is a data-driven SVG visualization that responds to user input in real-time through reactive graph generation.
Implementation Highlights:
- Programmatically generated SVG elements via
buildActiveGraph()
- Real-time data binding to visual properties
- Smooth transitions and animations
- Responsive scaling for all screen sizes
See it live: Visit eoeo.one and interact with the visualization controls to see the graphics update dynamically.
Technical approach: The visualization engine creates SVG elements through reactive graph building, where state changes automatically trigger graph regeneration and visual updates.
2. Observable State Management
The application implements a sophisticated singleton-based state management system using observables for reactive updates.
Architecture Features:
- Singleton Pattern: Global state access through
createAppState()
andgetAppState()
- Observable Events: lib0/observable for reactive state changes
- Immutable Updates: State cloning prevents direct mutations
- Granular Updates: Specific methods for different state properties
See it in action: Notice how changes in control panels immediately reflect in the visualization through the observable state system.
Source code reference: The state management in app-state.ts implements typed interfaces with comprehensive event handling.
3. Reactive Component Communication
The app demonstrates advanced reactive patterns using observable state and typed event interfaces.
Communication Patterns:
- AppStateEvents Interface: Typed event definitions for state, graph, transform, and search changes
- Observable Subscriptions: Components subscribe to specific state changes
- Automatic Graph Rebuilding: State changes trigger reactive graph updates
- Batch State Updates: Multiple state properties updated atomically
// Example reactive pattern from the implementation
interface AppStateEvents {
stateChange: (state: AppState) => void
graphChange: (graph: GraphData) => void
transformChange: (transform: TransformState) => void
searchChange: (query: string) => void
}
4. Interactive UI Components with State Binding
The interface uses Ductβs built-in components enhanced with reactive state binding.
Component Integration:
- Drawer Component: Navigation panels with state-driven visibility
- Select Component: Dropdown controls bound to observable state
- Custom Controls: Specialized inputs with granular state updates
- Reactive Layout: Dynamic updates based on state changes
State Integration: Components use methods like updatePerspective()
, updateMetric()
, and toggleState()
for granular state control.
5. Real-Time Reactive Updates
The application provides immediate visual feedback through the observable state system.
Reactive Features:
- Instant visualization changes via
buildActiveGraph()
- Smooth state transitions with immutable updates
- Performance-optimized observable subscriptions
- Memory-efficient event handling with cleanup
Check how the visualization responds immediately to control changes through the reactive state management system.
ποΈ Architecture Deep Dive
Observable State Pattern
// Simplified version of the actual implementation
function createAppState(initialState?: Partial<AppState>): AppStateManager {
const state = { ...defaultState, ...initialState }
const observable = new Observable<AppStateEvents>()
return {
getState: () => state,
updateState: (updates) => {
Object.assign(state, updates)
observable.emit('stateChange', state)
},
on: (event, callback) => observable.on(event, callback),
off: (event, callback) => observable.off(event, callback)
}
}
Component State Integration
// How components integrate with the observable state
function bind(el, eventEmitter, props) {
const appState = getAppState()
// Subscribe to state changes
appState.on('stateChange', (newState) => {
updateVisualization(newState)
})
appState.on('graphChange', (graph) => {
renderGraph(graph)
})
// Handle user interactions
function handleControlChange(value) {
appState.updatePerspective(value)
}
return {
release: () => {
// Observable cleanup handled automatically
}
}
}
π οΈ Technical Stack
- Framework: Duct UI (Client-side rendering)
- State Management: Observable pattern with lib0/observable
- Build Tool: Vite
- Graphics: Native SVG with reactive generation
- Styling: CSS with Tailwind utilities
- Architecture: Singleton state with reactive updates
- Languages: TypeScript, JavaScript
- Package Manager: pnpm
π Running Locally
To explore this example locally:
# Clone the repository
git clone https://github.com/navilan/eoeo.git
cd eoeo
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build for production
pnpm build
π‘ Key Takeaways
This real-world example demonstrates:
- Observable State Management: Implementing reactive state with typed events
- Singleton Pattern: Global state access with proper initialization
- Reactive Architecture: Automatic updates through observable subscriptions
- Component Integration: Seamless binding between Duct components and state
- SVG Generation: Dynamic graphics through reactive graph building
- Performance Optimization: Efficient state updates with immutable patterns
π Code Examples to Study
Observable State Implementation
Examine app-state.ts to understand the singleton observable pattern and reactive state management.
Graph Generation Logic
Study how buildActiveGraph()
creates dynamic visualizations based on state changes.
Component State Binding
See how Duct components integrate with the observable state system for reactive updates.
Event-Driven Architecture
Observe the typed event interfaces and how components subscribe to specific state changes.
π A Reactive Example
This project showcases Duct UIβs capability for building reactive, data-driven applications with sophisticated state management. The observable pattern creates a clean separation between state and UI while maintaining real-time synchronization.
The combination of singleton state management, observable events, and reactive graph generation creates a smooth, responsive user experience that demonstrates advanced architectural patterns.
Visit eoeo.one to experience the reactive visualization, and explore the source code to understand the observable state implementation.
π€ Share Your Duct UI Project!
Building reactive applications with Duct UI? Weβd love to see your work!
Join the conversation: Share your projects, ask questions, and connect with the Duct UI community in our GitHub Discussions.
Whether youβre building data visualizations, reactive interfaces, or state-driven applications, your examples help demonstrate Duct UIβs architectural capabilities and inspire others.
Start a discussion about your Duct UI project at github.com/navilan/duct-ui/discussions