'use client'; import type { RouterOutputs } from '@/trpc/client'; import { api } from '@/trpc/client'; import { cn } from '@/utils/cn'; import { getChartColor } from '@/utils/theme'; import { CartesianGrid, Line, LineChart, ReferenceLine, ResponsiveContainer, XAxis, YAxis, } from 'recharts'; import { createChartTooltip } from '@/components/charts/chart-tooltip'; import { useFormatDateInterval } from '@/hooks/useFormatDateInterval'; import { useNumber } from '@/hooks/useNumerFormatter'; import { average, getPreviousMetric, round } from '@openpanel/common'; import type { IInterval } from '@openpanel/validation'; import { Fragment } from 'react'; import { useXAxisProps, useYAxisProps } from '../common/axis'; import { PreviousDiffIndicatorPure } from '../common/previous-diff-indicator'; import { useReportChartContext } from '../context'; interface Props { data: RouterOutputs['chart']['conversion']; } export function Chart({ data }: Props) { const { report: { previous, interval, projectId, startDate, endDate, range, lineType, events, }, isEditMode, options: { hideXAxis, hideYAxis, maxDomain }, } = useReportChartContext(); const dataLength = data.current.length || 0; const references = api.reference.getChartReferences.useQuery( { projectId, startDate, endDate, range, }, { staleTime: 1000 * 60 * 10, }, ); const xAxisProps = useXAxisProps({ interval, hide: hideXAxis }); const yAxisProps = useYAxisProps({ hide: hideYAxis, }); const averageConversionRate = average( data.current.map((serie) => { return average(serie.data.map((item) => item.rate)); }, 0), ); return (
{references.data?.map((ref) => ( ))} {data.current.map((serie, index) => { const color = getChartColor(index); return ( ); })} {typeof averageConversionRate === 'number' && averageConversionRate && ( )}
); } const { Tooltip, TooltipProvider } = createChartTooltip< NonNullable< RouterOutputs['chart']['conversion']['current'][number] >['data'][number], { conversion: RouterOutputs['chart']['conversion']; interval: IInterval; } >(({ data, context }) => { if (!data[0]) { return null; } const { date } = data[0]; const formatDate = useFormatDateInterval(context.interval); const number = useNumber(); return ( <>
{formatDate(date)}
{context.conversion.current.map((serie, index) => { const item = data[index]; if (!item) { return null; } const prevItem = context.conversion?.previous?.[item.serieIndex]?.data[item.index]; const title = serie.breakdowns.length > 0 ? (serie.breakdowns.join(',') ?? 'Not set') : 'Conversion'; return (
{title}
{number.formatWithUnit(item.rate / 100, '%')} ({number.format(item.total)})
); })} ); });