← back to Omega Watches 2

src/components/charts/TopMoversChart.tsx

64 lines

'use client';

import { ResponsiveContainer, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Cell } from 'recharts';
import { formatCurrency } from '@/lib/utils';

interface MoverData {
  label: string;
  collection: string;
  model: string;
  stddev: number;
  avg_price: number;
  events: number;
}

interface TopMoversChartProps {
  data: MoverData[];
  title?: string;
}

const CustomTooltip = ({ active, payload }: any) => {
  if (!active || !payload?.length) return null;
  const d = payload[0].payload;
  return (
    <div className="bg-navy-800 border border-navy-600 rounded-lg p-3 shadow-xl">
      <p className="text-xs font-mono text-omega-400">{d.label}</p>
      <p className="text-xs text-white">{d.collection} — {d.model}</p>
      <p className="text-xs text-navy-300">Avg Price: {formatCurrency(d.avg_price)}</p>
      <p className="text-xs text-navy-300">Volatility: \u00B1{formatCurrency(d.stddev)}</p>
      <p className="text-xs text-navy-400">{d.events} events (30d)</p>
    </div>
  );
};

export default function TopMoversChart({ data, title }: TopMoversChartProps) {
  if (!data?.length) {
    return (
      <div className="bg-navy-800/50 rounded-xl border border-navy-700 p-8 text-center">
        <p className="text-navy-400">Not enough data for volatility analysis</p>
      </div>
    );
  }

  const maxStddev = Math.max(...data.map((d) => d.stddev));

  return (
    <div className="bg-navy-800/50 rounded-xl border border-navy-700 p-4">
      {title && <h3 className="text-sm font-semibold uppercase tracking-wider text-gray-400 mb-4">{title}</h3>}
      <ResponsiveContainer width="100%" height={280}>
        <BarChart data={data} layout="vertical" margin={{ top: 5, right: 10, bottom: 5, left: 80 }}>
          <CartesianGrid strokeDasharray="3 3" stroke="#1e293b" horizontal={false} />
          <XAxis type="number" stroke="#64748b" fontSize={11} tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`} />
          <YAxis type="category" dataKey="label" stroke="#64748b" fontSize={10} tick={{ fill: '#c89b3c' }} width={75} />
          <Tooltip content={<CustomTooltip />} />
          <Bar dataKey="stddev" radius={[0, 4, 4, 0]}>
            {data.map((entry, i) => (
              <Cell key={i} fill="#d4842e" fillOpacity={0.4 + (entry.stddev / maxStddev) * 0.6} />
            ))}
          </Bar>
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}