From drizzle-cube
Create and configure dashboards with portlets (charts/widgets) using DashboardConfig in Drizzle Cube.
How this skill is triggered — by the user, by Claude, or both
Slash command
/drizzle-cube:dc-dashboard-configThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill helps you create and configure analytics dashboards using DashboardConfig and PortletConfig structures.
This skill helps you create and configure analytics dashboards using DashboardConfig and PortletConfig structures.
interface DashboardConfig {
portlets: PortletConfig[] // Array of chart widgets
layoutMode?: 'grid' | 'rows' // Layout strategy
grid?: DashboardGridSettings // Grid configuration
rows?: RowLayout[] // Row-based layout
colorPalette?: string // Color palette name
filters?: DashboardFilter[] // Dashboard-level filters
eagerLoad?: boolean // Load all portlets immediately
}
const dashboardConfig: DashboardConfig = {
layoutMode: 'grid',
grid: {
cols: 12, // 12-column grid
rowHeight: 80, // Pixels per row unit
minW: 2, // Minimum portlet width
minH: 2 // Minimum portlet height
},
colorPalette: 'blue',
// Dashboard-level filters applied to all portlets
filters: [
{
id: 'dateFilter',
label: 'Date Range',
filter: {
member: 'Orders.createdAt',
operator: 'inDateRange',
values: ['2024-01-01', '2024-12-31']
},
isUniversalTime: true // Applies to all timeDimensions
},
{
id: 'regionFilter',
label: 'Region',
filter: {
member: 'Customers.region',
operator: 'equals',
values: ['North America']
}
}
],
portlets: [
// Portlet configs here...
]
}
interface PortletConfig {
id: string // Unique identifier
title: string // Display title
// NEW: Use analysisConfig (recommended)
analysisConfig?: AnalysisConfig // Complete analysis configuration
// Grid position (required)
w: number // Width in grid units (1-12)
h: number // Height in grid units
x: number // X position (0-11)
y: number // Y position (row)
// Filter integration
dashboardFilterMapping?: string[] // Filter IDs to apply
eagerLoad?: boolean // Override lazy loading
// DEPRECATED: Legacy fields (still supported for backward compatibility)
// query?: string // JSON string - use analysisConfig
// chartType?: ChartType // Use analysisConfig.charts
// chartConfig?: ChartAxisConfig // Use analysisConfig.charts
// displayConfig?: ChartDisplayConfig // Use analysisConfig.charts
}
{
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
}
}
}
{
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 // Use first palette color
}
}
},
query: {
measures: ['Sales.totalRevenue']
}
}
}
{
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, // Green
negativeColorIndex: 1, // Red
showHistogram: true
}
}
},
query: {
measures: ['Sales.totalRevenue'],
timeDimensions: [{
dimension: 'Sales.createdAt',
granularity: 'month',
compareDateRange: [
['2024-02-01', '2024-02-29'], // Current
['2024-01-01', '2024-01-31'] // Previous
]
}]
}
}
}
{
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
}]
}
}
}
{
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
}
}
}
}
{
id: 'top-customers',
title: 'Top Customers',
w: 6,
h: 5,
x: 6,
y: 4,
analysisConfig: {
version: 1,
analysisType: 'query',
activeView: 'table', // Show as 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
}
}
}
{
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: {
cols: 12, // Total columns (standard is 12)
rowHeight: 80, // Pixels per row unit
minW: 2, // Minimum width (grid units)
minH: 2 // Minimum height (grid units)
}
| 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 |
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 }
]
Filters can be applied at the dashboard level and mapped to individual portlets:
// Define filter at dashboard level
filters: [
{
id: 'dateFilter',
label: 'Date Range',
filter: {
member: 'Orders.createdAt',
operator: 'inDateRange',
values: ['2024-01-01', '2024-12-31']
},
isUniversalTime: true // Apply to ALL time dimensions
}
]
// Map filter to portlet
portlets: [
{
id: 'chart1',
dashboardFilterMapping: ['dateFilter'], // This portlet uses dateFilter
// ...
},
{
id: 'chart2',
dashboardFilterMapping: [], // This portlet ignores dashboard filters
// ...
}
]
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: [...]
}
By default, portlets are lazy-loaded as they scroll into view. Override with:
// Dashboard level - load all immediately
{
eagerLoad: true,
portlets: [...]
}
// Portlet level - override for specific portlet
{
id: 'important-chart',
eagerLoad: true, // Always load this one
// ...
}
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
}}
/>
)
}
analysisConfig field over legacy fieldsidlimit on queries to avoid huge data setsnpx claudepluginhub cliftonc/drizzle-cube-plugin --plugin drizzle-cubeAuto-activates on 'dashboard layout planner' requests to plan and configure dashboard layouts for data analytics, covering SQL queries, data visualization, statistical analysis, and business intelligence.
Builds or updates PostHog dashboards from insights, reusing existing insights or creating new ones. Uses PostHog dashboard templates as reference for metric groupings.
Build interactive HTML dashboards with charts, filters, and tables from query results or data sources. Useful for executive overviews, monitoring, and shareable reports.