After extensive experience building multi-source dashboards, here’s a comprehensive approach addressing all three key areas:
Data Aggregation Strategies:
The fundamental principle is to minimize client-side data fetching. Implement a server-side aggregator pattern where a single ThingWorx service orchestrates data retrieval from all sources. This service acts as a facade, abstracting the complexity of multiple data sources from the mashup.
Create a dedicated “DashboardDataAggregator” Thing with services for each dashboard or dashboard section. The service fetches data from all required sources in parallel (using async patterns where possible), performs any necessary data transformation or joining, and returns a unified dataset. Benefits include: reduced network round trips, centralized error handling, easier caching implementation, and simplified mashup logic.
For data joining and transformation, do it server-side in the aggregator service rather than in mashup expressions. ThingWorx services can efficiently join data from different InfoTables, perform calculations, and format data for visualization. This moves processing load from the browser to the server, which scales better.
Implement smart caching within the aggregator. Store aggregated results in a DataTable with timestamp and cache key. Before fetching fresh data, check if cached data exists and is within the acceptable staleness threshold. This is especially effective for data that doesn’t change frequently (configuration data, reference data, historical summaries).
For truly real-time data that must be current, use ThingWorx Streams or subscriptions rather than polling. Widgets can subscribe to property changes and update automatically when data changes, eliminating unnecessary refresh cycles.
Mashup Refresh Intervals:
Differentiate between widget types and their refresh requirements. Not all data needs the same update frequency. Categorize widgets:
- Real-time critical (device status, alarms): 10-15 second refresh or subscription-based
- Near real-time (production metrics, active counters): 30-60 second refresh
- Periodic (hourly/daily summaries, trends): 5-minute refresh
- Static (configuration, reference data): Manual refresh only or on-demand
Implement staggered refresh timing. If you have 10 widgets that need 30-second refresh, don’t refresh all at 0, 30, 60 seconds. Offset them: widget1 at 0s, widget2 at 3s, widget3 at 6s, etc. This distributes server load evenly rather than creating periodic spikes.
Use mashup parameters to control refresh behavior. Add a “refreshMode” parameter with options: auto, manual, on-demand. Let users choose based on their needs. Power users might want manual refresh for better control, while operators prefer auto-refresh for monitoring.
Implement smart refresh logic that pauses when the mashup tab is not active (using browser visibility API). No point refreshing data when users aren’t looking at the dashboard. Resume refresh when tab becomes active again.
Widget Performance Tuning:
Optimize individual widget configuration for better performance:
- Grid widgets: Enable pagination, limit visible rows to 50-100, implement virtual scrolling for large datasets
- Chart widgets: Limit data points displayed (max 500-1000 points), use aggregation for time-series data, avoid complex chart types (3D, pie charts with many slices)
- Value displays: Use number formatting to limit decimal places, avoid complex expressions in widget properties
- Lists: Implement lazy loading, show only top N items with “Show More” button
Minimize widget count. Each widget adds overhead. Instead of 20 small widgets, consider fewer composite widgets that display multiple related metrics. Use tabs or accordions to organize content and load tab content on-demand rather than all at once.
Optimize data binding expressions. Complex expressions in widget properties are evaluated on every refresh, consuming browser resources. Move complex logic to service-side data preparation. Keep mashup expressions simple: basic property access and formatting only.
Use widget visibility expressions wisely. Hidden widgets still execute their services and consume resources. Use mashup states or contained mashups to truly unload widgets when not needed.
Implement dashboard-level loading states. Show a loading overlay while initial data loads, then reveal the dashboard. This provides better UX than showing empty widgets that gradually populate.
Monitor dashboard performance using browser developer tools. Identify slow services, excessive network requests, and memory leaks. ThingWorx monitoring tools can track service execution times and help identify bottlenecks.
With these strategies implemented holistically, complex multi-source dashboards can load in 3-5 seconds and provide responsive user experience even with dozens of widgets and millions of data points. The key is moving intelligence to the server, implementing smart caching, and optimizing refresh patterns based on actual data currency requirements rather than defaulting to aggressive refresh intervals.