| 1 | import { useMemo } from "react"; |
| 2 | import { View } from "react-native"; |
| 3 | |
| 4 | import type { DailyTotals } from "@t3tools/shared/usageMerge"; |
| 5 | |
| 6 | import { buildChartDays, type UsageChartMetric } from "./usageChartData"; |
| 7 | import { useProviderColors } from "./usageProviders"; |
| 8 | |
| 9 | export interface UsageDailyChartProps { |
| 10 | readonly days: readonly string[]; |
| 11 | readonly daily: readonly DailyTotals[]; |
| 12 | readonly metric: UsageChartMetric; |
| 13 | readonly height: number; |
| 14 | } |
| 15 | |
| 16 | /** |
| 17 | * Stacked daily bars drawn with plain views. Android and any platform without |
| 18 | * Swift Charts land here; iOS resolves `UsageDailyChart.ios.tsx` instead. |
| 19 | */ |
| 20 | export function UsageDailyChart({ days, daily, metric, height }: UsageDailyChartProps) { |
| 21 | const colors = useProviderColors(); |
| 22 | const chartDays = useMemo(() => buildChartDays(days, daily, metric), [days, daily, metric]); |
| 23 | const max = chartDays.reduce((peak, day) => Math.max(peak, day.total), 0); |
| 24 | |
| 25 | return ( |
| 26 | <View style={{ height }} className="flex-row items-end gap-px"> |
| 27 | {/* column-reverse stacks the bottom-first provider values upward |
| 28 | without reversing the array (Hermes lacks Array#toReversed). */} |
| 29 | {chartDays.map((day) => ( |
| 30 | <View key={day.day} className="h-full flex-1 flex-col-reverse overflow-hidden rounded-sm"> |
| 31 | {day.values.map((entry) => ( |
| 32 | <View |
| 33 | key={entry.provider} |
| 34 | style={{ |
| 35 | height: max === 0 ? 0 : (entry.value / max) * height, |
| 36 | backgroundColor: colors[entry.provider], |
| 37 | }} |
| 38 | /> |
| 39 | ))} |
| 40 | </View> |
| 41 | ))} |
| 42 | </View> |
| 43 | ); |
| 44 | } |