import { Color } from '@signozhq/design-tokens'; import { Tooltip, Typography } from 'antd'; import { ColumnType } from 'antd/es/table'; import { MetricsListItemData, MetricsListPayload, MetricType, } from 'api/metricsExplorer/getMetricsList'; import { CardinalityData, DatapointsData, } from 'api/metricsExplorer/getMetricsTreeMap'; import { BarChart, BarChart2, BarChartHorizontal, Diff, Gauge, } from 'lucide-react'; import { useMemo } from 'react'; import { METRIC_TYPE_LABEL_MAP } from './constants'; import { MetricsListItemRowData, TreemapTile, TreemapViewType } from './types'; export const metricsTableColumns: ColumnType[] = [ { title:
METRIC
, dataIndex: 'metric_name', width: 400, sorter: true, className: 'metric-name-column-header', render: (value: string): React.ReactNode => (
{value}
), }, { title: 'DESCRIPTION', dataIndex: 'description', width: 400, }, { title: 'TYPE', dataIndex: 'metric_type', sorter: true, width: 150, }, { title: 'UNIT', dataIndex: 'unit', width: 150, }, { title: 'DATAPOINTS', dataIndex: TreemapViewType.DATAPOINTS, width: 150, sorter: true, }, { title: 'CARDINALITY', dataIndex: TreemapViewType.CARDINALITY, width: 150, sorter: true, }, ]; export const getMetricsListQuery = (): MetricsListPayload => ({ filters: { items: [], op: 'and', }, orderBy: { columnName: 'metric_name', order: 'asc' }, }); export function MetricTypeRenderer({ type, }: { type: MetricType; }): JSX.Element { const [icon, color] = useMemo(() => { switch (type) { case MetricType.SUM: return [ , Color.BG_ROBIN_500, ]; case MetricType.GAUGE: return [ , Color.BG_SAKURA_500, ]; case MetricType.HISTOGRAM: return [ , Color.BG_SIENNA_500, ]; case MetricType.SUMMARY: return [ , Color.BG_FOREST_500, ]; case MetricType.EXPONENTIAL_HISTOGRAM: return [ , Color.BG_AQUA_500, ]; default: return [null, '']; } }, [type]); return (
{icon} {METRIC_TYPE_LABEL_MAP[type]}
); } function ValidateRowValueWrapper({ value, children, }: { value: string | number | null; children: React.ReactNode; }): JSX.Element { if (!value) { return
-
; } return
{children}
; } export const formatDataForMetricsTable = ( data: MetricsListItemData[], ): MetricsListItemRowData[] => data.map((metric) => ({ key: metric.metric_name, metric_name: ( {metric.metric_name} ), description: ( {metric.description} ), metric_type: , unit: ( {metric.unit} ), [TreemapViewType.DATAPOINTS]: ( {metric[TreemapViewType.DATAPOINTS].toLocaleString()} ), [TreemapViewType.CARDINALITY]: ( {metric[TreemapViewType.CARDINALITY]} ), })); export const transformTreemapData = ( data: CardinalityData[] | DatapointsData[], viewType: TreemapViewType, ): TreemapTile[] => { const totalSize = (data as (CardinalityData | DatapointsData)[]).reduce( (acc: number, item: CardinalityData | DatapointsData) => acc + item.percentage, 0, ); const children = data.map((item) => ({ id: item.metric_name, size: totalSize > 0 ? Number((item.percentage / totalSize).toFixed(2)) : 0, displayValue: Number(item.percentage).toFixed(2), parent: viewType, })); return [ { id: viewType, size: 0, parent: null, displayValue: null, }, ...children, ]; }; const getTreemapTileBackgroundColor = (node: TreemapTile): string => { const size = node.size * 10; if (size > 0.8) { return Color.BG_AMBER_600; } if (size > 0.6) { return Color.BG_AMBER_500; } if (size > 0.4) { return Color.BG_AMBER_400; } if (size > 0.2) { return Color.BG_AMBER_300; } if (size > 0.1) { return Color.BG_AMBER_200; } return Color.BG_AMBER_100; }; export const getTreemapTileStyle = ( node: TreemapTile, ): React.CSSProperties => ({ overflow: 'visible', cursor: 'pointer', backgroundColor: getTreemapTileBackgroundColor(node), borderRadius: 4, }); export const getTreemapTileTextStyle = (): React.CSSProperties => ({ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', fontWeight: 'bold', color: Color.TEXT_SLATE_400, textAlign: 'center', padding: '4px', }); export const convertNanoToMilliseconds = (time: number): number => Math.floor(time / 1000000);