Analytics Helper
by markus41
Assists with building reports, dashboards, and data visualizations using Recharts and D3.js for the NABIP AMS. Use when creating member growth charts, revenue analytics, event performance metrics, email engagement tracking, or custom report builders with aggregations and scheduled exports.
Skill Details
Repository Files
1 file in this skill directory
name: analytics-helper description: Assists with building reports, dashboards, and data visualizations using Recharts and D3.js for the NABIP AMS. Use when creating member growth charts, revenue analytics, event performance metrics, email engagement tracking, or custom report builders with aggregations and scheduled exports.
Analytics Helper
Drive measurable insights through interactive data visualizations designed for association management decision-making.
When to Use
Activate this skill when:
- Creating charts with Recharts (line, area, bar, pie)
- Building custom report builders with field selection
- Implementing dashboard KPIs and metrics
- Designing aggregation queries (SUM, AVG, COUNT, MIN, MAX)
- Adding scheduled report generation (daily, weekly, monthly)
- Exporting data to CSV, Excel, or PDF formats
- Working with time-series analysis for trends
Key Metrics to Track
Member Analytics
- Total Members: Count by status (active, pending, inactive)
- Growth Rate: Month-over-month % change
- Retention Rate: % of members who renewed
- Engagement Distribution: Score ranges (0-25, 26-50, 51-75, 76-100)
- Tier Distribution: National vs State vs Local percentages
- Geographic Distribution: Members per state/region
Financial Analytics
- Total Revenue: By source (dues, events, donations)
- Revenue Trends: Monthly/quarterly comparisons
- Average Transaction Value: Per revenue source
- Payment Status: Completed vs pending vs failed
- Revenue per Chapter: Hierarchical rollup
Event Analytics
- Attendance Rate: Registered vs attended
- Capacity Utilization: % of available seats filled
- Revenue per Event: Total income vs costs
- Event Type Performance: Conference, webinar, workshop comparison
- Virtual vs In-Person: Attendance and revenue comparison
Communication Analytics
- Email Open Rate: % of emails opened
- Click-through Rate: % of links clicked
- Unsubscribe Rate: % who opted out
- Campaign Performance: A/B test results
- Segmentation Effectiveness: Engagement by audience segment
Chart Components with Recharts
Member Growth Trend (Line Chart)
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from "recharts"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
interface MemberGrowthData {
month: string
active: number
pending: number
inactive: number
}
export function MemberGrowthChart({ data }: { data: MemberGrowthData[] }) {
return (
<Card>
<CardHeader>
<CardTitle>Member Growth Trend</CardTitle>
<CardDescription>Track membership changes over time to identify growth patterns</CardDescription>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={350}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis
dataKey="month"
className="text-sm"
tickLine={false}
axisLine={false}
/>
<YAxis
className="text-sm"
tickLine={false}
axisLine={false}
tickFormatter={(value) => value.toLocaleString()}
/>
<Tooltip
contentStyle={{
backgroundColor: "hsl(var(--card))",
border: "1px solid hsl(var(--border))",
borderRadius: "8px"
}}
/>
<Legend />
<Line
type="monotone"
dataKey="active"
stroke="oklch(0.60 0.12 200)"
strokeWidth={2}
name="Active Members"
dot={{ fill: "oklch(0.60 0.12 200)", r: 4 }}
/>
<Line
type="monotone"
dataKey="pending"
stroke="oklch(0.75 0.15 85)"
strokeWidth={2}
name="Pending"
dot={{ fill: "oklch(0.75 0.15 85)", r: 4 }}
/>
<Line
type="monotone"
dataKey="inactive"
stroke="hsl(var(--muted-foreground))"
strokeWidth={2}
strokeDasharray="5 5"
name="Inactive"
dot={{ fill: "hsl(var(--muted-foreground))", r: 4 }}
/>
</LineChart>
</ResponsiveContainer>
</CardContent>
</Card>
)
}
Revenue by Source (Area Chart)
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts"
interface RevenueData {
month: string
dues: number
events: number
donations: number
}
export function RevenueAreaChart({ data }: { data: RevenueData[] }) {
return (
<Card>
<CardHeader>
<CardTitle>Revenue Breakdown</CardTitle>
<CardDescription>Visualize income streams to optimize revenue strategy</CardDescription>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={350}>
<AreaChart data={data}>
<defs>
<linearGradient id="colorDues" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="oklch(0.60 0.12 200)" stopOpacity={0.8} />
<stop offset="95%" stopColor="oklch(0.60 0.12 200)" stopOpacity={0} />
</linearGradient>
<linearGradient id="colorEvents" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="oklch(0.75 0.15 85)" stopOpacity={0.8} />
<stop offset="95%" stopColor="oklch(0.75 0.15 85)" stopOpacity={0} />
</linearGradient>
<linearGradient id="colorDonations" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="oklch(0.25 0.05 250)" stopOpacity={0.8} />
<stop offset="95%" stopColor="oklch(0.25 0.05 250)" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis dataKey="month" />
<YAxis tickFormatter={(value) => `$${(value / 1000).toFixed(0)}k`} />
<Tooltip formatter={(value: number) => `$${value.toLocaleString()}`} />
<Area
type="monotone"
dataKey="dues"
stackId="1"
stroke="oklch(0.60 0.12 200)"
fill="url(#colorDues)"
name="Membership Dues"
/>
<Area
type="monotone"
dataKey="events"
stackId="1"
stroke="oklch(0.75 0.15 85)"
fill="url(#colorEvents)"
name="Event Revenue"
/>
<Area
type="monotone"
dataKey="donations"
stackId="1"
stroke="oklch(0.25 0.05 250)"
fill="url(#colorDonations)"
name="Donations"
/>
</AreaChart>
</ResponsiveContainer>
</CardContent>
</Card>
)
}
Engagement Distribution (Bar Chart)
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell } from "recharts"
interface EngagementData {
range: string
count: number
}
export function EngagementDistributionChart({ data }: { data: EngagementData[] }) {
const colors = [
"hsl(var(--destructive))",
"hsl(var(--warning))",
"oklch(0.75 0.15 85)",
"oklch(0.60 0.12 200)"
]
return (
<Card>
<CardHeader>
<CardTitle>Member Engagement Distribution</CardTitle>
<CardDescription>Identify engagement levels to target low-scoring members</CardDescription>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
<XAxis dataKey="range" />
<YAxis />
<Tooltip />
<Bar dataKey="count" radius={[8, 8, 0, 0]}>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={colors[index % colors.length]} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
)
}
Custom Report Builder
Report Configuration Interface
interface ReportField {
table: "members" | "chapters" | "events" | "transactions"
field: string
label: string
type: "string" | "number" | "date" | "boolean"
aggregation?: "sum" | "avg" | "count" | "min" | "max"
}
interface ReportConfig {
name: string
description: string
fields: ReportField[]
filters?: Record<string, any>
groupBy?: string[]
orderBy?: { field: string; direction: "asc" | "desc" }[]
schedule?: {
frequency: "daily" | "weekly" | "monthly"
dayOfWeek?: number
dayOfMonth?: number
time: string
recipients: string[]
format: "csv" | "excel" | "pdf"
}
}
// Example: Generate SQL from report config
function generateReportQuery(config: ReportConfig): string {
const selectFields = config.fields.map(field => {
if (field.aggregation) {
return `${field.aggregation.toUpperCase()}(${field.table}.${field.field}) as ${field.label}`
}
return `${field.table}.${field.field} as ${field.label}`
})
const groupByFields = config.groupBy
? `GROUP BY ${config.groupBy.join(", ")}`
: ""
const orderByFields = config.orderBy
? `ORDER BY ${config.orderBy.map(o => `${o.field} ${o.direction.toUpperCase()}`).join(", ")}`
: ""
return `
SELECT ${selectFields.join(", ")}
FROM ${config.fields[0].table}
${groupByFields}
${orderByFields}
`.trim()
}
Scheduled Report Generation
import { format } from "date-fns"
import * as XLSX from "xlsx"
async function executeScheduledReports() {
const reports = await db
.select()
.from(reportConfigs)
.where(isNotNull(reportConfigs.schedule))
for (const reportConfig of reports) {
const shouldRun = checkSchedule(reportConfig.schedule)
if (shouldRun) {
// Execute report query
const results = await executeReportQuery(reportConfig)
// Export based on format
const exportFile = await exportReport(
results,
reportConfig.schedule.format,
reportConfig.name
)
// Send to recipients
await sendReportEmail(
reportConfig.schedule.recipients,
reportConfig.name,
exportFile
)
// Log execution
await createAuditLog({
action: "scheduled_report_executed",
reportName: reportConfig.name,
timestamp: new Date()
})
}
}
}
async function exportReport(data: any[], format: "csv" | "excel" | "pdf", reportName: string) {
if (format === "csv") {
return exportToCSV(data, reportName)
} else if (format === "excel") {
const ws = XLSX.utils.json_to_sheet(data)
const wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, "Report")
const buffer = XLSX.write(wb, { type: "buffer", bookType: "xlsx" })
return buffer
} else {
return exportToPDF(data, reportName)
}
}
Dashboard KPIs
Real-time Metrics Component
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { TrendingUp, TrendingDown, Users, DollarSign, Calendar, Mail } from "lucide-react"
interface KPI {
title: string
value: string | number
change?: number
changeType?: "positive" | "negative"
icon: React.ReactNode
}
export function KPIDashboard({ metrics }: { metrics: KPI[] }) {
return (
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
{metrics.map((kpi, index) => (
<Card key={index}>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">{kpi.title}</CardTitle>
{kpi.icon}
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{kpi.value}</div>
{kpi.change !== undefined && (
<p className="text-xs text-muted-foreground flex items-center gap-1 mt-1">
{kpi.changeType === "positive" ? (
<TrendingUp className="h-4 w-4 text-green-500" />
) : (
<TrendingDown className="h-4 w-4 text-red-500" />
)}
<span className={kpi.changeType === "positive" ? "text-green-500" : "text-red-500"}>
{Math.abs(kpi.change)}%
</span>
{" from last month"}
</p>
)}
</CardContent>
</Card>
))}
</div>
)
}
// Usage example
const dashboardMetrics: KPI[] = [
{
title: "Total Members",
value: "20,247",
change: 12.5,
changeType: "positive",
icon: <Users className="h-4 w-4 text-muted-foreground" />
},
{
title: "Monthly Revenue",
value: "$147,250",
change: 8.3,
changeType: "positive",
icon: <DollarSign className="h-4 w-4 text-muted-foreground" />
},
{
title: "Upcoming Events",
value: 12,
icon: <Calendar className="h-4 w-4 text-muted-foreground" />
},
{
title: "Email Engagement",
value: "34.2%",
change: -2.1,
changeType: "negative",
icon: <Mail className="h-4 w-4 text-muted-foreground" />
}
]
Performance Optimization Tips
✅ Use aggregations at database level (not in-memory) ✅ Implement pagination for large datasets (100+ rows) ✅ Cache expensive queries (use React Query or SWR) ✅ Debounce filter inputs (300ms delay) ✅ Lazy load chart libraries (code splitting) ✅ Virtualize long lists (react-window/react-virtual)
Integration with Other Skills
- Combine with
supabase-schema-validatorfor optimized queries - Use with
component-generatorfor dashboard UI - Works with
member-workflowfor engagement analytics
Best for: Developers building interactive dashboards, custom reports, and data-driven insights for NABIP association leadership and chapter administrators.
Related Skills
Xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Analyzing Financial Statements
This skill calculates key financial ratios and metrics from financial statement data for investment analysis
Data Storytelling
Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.
Team Composition Analysis
This skill should be used when the user asks to "plan team structure", "determine hiring needs", "design org chart", "calculate compensation", "plan equity allocation", or requests organizational design and headcount planning for a startup.
Startup Financial Modeling
This skill should be used when the user asks to "create financial projections", "build a financial model", "forecast revenue", "calculate burn rate", "estimate runway", "model cash flow", or requests 3-5 year financial planning for a startup.
Kpi Dashboard Design
Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.
Dbt Transformation Patterns
Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.
Startup Metrics Framework
This skill should be used when the user asks about "key startup metrics", "SaaS metrics", "CAC and LTV", "unit economics", "burn multiple", "rule of 40", "marketplace metrics", or requests guidance on tracking and optimizing business performance metrics.
