← back to Omega Watches 2

src/components/charts/ScatterPlot.tsx

73 lines

'use client';

import { ResponsiveContainer, ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, Tooltip, ZAxis } from 'recharts';
import { formatCurrency, formatDate } from '@/lib/utils';

interface ScatterPoint {
  x: number;  // timestamp or numeric
  y: number;  // price
  label?: string;
  source?: string;
  event_type?: string;
}

interface ScatterPlotProps {
  data: ScatterPoint[];
  title?: string;
  xLabel?: string;
  yLabel?: 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">
      {d.label && <p className="text-sm font-medium text-white">{d.label}</p>}
      <p className="text-xs text-navy-300">{formatDate(new Date(d.x).toISOString())}</p>
      <p className="text-sm text-omega-400">{formatCurrency(d.y)}</p>
      {d.source && <p className="text-xs text-navy-400">{d.source}</p>}
    </div>
  );
};

export default function ScatterPlot({ data, title, xLabel, yLabel }: ScatterPlotProps) {
  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">No scatter data available</p>
      </div>
    );
  }

  return (
    <div className="bg-navy-800/50 rounded-xl border border-navy-700 p-4">
      {title && <h3 className="text-lg font-semibold text-white mb-4">{title}</h3>}
      <ResponsiveContainer width="100%" height={350}>
        <ScatterChart margin={{ top: 5, right: 20, bottom: 5, left: 20 }}>
          <CartesianGrid strokeDasharray="3 3" stroke="#1e293b" />
          <XAxis
            type="number"
            dataKey="x"
            name={xLabel || 'Date'}
            tickFormatter={(v) => formatDate(new Date(v).toISOString())}
            stroke="#64748b"
            fontSize={11}
          />
          <YAxis
            type="number"
            dataKey="y"
            name={yLabel || 'Price'}
            tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`}
            stroke="#64748b"
            fontSize={11}
          />
          <ZAxis range={[40, 120]} />
          <Tooltip content={<CustomTooltip />} />
          <Scatter data={data} fill="#c89b3c" fillOpacity={0.7} />
        </ScatterChart>
      </ResponsiveContainer>
    </div>
  );
}