| name | dc-dashboard-config |
| description | Create and configure dashboards with portlets (charts/widgets) using DashboardConfig in Drizzle Cube. |
Dashboard Config Skill
This skill helps you create and configure analytics dashboards using DashboardConfig and PortletConfig structures.
DashboardConfig Overview
interface DashboardConfig {
portlets: PortletConfig[]
layoutMode?: 'grid' | 'rows'
grid?: DashboardGridSettings
rows?: RowLayout[]
colorPalette?: string
filters?: DashboardFilter[]
eagerLoad?: boolean
}
Complete Dashboard Example
const dashboardConfig: DashboardConfig = {
layoutMode: 'grid',
grid: {
cols: 12,
rowHeight: 80,
minW: 2,
minH: 2
},
colorPalette: 'blue',
filters: [
{
id: 'dateFilter',
label: 'Date Range',
filter: {
member: 'Orders.createdAt',
operator: 'inDateRange',
values: ['2024-01-01', '2024-12-31']
},
isUniversalTime: true
},
{
id: 'regionFilter',
label: 'Region',
filter: {
member: 'Customers.region',
operator: 'equals',
values: ['North America']
}
}
],
portlets: [
]
}
PortletConfig Structure
interface PortletConfig {
id: string
title: string
analysisConfig?: AnalysisConfig
w: number
h: number
x: number
y: number
dashboardFilterMapping?: string[]
eagerLoad?: boolean
}
Portlet Examples
Bar Chart Portlet
{
id: 'revenue-by-department',
title: 'Revenue by Department',
w: 6,
h: 4,
x: 0,
y: 0,
dashboardFilterMapping: ['dateFilter'],
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'chart',
charts: {
query: {
chartType: 'bar',
chartConfig: {
xAxis: ['Departments.name'],
yAxis: ['Sales.totalRevenue']
},
displayConfig: {
showLegend: false,
orientation: 'vertical',
stackType: 'none'
}
}
},
query: {
measures: ['Sales.totalRevenue'],
dimensions: ['Departments.name'],
order: { 'Sales.totalRevenue': 'desc' },
limit: 10
}
}
}
KPI Number Portlet
{
id: 'total-revenue',
title: 'Total Revenue',
w: 3,
h: 2,
x: 0,
y: 0,
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'chart',
charts: {
query: {
chartType: 'kpiNumber',
chartConfig: {
yAxis: ['Sales.totalRevenue']
},
displayConfig: {
prefix: '$',
decimals: 0,
valueColorIndex: 0
}
}
},
query: {
measures: ['Sales.totalRevenue']
}
}
}
KPI Delta Portlet (with comparison)
{
id: 'revenue-change',
title: 'Revenue vs Last Month',
w: 3,
h: 2,
x: 3,
y: 0,
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'chart',
charts: {
query: {
chartType: 'kpiDelta',
chartConfig: {
yAxis: ['Sales.totalRevenue']
},
displayConfig: {
prefix: '$',
decimals: 0,
positiveColorIndex: 2,
negativeColorIndex: 1,
showHistogram: true
}
}
},
query: {
measures: ['Sales.totalRevenue'],
timeDimensions: [{
dimension: 'Sales.createdAt',
granularity: 'month',
compareDateRange: [
['2024-02-01', '2024-02-29'],
['2024-01-01', '2024-01-31']
]
}]
}
}
}
Line Chart with Time Series
{
id: 'revenue-trend',
title: 'Revenue Trend',
w: 8,
h: 4,
x: 0,
y: 4,
dashboardFilterMapping: ['dateFilter'],
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'chart',
charts: {
query: {
chartType: 'line',
chartConfig: {
xAxis: ['Sales.createdAt'],
yAxis: ['Sales.totalRevenue']
},
displayConfig: {
showLegend: true,
showGrid: true,
showTooltip: true
}
}
},
query: {
measures: ['Sales.totalRevenue'],
timeDimensions: [{
dimension: 'Sales.createdAt',
granularity: 'month',
fillMissingDates: true
}]
}
}
}
Funnel Portlet
{
id: 'signup-funnel',
title: 'Signup to Purchase Funnel',
w: 6,
h: 4,
x: 6,
y: 0,
analysisConfig: {
version: 1,
analysisType: 'funnel',
activeView: 'chart',
charts: {
funnel: {
chartType: 'funnel',
chartConfig: {},
displayConfig: {
funnelStyle: 'funnel',
showFunnelConversion: true,
showFunnelAvgTime: true
}
}
},
query: {
funnel: {
bindingKey: 'Events.userId',
timeDimension: 'Events.timestamp',
steps: [
{ name: 'Signup', cube: 'Events', filter: {...} },
{ name: 'First Visit', cube: 'Events', filter: {...} },
{ name: 'Purchase', cube: 'Events', filter: {...} }
],
includeTimeMetrics: true
}
}
}
}
Data Table Portlet
{
id: 'top-customers',
title: 'Top Customers',
w: 6,
h: 5,
x: 6,
y: 4,
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'table',
charts: {
query: {
chartType: 'table',
chartConfig: {},
displayConfig: {
pivotTimeDimension: false
}
}
},
query: {
measures: ['Orders.totalRevenue', 'Orders.count'],
dimensions: ['Customers.name', 'Customers.email'],
order: { 'Orders.totalRevenue': 'desc' },
limit: 20
}
}
}
Markdown/Text Portlet
{
id: 'dashboard-header',
title: 'Sales Overview',
w: 12,
h: 1,
x: 0,
y: 0,
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'chart',
charts: {
query: {
chartType: 'markdown',
chartConfig: {},
displayConfig: {
content: '# Q1 2024 Sales Dashboard\n\nKey metrics and trends',
fontSize: 'medium',
alignment: 'center'
}
}
},
query: {}
}
}
Grid Layout System
Grid Settings
grid: {
cols: 12,
rowHeight: 80,
minW: 2,
minH: 2
}
Grid Position Reference
| Position | Description |
|---|
x: 0, w: 6 | Left half |
x: 6, w: 6 | Right half |
x: 0, w: 12 | Full width |
x: 0, w: 4 | Left third |
x: 4, w: 4 | Center third |
x: 8, w: 4 | Right third |
x: 0, w: 3 | Quarter width |
Common Layout Patterns
Two columns:
[
{ id: 'left', w: 6, h: 4, x: 0, y: 0 },
{ id: 'right', w: 6, h: 4, x: 6, y: 0 }
]
Header + two columns:
[
{ id: 'header', w: 12, h: 2, x: 0, y: 0 },
{ id: 'left', w: 6, h: 4, x: 0, y: 2 },
{ id: 'right', w: 6, h: 4, x: 6, y: 2 }
]
KPI row + main chart:
[
{ id: 'kpi1', w: 3, h: 2, x: 0, y: 0 },
{ id: 'kpi2', w: 3, h: 2, x: 3, y: 0 },
{ id: 'kpi3', w: 3, h: 2, x: 6, y: 0 },
{ id: 'kpi4', w: 3, h: 2, x: 9, y: 0 },
{ id: 'mainChart', w: 12, h: 5, x: 0, y: 2 }
]
Dashboard Filters
Filters can be applied at the dashboard level and mapped to individual portlets:
filters: [
{
id: 'dateFilter',
label: 'Date Range',
filter: {
member: 'Orders.createdAt',
operator: 'inDateRange',
values: ['2024-01-01', '2024-12-31']
},
isUniversalTime: true
}
]
portlets: [
{
id: 'chart1',
dashboardFilterMapping: ['dateFilter'],
},
{
id: 'chart2',
dashboardFilterMapping: [],
}
]
Color Palettes
Built-in palettes:
'default' - Balanced color set
'blue' - Blue tones
'green' - Green tones
'warm' - Orange/red tones
'cool' - Blue/purple tones
'monochrome' - Grayscale
{
colorPalette: 'blue',
portlets: [...]
}
Lazy Loading
By default, portlets are lazy-loaded as they scroll into view. Override with:
{
eagerLoad: true,
portlets: [...]
}
{
id: 'important-chart',
eagerLoad: true,
}
React Usage
import { AnalyticsDashboard } from 'drizzle-cube/client'
import 'drizzle-cube/client/styles.css'
function MyDashboard() {
const [config, setConfig] = useState<DashboardConfig>(initialConfig)
return (
<AnalyticsDashboard
config={config}
editable={true}
onConfigChange={setConfig}
onSave={async (newConfig) => {
await saveDashboard(newConfig)
}}
onDirtyStateChange={(isDirty) => {
// Handle unsaved changes warning
}}
/>
)
}
Best Practices
- Use analysisConfig - Prefer the new
analysisConfig field over legacy fields
- Unique IDs - Ensure every portlet has a unique
id
- Consistent grid - Use a 12-column grid for flexibility
- Filter mapping - Map dashboard filters to relevant portlets only
- Appropriate chart types - Match chart type to data (KPIs for single values, lines for trends)
- Reasonable limits - Set
limit on queries to avoid huge data sets
- Loading strategy - Use lazy loading for large dashboards