mirror of
https://github.com/supabase/supabase.git
synced 2026-10-13 21:29:08 +03:00
feat: add hideHighlightedLabel to ComposedChart
This commit is contained in:
1 parent
ff75c5e837
commit
797ef7c6e0
4 files changed
+141
-2
No files matched your search
@@ -0,0 +1,112 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import ComposedChart from 'ui/Charts/ComposedChart'
|
||||
import { MultiAttribute } from 'ui/Charts/ComposedChart.utils'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export interface QueryMetricChartProps {
|
||||
data: Array<{
|
||||
period_start: string
|
||||
timestamp: number
|
||||
[key: string]: any
|
||||
}>
|
||||
attributes: Array<{
|
||||
attribute: string
|
||||
label: string
|
||||
format: string
|
||||
color?: {
|
||||
light: string
|
||||
dark: string
|
||||
}
|
||||
strokeDasharray?: string
|
||||
type?: 'line'
|
||||
strokeWidth?: number
|
||||
}>
|
||||
selectedMetric: 'rows_read' | 'query_latency' | 'calls' | 'cache_hits'
|
||||
className?: string
|
||||
height?: number
|
||||
}
|
||||
|
||||
export const QueryMetricChart = ({
|
||||
data,
|
||||
attributes,
|
||||
selectedMetric,
|
||||
className = '',
|
||||
height = 264,
|
||||
}: QueryMetricChartProps) => {
|
||||
// Transform attributes into MultiAttribute format for ComposedChart
|
||||
const chartAttributes = useMemo((): MultiAttribute[] => {
|
||||
return attributes.map((attr) => ({
|
||||
attribute: attr.attribute,
|
||||
provider: 'infra-monitoring' as const,
|
||||
label: attr.label,
|
||||
color: attr.color,
|
||||
strokeDasharray: attr.strokeDasharray,
|
||||
type: attr.type === 'line' ? 'line' : 'area-bar',
|
||||
stackId: '1', // Stack all attributes together
|
||||
enabled: true,
|
||||
}))
|
||||
}, [attributes])
|
||||
|
||||
// Transform data to match ComposedChart's expected format
|
||||
const chartData = useMemo(() => {
|
||||
return data.map((item) => {
|
||||
const transformed: Record<string, any> = {
|
||||
timestamp: item.timestamp,
|
||||
period_start: item.period_start,
|
||||
}
|
||||
|
||||
// Add each attribute value
|
||||
attributes.forEach((attr) => {
|
||||
transformed[attr.attribute] = item[attr.attribute] || 0
|
||||
})
|
||||
|
||||
return transformed
|
||||
})
|
||||
}, [data, attributes])
|
||||
|
||||
// Determine format based on selected metric
|
||||
const getFormat = () => {
|
||||
switch (selectedMetric) {
|
||||
case 'query_latency':
|
||||
return 'ms'
|
||||
case 'cache_hits':
|
||||
return '%'
|
||||
case 'rows_read':
|
||||
case 'calls':
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
return (
|
||||
<div className="flex items-center justify-center" style={{ height }}>
|
||||
<div className="text-sm text-foreground-lighter">No data available</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={className} style={{ height }}>
|
||||
<ComposedChart
|
||||
data={chartData}
|
||||
attributes={chartAttributes}
|
||||
xAxisKey="period_start"
|
||||
yAxisKey={attributes[0]?.attribute || 'calls'}
|
||||
format={getFormat()}
|
||||
title=""
|
||||
size="normal"
|
||||
showGrid={true}
|
||||
showTooltip={true}
|
||||
showTotal={true}
|
||||
xAxisIsDate={true}
|
||||
customDateFormat="HH:mm"
|
||||
displayDateInUtc={false}
|
||||
updateDateRange={() => {}} // No-op for now
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, useMemo, useEffect, useCallback } from 'react'
|
||||
|
||||
import {
|
||||
Tabs_Shadcn_,
|
||||
TabsContent_Shadcn_,
|
||||
@@ -282,6 +283,20 @@ export const QueryMetricExplorer = ({ startTime, endTime }: QueryMetricExplorerP
|
||||
return attributes
|
||||
}, [selectedMetric, safeVisiblePercentiles, selectedQuery])
|
||||
|
||||
const transformedChartAttributes = useMemo(() => {
|
||||
return getChartAttributes
|
||||
.filter((attr) => attr.label && attr.format) // Filter out undefined values
|
||||
.map((attr) => ({
|
||||
attribute: attr.attribute,
|
||||
label: attr.label!,
|
||||
format: attr.format!,
|
||||
color: attr.color,
|
||||
strokeDasharray: attr.strokeDasharray,
|
||||
type: attr.type === 'line' ? ('line' as const) : undefined,
|
||||
strokeWidth: typeof attr.strokeWidth === 'number' ? attr.strokeWidth : undefined,
|
||||
}))
|
||||
}, [getChartAttributes])
|
||||
|
||||
// Calculate average P95 for query latency
|
||||
const averageP95 = useMemo(() => {
|
||||
if (selectedMetric === 'query_latency' && metricsData && metricsData.length > 0) {
|
||||
@@ -578,7 +593,9 @@ export const QueryMetricExplorer = ({ startTime, endTime }: QueryMetricExplorerP
|
||||
customDateFormat="HH:mm"
|
||||
hideChartType={true}
|
||||
hideHighlightedValue={true}
|
||||
hideHighlightedLabel={true}
|
||||
showTooltip={true}
|
||||
showGrid={false}
|
||||
showLegend={
|
||||
selectedMetric === 'query_latency' ||
|
||||
selectedMetric === 'cache_hits' ||
|
||||
@@ -587,6 +604,11 @@ export const QueryMetricExplorer = ({ startTime, endTime }: QueryMetricExplorerP
|
||||
showTotal={false}
|
||||
showMaxValue={false}
|
||||
updateDateRange={updateDateRange}
|
||||
YAxisProps={{
|
||||
tick: true,
|
||||
width: 60,
|
||||
tickFormatter: (value) => value.toLocaleString(),
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface ChartHeaderProps {
|
||||
highlightedLabel?: number | string | any | null
|
||||
highlightedValue?: number | string | any | null
|
||||
hideHighlightedValue?: boolean
|
||||
hideHighlightedLabel?: boolean
|
||||
hideChartType?: boolean
|
||||
chartStyle?: string
|
||||
onChartStyleChange?: (style: string) => void
|
||||
@@ -38,6 +39,7 @@ const ChartHeader = ({
|
||||
highlightedValue,
|
||||
highlightedLabel,
|
||||
hideHighlightedValue = false,
|
||||
hideHighlightedLabel = false,
|
||||
title,
|
||||
minimalHeader = false,
|
||||
hideChartType = false,
|
||||
@@ -184,7 +186,7 @@ const ChartHeader = ({
|
||||
{title && chartTitle}
|
||||
<div className="flex flex-row items-baseline gap-x-2">
|
||||
{highlightedValue !== undefined && !hideHighlightedValue && highlighted}
|
||||
{label}
|
||||
{!hideHighlightedLabel && label}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -198,7 +200,7 @@ const ChartHeader = ({
|
||||
{title && chartTitle}
|
||||
<div className="h-4">
|
||||
{hasHighlightedValue && highlighted}
|
||||
{label}
|
||||
{!hideHighlightedLabel && label}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -62,6 +62,7 @@ export interface ComposedChartProps<D = Datum> extends CommonChartProps<D> {
|
||||
titleTooltip?: string
|
||||
hideYAxis?: boolean
|
||||
hideHighlightedValue?: boolean
|
||||
hideHighlightedLabel?: boolean
|
||||
syncId?: string
|
||||
docsUrl?: string
|
||||
}
|
||||
@@ -98,6 +99,7 @@ export default function ComposedChart({
|
||||
updateDateRange,
|
||||
hideYAxis,
|
||||
hideHighlightedValue,
|
||||
hideHighlightedLabel = false,
|
||||
syncId,
|
||||
docsUrl,
|
||||
}: ComposedChartProps) {
|
||||
@@ -307,6 +309,7 @@ export default function ComposedChart({
|
||||
customDateFormat={customDateFormat}
|
||||
highlightedValue={formatHighlightedValue(resolvedHighlightedValue)}
|
||||
highlightedLabel={resolvedHighlightedLabel}
|
||||
hideHighlightedLabel={hideHighlightedLabel}
|
||||
minimalHeader={minimalHeader}
|
||||
hideChartType={hideChartType}
|
||||
chartStyle={chartStyle}
|
||||
|
||||
Reference in new issue
Block a user