Home / Function/ ChartBlock() — supabase Function Reference

ChartBlock() — supabase Function Reference

Architecture documentation for the ChartBlock() function in ChartBlock.tsx from the supabase codebase.

Entity Profile

Relationship Graph

Source Code

apps/studio/components/interfaces/Reports/ReportBlock/ChartBlock.tsx lines 48–304

export const ChartBlock = ({
  label,
  attribute,
  provider,
  startDate,
  endDate,
  interval = '1d',
  defaultChartStyle = 'bar',
  isLoading = false,
  actions,
  maxHeight,
  onUpdateChartConfig,
}: ChartBlockProps) => {
  const router = useRouter()
  const { ref } = router.query

  const state = useDatabaseSelectorStateSnapshot()
  const [chartStyle, setChartStyle] = useState<string>(defaultChartStyle)
  const [latestValue, setLatestValue] = useState<string | undefined>()

  const databaseIdentifier = state.selectedDatabaseId

  const {
    data: dailyStatsData,
    isFetching: isFetchingDailyStats,
    isPending: isLoadingDailyStats,
  } = useProjectDailyStatsQuery(
    {
      projectRef: ref as string,
      attribute: attribute as ProjectDailyStatsAttribute,
      startDate: dayjs(startDate).format('YYYY-MM-DD'),
      endDate: dayjs(endDate).format('YYYY-MM-DD'),
    },
    { enabled: provider === 'daily-stats' }
  )

  const {
    data: infraMonitoringRawData,
    isFetching: isFetchingInfraMonitoring,
    isPending: isLoadingInfraMonitoring,
  } = useInfraMonitoringAttributesQuery(
    {
      projectRef: ref as string,
      attributes: [attribute as InfraMonitoringAttribute],
      startDate,
      endDate,
      interval: interval as AnalyticsInterval,
      databaseIdentifier,
    },
    { enabled: provider === 'infra-monitoring' }
  )

  const infraMonitoringData = useMemo(() => {
    if (!infraMonitoringRawData) return undefined
    const mapped = mapMultiResponseToAnalyticsData(infraMonitoringRawData, [
      attribute as InfraMonitoringAttribute,
    ])
    return mapped[attribute]
  }, [infraMonitoringRawData, attribute])

  const chartData =
    provider === 'infra-monitoring'
      ? infraMonitoringData
      : provider === 'daily-stats'
        ? dailyStatsData
        : undefined

  const isFetching =
    provider === 'infra-monitoring'
      ? isFetchingInfraMonitoring
      : provider === 'daily-stats'
        ? isFetchingDailyStats
        : false

  const loading =
    isLoading ||
    attribute.startsWith('new_snippet_') ||
    (provider === 'infra-monitoring'
      ? isLoadingInfraMonitoring
      : provider === 'daily-stats'
        ? isLoadingDailyStats
        : isLoading)

  const metric = METRICS.find((x) => x.key === attribute)
  const metricLabel = metric?.label ?? attribute

  const getCellColor = (attribute: string, value: number) => {
    const threshold = METRIC_THRESHOLDS[attribute as keyof typeof METRIC_THRESHOLDS]
    if (!threshold) return 'hsl(var(--chart-1))'
    if (threshold.check === 'gt') {
      return value >= threshold.danger
        ? 'hsl(var(--chart-destructive))'
        : value >= threshold.warning
          ? 'hsl(var(--chart-warning))'
          : 'hsl(var(--chart-1))'
    } else {
      return value <= threshold.danger
        ? 'hsl(var(--chart-destructive))'
        : value <= threshold.warning
          ? 'hsl(var(--chart-warning))'
          : 'hsl(var(--chart-1))'
    }
  }

  const isPercentage = chartData?.format === '%'
  const data = (chartData?.data ?? []).map((x: any) => {
    const value = isPercentage ? x[attribute] : x[attribute]
    const color = getCellColor(attribute, x[attribute])
    return {
      ...x,
      period_start: dayjs(x.period_start).utc().format('YYYY-MM-DD'),
      [attribute]: value,
      [metricLabel]: value,
      fill: color,
      stroke: color,
    }
  })

  const getInitialHighlightedValue = useCallback(() => {
    if (!chartData?.data?.length) return undefined
    const lastDataPoint = chartData.data[chartData.data.length - 1]
    const value = lastDataPoint[attribute]
    return isPercentage
      ? `${typeof value === 'number' ? value.toFixed(1) : value}%`
      : typeof value === 'number'
        ? value.toLocaleString()
        : value
  }, [chartData?.data, chartData?.format, attribute])

  useEffect(() => {
    if (defaultChartStyle) setChartStyle(defaultChartStyle)
  }, [defaultChartStyle])

  useEffect(() => {
    setLatestValue(getInitialHighlightedValue())
  }, [chartData, getInitialHighlightedValue])

  return (
    <ReportBlockContainer
      draggable
      showDragHandle
      loading={isFetching}
      icon={metric?.category?.icon('text-foreground-muted')}
      label={label}
      actions={
        <>
          <ButtonTooltip
            type="text"
            size="tiny"
            disabled={loading}
            className="w-7 h-7"
            icon={chartStyle === 'bar' ? <Activity /> : <BarChartIcon />}
            onClick={() => {
              const style = chartStyle === 'bar' ? 'line' : 'bar'
              if (onUpdateChartConfig) onUpdateChartConfig({ chart: { chart_type: style } })
              setChartStyle(style)
            }}
            tooltip={{
              content: {
                side: 'bottom',
                className: 'max-w-56 text-center',
                text: `View as ${chartStyle === 'bar' ? 'line chart' : 'bar chart'}`,
              },
            }}
          />
          {actions}
        </>
      }
    >
      {loading ? (
        <div className="flex flex-grow w-full flex-col items-center justify-center gap-y-2 px-4">
          <Loader2 size={18} className="animate-spin text-border-strong" />
          <p className="text-xs text-foreground-lighter text-center">Loading data for {label}</p>
        </div>
      ) : chartData === undefined ? (
        <div className="flex flex-grow w-full flex-col items-center justify-center gap-y-2 px-4">
          <WarningIcon />
          <p className="text-xs text-foreground-lighter text-center">
            Unable to load data for {label}
          </p>
        </div>
      ) : data.length === 0 ? (
        <div className="flex flex-grow w-full flex-col items-center justify-center gap-y-2">
          <NoDataPlaceholder
            size="small"
            className="border-0"
            description="It may take up to 24 hours for data to refresh"
          />
        </div>
      ) : (
        <>
          {latestValue && (
            <div className="pt-2 px-3 w-full text-left leading-tight">
              <span className="text-xs font-mono uppercase text-foreground-light">
                Most recently
              </span>
              <p className="text-lg text">{latestValue}</p>
            </div>
          )}
          <ChartContainer
            className="w-full aspect-auto px-3 py-2"
            style={{
              height: maxHeight ? `${maxHeight}px` : undefined,
              minHeight: maxHeight ? `${maxHeight}px` : undefined,
            }}
          >
            {chartStyle === 'bar' ? (
              <BarChart accessibilityLayer margin={{ left: 0, right: 0 }} data={data}>
                <CartesianGrid vertical={false} />
                <XAxis
                  dataKey="period_start"
                  tickLine={false}
                  axisLine={false}
                  tickMargin={8}
                  minTickGap={32}
                />
                <YAxis hide domain={isPercentage ? [0, 100] : undefined} />
                <ChartTooltip
                  content={
                    <ChartTooltipContent
                      className="w-[200px]"
                      labelSuffix={isPercentage ? '%' : ''}
                      labelFormatter={(x) => dayjs(x).format('DD MMM YYYY')}
                    />
                  }
                />
                <Bar dataKey={metricLabel} radius={[2, 2, 1, 1]} />
              </BarChart>
            ) : (
              <LineChart accessibilityLayer margin={{ left: 0, right: 0 }} data={data}>
                <CartesianGrid vertical={false} />
                <XAxis
                  dataKey="period_start"
                  tickLine={false}
                  axisLine={false}
                  tickMargin={8}
                  minTickGap={32}
                />
                <YAxis hide domain={isPercentage ? [0, 100] : undefined} />
                <ChartTooltip
                  content={
                    <ChartTooltipContent
                      className="w-[200px]"
                      labelSuffix={chartData?.format === '%' ? '%' : ''}
                      labelFormatter={(x) => dayjs(x).format('DD MMM YYYY')}
                    />
                  }
                />
                <Line dataKey={metricLabel} stroke="hsl(var(--chart-1))" radius={4} />
              </LineChart>
            )}
          </ChartContainer>
        </>
      )}
    </ReportBlockContainer>
  )
}

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free