export default function TransactionZoomChart()

in src/components/graphs/TransactionChart.tsx [44:191]


export default function TransactionZoomChart() {
  const chartRef = useRef(null)
  const [chartData, setChartData] = useState([])
  const [refAreaLeft, setRefAreaLeft] = useState(null)
  const [refAreaRight, setRefAreaRight] = useState(null)
  const [left, setLeft] = useState(0)
  const [right, setRight] = useState(0)
  const [top, setTop] = useState(0)
  const [bottom, setBottom] = useState(0)
  const [fullDomain, setFullDomain] = useState({ left: 0, right: 0, top: 0, bottom: 0 })

  useEffect(() => {
    const fetchTransactionHistory = async () => {
      const { default: downsample } = await import("downsample-lttb")
      try {
        const response = await middlewareApi.get("/explorer/getAllEncodedBlocks")
        const decoded = decodeDeltaEncoding(response?.data)

        const points = decoded.map((d) => [d.epoch / 1000, d.volume])
        const sampledPoints = downsample.processData(points, 2000)

        const finalData = sampledPoints.map(([x, y]) => ({
          epoch: x * 1000,
          volume: y,
          createdAt: new Date(x * 1000).toISOString(),
        }))

        const [b, t] = getAxisYDomain(finalData, finalData[0].epoch, finalData[finalData.length - 1].epoch, 1)

        setChartData(finalData)
        setLeft(finalData[0].epoch)
        setRight(finalData[finalData.length - 1].epoch)
        setTop(t)
        setBottom(b)
        setFullDomain({ left: finalData[0].epoch, right: finalData[finalData.length - 1].epoch, top: t, bottom: b })
      } catch (error) {
        console.error("Failed to fetch transaction history:", error)
      }
    }

    fetchTransactionHistory()
  }, [])

  const zoom = () => {
    if (refAreaLeft === null || refAreaRight === null || refAreaLeft === refAreaRight) {
      setRefAreaLeft(null)
      setRefAreaRight(null)
      return
    }

    const [newLeft, newRight] = [Math.min(refAreaLeft, refAreaRight), Math.max(refAreaLeft, refAreaRight)]
    const [newBottom, newTop] = getAxisYDomain(chartData, newLeft, newRight, 1)

    setLeft(newLeft)
    setRight(newRight)
    setTop(newTop)
    setBottom(newBottom)
    setRefAreaLeft(null)
    setRefAreaRight(null)
  }

  const zoomOut = () => {
    setLeft(fullDomain.left)
    setRight(fullDomain.right)
    setTop(fullDomain.top)
    setBottom(fullDomain.bottom)
    setRefAreaLeft(null)
    setRefAreaRight(null)
  }

  const formatXAxis = (epoch) => {
    if (epoch > 1e15) epoch = epoch / 1000
    const date = new Date(epoch)
    if (isNaN(date.getTime())) return "Invalid"
    return date.toLocaleString("en-US", { month: "short", year: "numeric" })
  }

  return (
    <Card className="w-full bg-gradient-to-br from-slate-900 to-slate-950 text-white shadow-xl">
      <CardHeader className="pb-2">
        <div className="flex justify-between">
          <div className="flex items-center gap-2">
            <CardTitle className="text-2xl font-bold">Transaction Timeline</CardTitle>
          </div>
          <Button variant="outline" size="icon" onClick={zoomOut} title="Reset zoom">
            <RefreshCcw className="h-4 w-4" />
          </Button>
        </div>
      </CardHeader>
      <CardContent className="pt-2">
        <div className="w-full h-full" style={{ userSelect: "none" }}>
          <ChartContainer config={{ desktop: { label: "Volume", color: "hsl(var(--chart-1))" } }}>
            <ResponsiveContainer width="100%" height="100%">
              <LineChart
                data={chartData}
                margin={{ top: 5, right: 5, left: 5, bottom: 20 }}
                onMouseDown={(e) => {
                  if (e?.activePayload && e.activePayload[0]) {
                    setRefAreaLeft(e.activePayload[0].payload.epoch)
                  }
                }}
                onMouseMove={(e) => {
                  if (refAreaLeft !== null && e?.activePayload && e.activePayload[0]) {
                    setRefAreaRight(e.activePayload[0].payload.epoch)
                  }
                }}
                onMouseUp={zoom}
              >
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis
                  dataKey="epoch"
                  type="number"
                  domain={[left, right]}
                  allowDataOverflow
                  tickFormatter={formatXAxis}
                  height={30}
                />
                <YAxis type="number" domain={[bottom, top]} allowDataOverflow width={40} />
                <Tooltip
                  content={<ChartTooltipContent indicator="dashed" />}
                  formatter={(value) => ["Volume: ", value]}
                  labelFormatter={(value) =>
                    new Date(value).toLocaleDateString("en-US", {
                      day: "numeric",
                      month: "short",
                      year: "numeric",
                    })
                  }
                />
                <Line
                  dataKey="volume"
                  type="monotone"
                  stroke="hsl(var(--chart-1))"
                  strokeWidth={2}
                  dot={false}
                  animationDuration={750}
                />
                {refAreaLeft && refAreaRight && (
                  <ReferenceArea x1={refAreaLeft} x2={refAreaRight} strokeOpacity={0.3} />
                )}
              </LineChart>
            </ResponsiveContainer>
          </ChartContainer>
        </div>
      </CardContent>
    </Card>
  )
}