"use client" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { ResponsiveContainer, ScatterChart, Scatter, XAxis, YAxis, ZAxis, Tooltip, CartesianGrid, TooltipProps } from "recharts" import { format } from "date-fns" import { Badge } from "@/components/ui/badge" import { TrendingUp, Info } from "lucide-react" interface Performance { id: number show_date: string avg_rating: number venue_name: string venue_city: string venue_state: string | null show_id: number } interface SongEvolutionChartProps { performances: Performance[] title?: string } const CustomTooltip = ({ active, payload }: TooltipProps) => { if (active && payload && payload.length) { const data = payload[0].payload return (
{format(new Date(data.date), "MMM d, yyyy")}
{data.venue}
Rating: ★ {data.rating.toFixed(1)}
) } return null } export function SongEvolutionChart({ performances, title = "Rating Evolution" }: SongEvolutionChartProps) { // Filter out unrated performances to keep chart clean? // Or keep them as 0? Usually 0 skews the chart. Let's filter > 0 for "Evolution of Quality". const ratedPerfs = performances .filter(p => p.avg_rating > 0) .map(p => ({ id: p.id, date: new Date(p.show_date).getTime(), rating: p.avg_rating, venue: `${p.venue_name}, ${p.venue_city}`, fullDate: p.show_date })) .sort((a, b) => a.date - b.date) if (ratedPerfs.length < 2) { return null } // Calculate trend? Simple linear/avg for now. const average = ratedPerfs.reduce((acc, curr) => acc + curr.rating, 0) / ratedPerfs.length const latest = ratedPerfs[ratedPerfs.length - 1].rating const isTrendingUp = latest >= average return (
{title} {ratedPerfs.length > 5 && (
Avg: {average.toFixed(1)}
)}
format(new Date(unixTime), "yyyy")} stroke="hsl(var(--muted-foreground))" fontSize={12} tickLine={false} axisLine={false} dy={10} /> } cursor={{ strokeDasharray: '3 3' }} />
) }