/**
* ReportChart
*
* A wrapper component that uses the useChartData hook to fetch data for a chart
* and then passes the data and loading state to the ComposedChartHandler.
*
* This component acts as a bridge between the data-fetching logic and the
* presentational chart component.
*/
import Link from 'next/link'
import { useRef, useState } from 'react'
import type { MultiAttribute } from 'components/ui/Charts/ComposedChart.utils'
import LogChartHandler from 'components/ui/Charts/LogChartHandler'
import Panel from 'components/ui/Panel'
import { useFillTimeseriesSorted } from 'hooks/analytics/useFillTimeseriesSorted'
import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan'
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
import { useChartData } from 'hooks/useChartData'
import type { UpdateDateRange } from 'pages/project/[ref]/reports/database'
import { Button, cn } from 'ui'
const ReportChart = ({
chart,
startDate,
endDate,
interval,
updateDateRange,
functionIds,
isLoading,
className,
}: {
chart: any
startDate: string
endDate: string
interval: string
updateDateRange: UpdateDateRange
functionIds?: string[]
isLoading?: boolean
className?: string
}) => {
const { data: org } = useSelectedOrganizationQuery()
const { plan: orgPlan } = useCurrentOrgPlan()
const orgPlanId = orgPlan?.id
const [isHoveringUpgrade, setIsHoveringUpgrade] = useState(false)
const isAvailable =
chart.availableIn === undefined || (orgPlanId && chart.availableIn.includes(orgPlanId))
const canFetch = orgPlanId !== undefined
const {
data,
isLoading: isLoadingChart,
highlightedValue,
} = useChartData({
attributes: chart.attributes,
startDate,
endDate,
interval,
functionIds,
data: undefined,
enabled: canFetch,
highlightedValue:
chart.id === 'client-connections' || chart.id === 'pgbouncer-connections'
? true
: chart.showMaxValue,
})
const isTopListChart = chart.id === 'top-api-routes' || chart.id === 'top-rpc-functions'
const chartDataArray = Array.isArray(data) ? data : []
const { data: filledData, isError: isFillError } = useFillTimeseriesSorted(
chartDataArray,
'period_start',
chart.attributes.map((attr: any) => attr.attribute),
0,
startDate,
endDate,
undefined,
interval
)
const finalData =
chartDataArray.length > 0 && chartDataArray.length < 20 && !isFillError && !isTopListChart
? filledData
: chartDataArray
const getExpDemoChartData = () =>
new Array(20).fill(0).map((_, index) => ({
period_start: new Date(startDate).getTime() + index * 1000,
demo: Math.floor(Math.pow(1.25, index) * 10),
max_demo: 1000,
}))
const getDemoChartData = () =>
new Array(20).fill(0).map((_, index) => ({
period_start: new Date(startDate).getTime() + index * 1000,
demo: Math.floor(Math.random() * 10) + 1,
max_demo: 1000,
}))
// [Jordi] useRef to prevent re-rendering making the chart change.
const demoChartData = useRef(getDemoChartData())
const exponentialChartData = useRef(getExpDemoChartData())
const chartData = isHoveringUpgrade ? exponentialChartData.current : demoChartData.current
if (!isAvailable && !isLoading) {
return (
This chart is available from{' '} {!!chart.availableIn?.length ? chart.availableIn[0] : 'Pro'} {' '} plan and above