EdgeFunctionInvocationsChart.tsx114 lines · main
1import { Rocket } from 'lucide-react'
2import { useMemo } from 'react'
3import {
4 Bar,
5 CartesianGrid,
6 BarChart as RechartBarChart,
7 ReferenceLine,
8 XAxis,
9 YAxis,
10} from 'recharts'
11import { ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui'
12
13import {
14 formatChartTimestamp,
15 getChartTimeRangeLabels,
16 INVOCATION_CHART_CONFIG,
17} from './EdgeFunctionOverview.utils'
18import type { InvocationChartDatum, InvocationUpdateAnnotation } from './EdgeFunctionOverview.utils'
19
20interface EdgeFunctionInvocationsChartProps {
21 chartData: InvocationChartDatum[]
22 dateTimeFormat: string
23 onChartClick: () => void
24 updateAnnotation?: InvocationUpdateAnnotation
25}
26
27export const EdgeFunctionInvocationsChart = ({
28 chartData,
29 dateTimeFormat,
30 onChartClick,
31 updateAnnotation,
32}: EdgeFunctionInvocationsChartProps) => {
33 const timeRangeLabels = useMemo(
34 () => getChartTimeRangeLabels(chartData, dateTimeFormat),
35 [chartData, dateTimeFormat]
36 )
37
38 return (
39 <div className="flex flex-col gap-1">
40 <div className="relative h-40 w-full overflow-visible">
41 <ChartContainer config={INVOCATION_CHART_CONFIG} className="aspect-auto! h-full! w-full!">
42 <RechartBarChart
43 data={chartData}
44 margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
45 onClick={onChartClick}
46 >
47 <CartesianGrid vertical={false} />
48 <YAxis hide width={0} />
49 <XAxis
50 dataKey="timestamp"
51 tickLine={false}
52 axisLine={false}
53 tick={false}
54 minTickGap={32}
55 />
56 <ChartTooltip
57 cursor={false}
58 content={
59 <ChartTooltipContent
60 className="text-foreground-light"
61 labelFormatter={(value) =>
62 formatChartTimestamp(value as string | number | undefined, dateTimeFormat)
63 }
64 indicator="dot"
65 />
66 }
67 />
68 <Bar
69 dataKey="error_count"
70 stackId="invocations"
71 fill="var(--color-error_count)"
72 maxBarSize={24}
73 />
74 <Bar
75 dataKey="warning_count"
76 stackId="invocations"
77 fill="var(--color-warning_count)"
78 maxBarSize={24}
79 />
80 <Bar
81 dataKey="ok_count"
82 stackId="invocations"
83 fill="var(--color-ok_count)"
84 maxBarSize={24}
85 />
86 {updateAnnotation && (
87 <ReferenceLine
88 x={updateAnnotation.timestamp}
89 stroke="hsl(var(--foreground-default))"
90 strokeDasharray="4 4"
91 strokeWidth={1.5}
92 />
93 )}
94 </RechartBarChart>
95 </ChartContainer>
96 {updateAnnotation && (
97 <span
98 className="pointer-events-none absolute bottom-0 z-10 flex h-6 w-6 -translate-x-1/2 translate-y-1/2 items-center justify-center rounded-full border border-foreground/20 bg-background text-foreground shadow-xs"
99 style={{ left: `${updateAnnotation.position}%` }}
100 title={`Updated ${formatChartTimestamp(updateAnnotation.updatedAt, dateTimeFormat)}`}
101 >
102 <Rocket size={12} strokeWidth={1.75} />
103 </span>
104 )}
105 </div>
106 {timeRangeLabels && (
107 <div className="-mt-6 flex items-center justify-between text-[10px] font-mono text-foreground-lighter">
108 <span>{timeRangeLabels.start}</span>
109 <span>{timeRangeLabels.end}</span>
110 </div>
111 )}
112 </div>
113 )
114}