Creates comprehensive dashboard and analytics interfaces that combine data visualization, KPI cards, real-time updates, and interactive layouts...
This skill enables the creation of sophisticated dashboard interfaces that aggregate and present data through coordinated widgets including KPI cards, charts, tables, and filters. Dashboards serve as centralized command centers for data-driven decision making, combining multiple component types from other skills (data-viz, tables, design-tokens) into unified analytics experiences with real-time updates, responsive layouts, and interactive filtering.
Activate this skill when:
┌────────────────────────────┐
│ Revenue (This Month) │ ← Label with time period
│ │
│ $1,245,832 │ ← Big number (primary metric)
│ ↑ 15.3% vs last month │ ← Trend indicator with comparison
│ ▂▃▅▆▇█ (sparkline) │ ← Mini visualization
└────────────────────────────┘
Fixed Layout: Designer-defined placement, consistent across users Customizable Grid: User drag-and-drop, resizable widgets, saved layouts Template-Based: Pre-built patterns, industry-specific starting points
For Quick Analytics Dashboard → Use Tremor Pre-built KPI cards, charts, and tables with minimal code:
npm install @tremor/react
For Customizable Dashboard → Use react-grid-layout Drag-and-drop, resizable widgets, user-defined layouts:
npm install react-grid-layout
Implement filter context for cross-widget coordination:
// Dashboard context for shared filters
const DashboardContext = createContext({
filters: { dateRange: null, categories: [] },
setFilters: () => {},
refreshInterval: 30000
});
// Wrap dashboard with provider
<DashboardContext.Provider value={dashboardState}>
<FilterPanel />
<WidgetGrid />
</DashboardContext.Provider>
Parallel Loading: Fetch all widget data simultaneously Lazy Loading: Load visible widgets first, others on scroll Cached Updates: Serve from cache while fetching fresh data
Server-Sent Events (Recommended for Dashboards):
const eventSource = new EventSource('/api/dashboard/stream');
eventSource.onmessage = (event) => {
const update = JSON.parse(event.data);
updateWidget(update.widgetId, update.data);
};
Define breakpoints for different screen sizes:
import { Card, Grid, Metric, Text, BadgeDelta, AreaChart } from '@tremor/react';
function QuickDashboard({ data }) {
return (
<Grid numItems={1} numItemsSm={2} numItemsLg={4} className="gap-4">
{/* KPI Cards */}
<Card>
<Text>Total Revenue</Text>
<Metric>$45,231.89</Metric>
<BadgeDelta deltaType="increase">+12.5%</BadgeDelta>
</Card>
<Card>
<Text>Active Users</Text>
<Metric>1,234</Metric>
<BadgeDelta deltaType="decrease">-2.3%</BadgeDelta>
</Card>
{/* Chart Widget */}
<Card className="lg:col-span-2">
<Text>Revenue Trend</Text>
<AreaChart
data={data.revenue}
index="date"
categories={["revenue"]}
valueFormatter={(value) => `$${value.toLocaleString()}`}
/>
</Card>
</Grid>
);
}
For complete implementation, see examples/tremor-dashboard.tsx.
import { Responsive, WidthProvider } from 'react-grid-layout';
import 'react-grid-layout/css/styles.css';
const ResponsiveGridLayout = WidthProvider(Responsive);
function CustomizableDashboard() {
const [layouts, setLayouts] = useState(getStoredLayouts());
return (
<ResponsiveGridLayout
layouts={layouts}
breakpoints={{ lg: 1200, md: 996, sm: 768 }}
cols={{ lg: 12, md: 10, sm: 6 }}
rowHeight={60}
onLayoutChange={(layout, layouts) => {
setLayouts(layouts);
localStorage.setItem('dashboardLayout', JSON.stringify(layouts));
}}
draggableHandle=".widget-header"
>
<div key="kpi1">
<KPIWidget data={kpiData} />
</div>
<div key="chart1">
<ChartWidget data={chartData} />
</div>
<div key="table1">
<TableWidget data={tableData} />
</div>
</ResponsiveGridLayout>
);
}
For full example with widget catalog, see examples/customizable-dashboard.tsx.
Best for unidirectional updates from server to dashboard:
function useSSEUpdates(endpoint) {
useEffect(() => {
const eventSource = new EventSource(endpoint);
eventSource.onmessage = (event) => {
const update = JSON.parse(event.data);
// Update specific widget or all widgets
dispatch({ type: 'UPDATE_WIDGET', payload: update });
};
return () => eventSource.close();
}, [endpoint]);
}
Use when dashboard needs to send commands back to server:
const ws = new WebSocket('ws://localhost:3000/dashboard');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
updateDashboard(data);
};
// Send filter changes to server
ws.send(JSON.stringify({ type: 'FILTER_CHANGE', filters }));
For environments without WebSocket/SSE support:
function useSmartPolling(fetchData, interval = 30000) {
const [isPaused, setIsPaused] = useState(false);
useEffect(() => {
if (isPaused || document.hidden) return;
const timer = setInterval(fetchData, interval);
return () => clearInterval(timer);
}, [isPaused, interval]);
// Pause when tab inactive
useEffect(() => {
const handleVisibilityChange = () => {
setIsPaused(document.hidden);
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, []);
}
For detailed patterns including error handling and reconnection, see references/real-time-updates.md.
function DashboardGrid({ widgets }) {
const [visibleWidgets, setVisibleWidgets] = useState(new Set());
return widgets.map(widget => (
<LazyLoad
key={widget.id}
height={widget.height}
offset={100}
once
placeholder={<WidgetSkeleton />}
>
<Widget {...widget} />
</LazyLoad>
));
}
// Fetch all widget data simultaneously
const loadDashboard = async () => {
const [kpis, charts, tables] = await Promise.all([
fetchKPIs(),
fetchChartData(),
fetchTableData()
]);
return { kpis, charts, tables };
};
function CachedWidget({ id, fetcher, ttl = 60000 }) {
const cache = useRef({ data: null, timestamp: 0 });
const getData = async () => {
const now = Date.now();
if (cache.current.data && now - cache.current.timestamp < ttl) {
return cache.current.data;
}
const fresh = await fetcher();
cache.current = { data: fresh, timestamp: now };
return fresh;
};
// Use cached data while fetching fresh
return <Widget data={cache.current.data} onRefresh={getData} />;
}
To analyze and optimize dashboard performance, run:
python scripts/optimize-dashboard-performance.py --analyze dashboard-config.json
Reference the data-viz skill for chart widgets:
// Use charts from data-viz skill
import { createChart } from '../data-viz/chart-factory';
const revenueChart = createChart('area', {
data: revenueData,
xAxis: 'date',
yAxis: 'revenue',
theme: dashboardTheme
});
Reference the tables skill for data grids:
// Use advanced tables from tables skill
import { DataGrid } from '../tables/data-grid';
<DataGrid
data={transactions}
columns={columnDefs}
pagination={true}
sorting={true}
filtering={true}
/>
Use the design-tokens skill for consistent theming:
// Dashboard-specific tokens from design-tokens skill
const dashboardTokens = {
'--dashboard-bg': 'var(--color-bg-secondary)',
'--widget-bg': 'var(--color-white)',
'--widget-shadow': 'var(--shadow-lg)',
'--kpi-value-size': 'var(--font-size-4xl)',
'--kpi-trend-positive': 'var(--color-success)',
'--kpi-trend-negative': 'var(--color-error)'
};
Optionally use the forms skill for filter controls:
// Advanced filter inputs from forms skill
import { DateRangePicker, MultiSelect } from '../forms/inputs';
<FilterPanel>
<DateRangePicker onChange={handleDateChange} />
<MultiSelect options={categories} onChange={handleCategoryFilter} />
</FilterPanel>
scripts/generate-dashboard-layout.py - Generate responsive grid configurationsscripts/calculate-kpi-metrics.py - Calculate trends, comparisons, sparklinesscripts/validate-widget-config.py - Validate widget and filter configurationsscripts/optimize-dashboard-performance.py - Analyze and optimize performancescripts/export-dashboard.py - Export dashboards to various formatsRun scripts directly without loading into context:
python scripts/calculate-kpi-metrics.py --data metrics.json --period monthly
references/kpi-card-patterns.md - KPI card design patterns and variationsreferences/layout-strategies.md - Grid systems and responsive approachesreferences/real-time-updates.md - WebSocket, SSE, and polling implementationsreferences/filter-coordination.md - Cross-widget filter synchronizationreferences/performance-optimization.md - Advanced optimization techniquesreferences/library-guide.md - Detailed Tremor and react-grid-layout guidesexamples/sales-dashboard.tsx - Full sales analytics dashboardexamples/monitoring-dashboard.tsx - Real-time monitoring with alertsexamples/executive-dashboard.tsx - Polished executive reportingexamples/customizable-dashboard.tsx - Drag-and-drop with persistenceexamples/tremor-dashboard.tsx - Quick Tremor implementationexamples/filter-context.tsx - Global filter coordinationassets/dashboard-templates.json - Pre-built dashboard layoutsassets/widget-library.json - Widget catalog and configurationsassets/grid-layouts.json - Responsive grid configurationsassets/kpi-formats.json - Number formatting rulesassets/theme-tokens.json - Dashboard-specific design tokensFor specific patterns and detailed implementations, explore the bundled resources referenced above.