18 KiB
Billing Dashboard Visualization & Animation Opportunities
Executive Summary
This document reviews the existing Recharts utilities, current chart implementations in the billing dashboard, and provides recommendations for additional visualizations and Framer Motion animations to enhance user experience and data comprehension.
1. Current Recharts Infrastructure
1.1 Lazy Loading Wrapper (frontend/src/utils/lazyRecharts.tsx)
Available Components:
LazyLineChart- Line charts (lazy loaded)LazyBarChart- Bar charts (lazy loaded)LazyPieChart- Pie charts (lazy loaded)LazyAreaChart- Area charts (lazy loaded)LazyRadarChart- Radar charts (lazy loaded)LazyComposedChart- Combined charts (lazy loaded)
Lightweight Direct Imports:
Line,Bar,Pie,Area,RadarXAxis,YAxis,CartesianGridTooltip,Legend,ResponsiveContainerCell,PolarGrid,PolarAngleAxis,PolarRadiusAxis
Best Practice: Always use lazy-loaded components wrapped in <Suspense> with ChartLoadingFallback for optimal performance.
2. Current Chart Implementations
2.1 Existing Charts in Billing Dashboard
✅ CostBreakdown.tsx - Pie Chart
- Type: Pie chart showing provider cost distribution
- Data:
ProviderBreakdown(cost per provider) - Features:
- Custom tooltip with provider icon, cost, calls, tokens
- Custom label showing percentage
- Color-coded by provider
- Framer Motion: Basic fade-in animation
✅ UsageTrends.tsx - Line/Area Charts
- Type: Line and Area charts for historical trends
- Data:
UsageTrends(periods, costs, calls, tokens) - Features:
- Multi-series line chart (cost, calls, tokens)
- Area chart for cost projections
- Growth rate indicators
- Cost velocity calculations
- Custom tooltips
- Framer Motion: Card-level animations
✅ AdvancedCostAnalytics.tsx - Bar/Pie Charts
- Type: Bar charts (time of day, user actions) and Pie charts
- Data:
UsageLog[](aggregated by hour, endpoint) - Features:
- Time-of-day cost distribution (bar chart)
- Tool/endpoint cost breakdown (pie chart)
- Efficiency metrics
- Tabbed interface
- Framer Motion: Tab transitions
✅ ToolCostBreakdown.tsx - No Charts (Text-based)
- Type: Grid-based tool cost display
- Data:
UsageLog[](grouped by tool/endpoint) - Opportunity: Could benefit from bar or pie chart visualization
3. Recommended New Visualizations
3.1 Compact Dashboard Enhancements
📊 Mini Sparkline Charts (High Priority)
Location: CompactBillingDashboard.tsx - Metric cards
Purpose: Show trend at a glance without expanding
Implementation:
// Add to each metric card (Total Cost, Total Calls, etc.)
<Box sx={{ height: 40, mt: 1 }}>
<ResponsiveContainer width="100%" height="100%">
<LazyLineChart data={last7DaysData}>
<Line
type="monotone"
dataKey="value"
stroke={getStatusColor(status)}
strokeWidth={2}
dot={false}
/>
</LazyLineChart>
</ResponsiveContainer>
</Box>
Data Source: Last 7 days from UsageTrends
Animation: Fade-in on card hover
📈 Provider Cost Comparison Bar Chart (Medium Priority)
Location: CompactBillingDashboard.tsx - Below Monthly Budget Usage
Purpose: Quick visual comparison of provider costs
Implementation:
- Horizontal bar chart
- Top 5 providers by cost
- Color-coded bars matching provider colors
- Click to expand to detailed view
Data Source: current_usage.provider_breakdown
🎯 Usage Limit Progress Rings (High Priority)
Location: CompactBillingDashboard.tsx - Replace linear progress bars
Purpose: More visually appealing circular progress indicators
Implementation:
- Circular progress rings (using SVG or Recharts RadialBar)
- Color-coded by usage level (green/yellow/red)
- Percentage and absolute values displayed
- Animated fill on load
Data Source: usage_percentages from UsageStats
3.2 Detailed Dashboard Enhancements
📊 Cost Over Time - Multi-Series Area Chart (High Priority)
Location: UsageTrends.tsx - Enhance existing
Purpose: Show cost trends with provider breakdown
Implementation:
- Stacked area chart showing:
- Total cost (area)
- Individual provider costs (stacked)
- Projected cost (dashed line)
- Interactive legend to toggle providers
- Zoom/pan capabilities
Data Source: trends.provider_trends
📈 Daily Cost Heatmap (Medium Priority)
Location: New component or AdvancedCostAnalytics.tsx
Purpose: Visualize cost patterns by day of week and hour
Implementation:
- Calendar-style heatmap
- X-axis: Days of month
- Y-axis: Hours of day
- Color intensity: Cost amount
- Tooltip: Exact cost, calls, date/time
Data Source: UsageLog[] aggregated by day/hour
🎨 Provider Efficiency Radar Chart (Low Priority)
Location: AdvancedCostAnalytics.tsx or new component
Purpose: Compare providers across multiple dimensions
Implementation:
- Radar chart with axes:
- Cost per call
- Average response time
- Success rate
- Token efficiency
- Usage volume
- Multiple providers overlaid
- Interactive legend
Data Source: Aggregated UsageLog[] by provider
📉 Cost Velocity Trend Line (High Priority)
Location: UsageTrends.tsx or BillingOverview.tsx
Purpose: Show spending velocity (daily cost rate) over time
Implementation:
- Line chart showing:
- Daily spending rate (calculated)
- 7-day moving average
- Projected monthly cost (horizontal line)
- Budget limit (horizontal line)
- Annotations for budget warnings
Data Source: Calculated from UsageTrends
🎯 Tool Usage Sankey Diagram (Low Priority - Complex)
Location: New component or ToolCostBreakdown.tsx
Purpose: Show flow of usage across tools and providers
Implementation:
- Sankey diagram (may need custom library or D3)
- Left: Tools (Blog Writer, Image Studio, etc.)
- Right: Providers (Gemini, WaveSpeed, etc.)
- Flow width: Cost amount
- Interactive: Click to filter
Data Source: UsageLog[] grouped by tool → provider
3.3 Real-time Monitoring Visualizations
⚡ Live Cost Counter (High Priority)
Location: BillingOverview.tsx or header
Purpose: Animated counter showing real-time cost accumulation
Implementation:
- Animated number counter (using Framer Motion)
- Updates on data refresh
- Color changes based on velocity
- Pulse animation when cost increases
Data Source: current_usage.total_cost
📊 Error Rate Gauge (Medium Priority)
Location: SystemHealthIndicator.tsx or BillingOverview.tsx
Purpose: Visual gauge showing API error rate
Implementation:
- Semi-circular gauge chart
- Green (0-5%), Yellow (5-10%), Red (>10%)
- Animated needle
- Current value and target displayed
Data Source: systemHealth.error_rate
4. Framer Motion Animation Opportunities
4.1 Current Animation Usage
Existing:
- ✅ Card-level fade-in (
motion.divwithinitial,animate) - ✅ View mode transitions (
AnimatePresencewith slide) - ✅ Hover effects (
whileHoveron cards) - ✅ Loading spinner rotation
Missing Opportunities:
- ❌ Stagger animations for metric cards
- ❌ Number counting animations
- ❌ Progress bar fill animations
- ❌ Chart data entry animations
- ❌ Error/warning pulse animations
- ❌ Refresh button rotation
- ❌ Tooltip entrance animations
4.2 Recommended Animations
🎬 Staggered Card Entrance (High Priority)
Location: CompactBillingDashboard.tsx - Metric cards grid
Implementation:
<Grid container spacing={2}>
{metrics.map((metric, index) => (
<Grid item key={metric.id}>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
delay: index * 0.1,
duration: 0.4,
ease: "easeOut"
}}
>
<MetricCard {...metric} />
</motion.div>
</Grid>
))}
</Grid>
🔢 Animated Number Counter (High Priority)
Location: All cost/call/token displays Implementation:
import { useMotionValue, useSpring, useTransform } from 'framer-motion';
const AnimatedNumber: React.FC<{ value: number; format?: (n: number) => string }> = ({
value,
format = (n) => n.toLocaleString()
}) => {
const motionValue = useMotionValue(0);
const spring = useSpring(motionValue, {
stiffness: 50,
damping: 30
});
const display = useTransform(spring, (latest) => format(Math.round(latest)));
useEffect(() => {
motionValue.set(value);
}, [value, motionValue]);
return <motion.span>{display}</motion.span>;
};
📊 Chart Data Entry Animation (Medium Priority)
Location: All chart components Implementation:
// For line/area charts
<Area
dataKey="cost"
fill="url(#colorCost)"
stroke="#667eea"
strokeWidth={2}
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 1, ease: "easeInOut" }}
/>
// For bar charts
<Bar dataKey="cost">
{data.map((entry, index) => (
<Cell
key={`cell-${index}`}
initial={{ scaleY: 0 }}
animate={{ scaleY: 1 }}
transition={{
delay: index * 0.05,
duration: 0.5,
ease: "easeOut"
}}
/>
))}
</Bar>
🎯 Progress Bar Fill Animation (High Priority)
Location: All progress bars (usage limits, budget) Implementation:
<motion.div
initial={{ scaleX: 0 }}
animate={{ scaleX: usagePercentage / 100 }}
transition={{
duration: 1,
ease: "easeOut",
delay: 0.2
}}
style={{
transformOrigin: "left",
height: "100%",
backgroundColor: getProgressColor(usagePercentage)
}}
/>
⚠️ Alert Pulse Animation (Medium Priority)
Location: UsageAlerts.tsx and alert indicators
Implementation:
<motion.div
animate={{
scale: [1, 1.05, 1],
opacity: [1, 0.8, 1]
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
>
<Alert severity="warning">...</Alert>
</motion.div>
🔄 Refresh Button Rotation (Low Priority - Already has CSS)
Location: All refresh buttons Implementation:
<motion.div
animate={{ rotate: loading ? 360 : 0 }}
transition={{
duration: 1,
repeat: loading ? Infinity : 0,
ease: "linear"
}}
>
<RefreshCw />
</motion.div>
💬 Tooltip Entrance (Low Priority)
Location: All tooltips Implementation:
<motion.div
initial={{ opacity: 0, scale: 0.8, y: 10 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.8, y: 10 }}
transition={{ duration: 0.2 }}
>
<TooltipContent />
</motion.div>
5. Implementation Priority
Phase 1: High Impact, Low Effort (Week 1)
- ✅ Animated number counters
- ✅ Progress bar fill animations
- ✅ Staggered card entrance
- ✅ Mini sparkline charts in compact view
Phase 2: Medium Impact, Medium Effort (Week 2)
- ✅ Cost velocity trend line
- ✅ Provider cost comparison bar chart
- ✅ Usage limit progress rings
- ✅ Chart data entry animations
Phase 3: High Impact, High Effort (Week 3-4)
- ✅ Multi-series area chart (cost over time)
- ✅ Daily cost heatmap
- ✅ Live cost counter
- ✅ Error rate gauge
Phase 4: Nice to Have (Future)
- ⏳ Provider efficiency radar chart
- ⏳ Tool usage Sankey diagram
- ⏳ Alert pulse animations
- ⏳ Enhanced tooltip animations
6. Code Examples
6.1 Mini Sparkline Component
// components/billing/MiniSparkline.tsx
import React, { Suspense } from 'react';
import { Box } from '@mui/material';
import { LazyLineChart, Line, ResponsiveContainer, ChartLoadingFallback } from '../../utils/lazyRecharts';
interface MiniSparklineProps {
data: Array<{ date: string; value: number }>;
color: string;
height?: number;
}
export const MiniSparkline: React.FC<MiniSparklineProps> = ({
data,
color,
height = 40
}) => {
return (
<Box sx={{ height, width: '100%', mt: 1 }}>
<Suspense fallback={<ChartLoadingFallback />}>
<ResponsiveContainer width="100%" height="100%">
<LazyLineChart data={data}>
<Line
type="monotone"
dataKey="value"
stroke={color}
strokeWidth={2}
dot={false}
isAnimationActive={true}
animationDuration={1000}
/>
</LazyLineChart>
</ResponsiveContainer>
</Suspense>
</Box>
);
};
6.2 Animated Number Component
// components/shared/AnimatedNumber.tsx
import React, { useEffect } from 'react';
import { motion, useMotionValue, useSpring, useTransform } from 'framer-motion';
interface AnimatedNumberProps {
value: number;
format?: (n: number) => string;
duration?: number;
}
export const AnimatedNumber: React.FC<AnimatedNumberProps> = ({
value,
format = (n) => n.toLocaleString(),
duration = 1
}) => {
const motionValue = useMotionValue(0);
const spring = useSpring(motionValue, {
stiffness: 50,
damping: 30
});
const display = useTransform(spring, (latest) => format(Math.round(latest)));
useEffect(() => {
motionValue.set(value);
}, [value, motionValue]);
return <motion.span>{display}</motion.span>;
};
6.3 Usage Limit Progress Ring
// components/billing/UsageLimitRing.tsx
import React, { Suspense } from 'react';
import { Box, Typography } from '@mui/material';
import { LazyPieChart, Pie, Cell, ResponsiveContainer, ChartLoadingFallback } from '../../utils/lazyRecharts';
import { motion } from 'framer-motion';
interface UsageLimitRingProps {
used: number;
limit: number;
label: string;
color: string;
}
export const UsageLimitRing: React.FC<UsageLimitRingProps> = ({
used,
limit,
label,
color
}) => {
const percentage = Math.min((used / limit) * 100, 100);
const data = [
{ name: 'Used', value: used },
{ name: 'Remaining', value: Math.max(0, limit - used) }
];
return (
<Box sx={{ position: 'relative', width: 120, height: 120 }}>
<Suspense fallback={<ChartLoadingFallback />}>
<ResponsiveContainer width="100%" height="100%">
<LazyPieChart>
<Pie
data={data}
cx="50%"
cy="50%"
innerRadius={40}
outerRadius={50}
startAngle={90}
endAngle={-270}
dataKey="value"
animationBegin={0}
animationDuration={1000}
>
<Cell fill={color} />
<Cell fill="rgba(255,255,255,0.1)" />
</Pie>
</LazyPieChart>
</ResponsiveContainer>
</Suspense>
<Box sx={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
textAlign: 'center'
}}>
<Typography variant="h6" sx={{ fontWeight: 'bold' }}>
{Math.round(percentage)}%
</Typography>
<Typography variant="caption" sx={{ fontSize: '0.7rem' }}>
{label}
</Typography>
</Box>
</Box>
);
};
7. Performance Considerations
7.1 Chart Optimization
- ✅ Use lazy loading for all charts
- ✅ Implement
Suspenseboundaries - ✅ Limit data points (max 30-50 for line charts)
- ✅ Use
ResponsiveContainerfor responsive sizing - ✅ Debounce chart updates on window resize
7.2 Animation Optimization
- ✅ Use
will-changeCSS property for animated elements - ✅ Prefer
transformandopacityover layout properties - ✅ Limit simultaneous animations (max 10-15)
- ✅ Use
useReducedMotionhook for accessibility
7.3 Data Aggregation
- ✅ Pre-aggregate data on backend when possible
- ✅ Cache chart data with appropriate TTL
- ✅ Use virtual scrolling for large datasets
8. Accessibility
8.1 Chart Accessibility
- Add
aria-labelto all charts - Provide text alternatives for chart data
- Ensure color contrast meets WCAG AA standards
- Support keyboard navigation for interactive charts
8.2 Animation Accessibility
- Respect
prefers-reduced-motionmedia query - Provide option to disable animations
- Ensure animations don't interfere with screen readers
9. Testing Recommendations
9.1 Visual Regression Testing
- Screenshot tests for all chart types
- Test with various data scenarios (empty, single point, many points)
- Test responsive behavior at different screen sizes
9.2 Animation Testing
- Verify animations complete within performance budget (60fps)
- Test with reduced motion preferences
- Verify animations don't cause layout shifts
10. Conclusion
The billing dashboard has a solid foundation with existing charts and animations. The recommended enhancements will:
- Improve Data Comprehension: More visualizations make patterns easier to spot
- Enhance User Experience: Smooth animations create a polished, professional feel
- Increase Engagement: Interactive charts encourage exploration
- Support Decision Making: Better visualizations help users optimize costs
Next Steps:
- Review and prioritize recommendations with stakeholders
- Create detailed implementation tickets
- Start with Phase 1 (high impact, low effort) items
- Gather user feedback and iterate
Document Version: 1.0
Last Updated: 2025-01-07
Author: AI Assistant
Review Status: Ready for Review