import { useNumber } from '@/hooks/useNumerFormatter'; import type { RouterOutputs } from '@/trpc/client'; import { cn } from '@/utils/cn'; import { max, min } from '@openpanel/common'; import { useReportChartContext } from '../context'; type CohortData = RouterOutputs['chart']['cohort']; type CohortTableProps = { data: CohortData; }; const CohortTable: React.FC = ({ data }) => { const { report: { unit, interval }, } = useReportChartContext(); const isPercentage = unit === '%'; const number = useNumber(); const highestValue = max(data.map((row) => max(row.values))); const lowestValue = min(data.map((row) => min(row.values))); const rowWithHigestSum = data.find( (row) => row.sum === max(data.map((row) => row.sum)), ); const getBackground = (value: number | undefined) => { if (!value) return { backgroundClassName: '', opacity: 0, }; const percentage = isPercentage ? value / 100 : (value - lowestValue) / (highestValue - lowestValue); const opacity = Math.max(0.05, percentage); return { backgroundClassName: 'bg-highlight dark:bg-emerald-700', opacity, }; }; const thClassName = 'h-10 align-top pt-3 whitespace-nowrap font-semibold text-muted-foreground'; return (
{data[0]?.values.map((column, index) => ( ))} {data.map((row) => { const values = isPercentage ? row.percentages : row.values; return ( {values.map((value, index) => { const { opacity, backgroundClassName } = getBackground(value); return ( ); })} ); })}
Date
Total profiles {index === 0 ? `< ${interval} 1` : `${interval} ${index}`}
{row.cohort_interval}
{number.format(row?.sum)} {row.cohort_interval === rowWithHigestSum?.cohort_interval && ' 🚀'}
0.7 && 'text-white [text-shadow:_0_0_3px_rgb(0_0_0_/_20%)]', )} >
{number.formatWithUnit(value, unit)} {value === highestValue && ' 🚀'}
); }; export default CohortTable;