mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-10 17:53:36 +02:00
fix: pr comments
This commit is contained in:
parent
1d373f71e7
commit
cc834f73ef
@ -1,6 +1,6 @@
|
|||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useTheme, Box, Typography, Alert } from '@mui/material';
|
import { Box, Typography, Alert } from '@mui/material';
|
||||||
import {
|
import {
|
||||||
LineChart,
|
LineChart,
|
||||||
NotEnoughData,
|
NotEnoughData,
|
||||||
@ -15,18 +15,11 @@ import { useImpactMetricsMetadata } from 'hooks/api/getters/useImpactMetricsMeta
|
|||||||
import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||||
import { usePlaceholderData } from '../hooks/usePlaceholderData.js';
|
import { usePlaceholderData } from '../hooks/usePlaceholderData.js';
|
||||||
import { ImpactMetricsControls } from './ImpactMetricsControls.tsx';
|
import { ImpactMetricsControls } from './ImpactMetricsControls.tsx';
|
||||||
import {
|
import { getDisplayFormat, getTimeUnit, formatLargeNumbers } from './utils.ts';
|
||||||
getDisplayFormat,
|
|
||||||
getSeriesLabel,
|
|
||||||
getTimeUnit,
|
|
||||||
formatLargeNumbers,
|
|
||||||
} from './utils.ts';
|
|
||||||
import { fromUnixTime } from 'date-fns';
|
import { fromUnixTime } from 'date-fns';
|
||||||
import { useSeriesColor } from './hooks/useSeriesColor.ts';
|
import { useChartData } from './hooks/useChartData.ts';
|
||||||
|
|
||||||
export const ImpactMetrics: FC = () => {
|
export const ImpactMetrics: FC = () => {
|
||||||
const theme = useTheme();
|
|
||||||
const getSeriesColor = useSeriesColor();
|
|
||||||
const [selectedSeries, setSelectedSeries] = useState<string>('');
|
const [selectedSeries, setSelectedSeries] = useState<string>('');
|
||||||
const [selectedRange, setSelectedRange] = useState<
|
const [selectedRange, setSelectedRange] = useState<
|
||||||
'hour' | 'day' | 'week' | 'month'
|
'hour' | 'day' | 'week' | 'month'
|
||||||
@ -78,78 +71,7 @@ export const ImpactMetrics: FC = () => {
|
|||||||
}));
|
}));
|
||||||
}, [metadata]);
|
}, [metadata]);
|
||||||
|
|
||||||
const data = useMemo(() => {
|
const data = useChartData(timeSeriesData);
|
||||||
if (!timeSeriesData || timeSeriesData.length === 0) {
|
|
||||||
return {
|
|
||||||
labels: [],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
data: [],
|
|
||||||
borderColor: theme.palette.primary.main,
|
|
||||||
backgroundColor: theme.palette.primary.light,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timeSeriesData.length === 1) {
|
|
||||||
const series = timeSeriesData[0];
|
|
||||||
const timestamps = series.data.map(
|
|
||||||
([epochTimestamp]) => new Date(epochTimestamp * 1000),
|
|
||||||
);
|
|
||||||
const values = series.data.map(([, value]) => value);
|
|
||||||
|
|
||||||
return {
|
|
||||||
labels: timestamps,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
data: values,
|
|
||||||
borderColor: theme.palette.primary.main,
|
|
||||||
backgroundColor: theme.palette.primary.light,
|
|
||||||
label: getSeriesLabel(series.metric),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
const allTimestamps = new Set<number>();
|
|
||||||
timeSeriesData.forEach((series) => {
|
|
||||||
series.data.forEach(([timestamp]) => {
|
|
||||||
allTimestamps.add(timestamp);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const sortedTimestamps = Array.from(allTimestamps).sort(
|
|
||||||
(a, b) => a - b,
|
|
||||||
);
|
|
||||||
const labels = sortedTimestamps.map(
|
|
||||||
(timestamp) => new Date(timestamp * 1000),
|
|
||||||
);
|
|
||||||
|
|
||||||
const datasets = timeSeriesData.map((series) => {
|
|
||||||
const seriesLabel = getSeriesLabel(series.metric);
|
|
||||||
const color = getSeriesColor(seriesLabel);
|
|
||||||
|
|
||||||
const dataMap = new Map(series.data);
|
|
||||||
|
|
||||||
const data = sortedTimestamps.map(
|
|
||||||
(timestamp) => dataMap.get(timestamp) ?? null,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
label: seriesLabel,
|
|
||||||
data,
|
|
||||||
borderColor: color,
|
|
||||||
backgroundColor: color,
|
|
||||||
fill: false,
|
|
||||||
spanGaps: false, // Don't connect nulls
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
labels,
|
|
||||||
datasets,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [timeSeriesData, theme, getSeriesColor]);
|
|
||||||
|
|
||||||
const hasError = metadataError || dataError;
|
const hasError = metadataError || dataError;
|
||||||
const isLoading = metadataLoading || dataLoading;
|
const isLoading = metadataLoading || dataLoading;
|
||||||
|
@ -143,8 +143,7 @@ export const ImpactMetricsControls: FC<ImpactMetricsControlsProps> = ({
|
|||||||
}
|
}
|
||||||
label='Begin at zero'
|
label='Begin at zero'
|
||||||
/>
|
/>
|
||||||
|
{availableLabels && Object.keys(availableLabels).length > 0 ? (
|
||||||
{availableLabels && Object.keys(availableLabels).length > 0 && (
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||||
<Typography variant='subtitle2'>
|
<Typography variant='subtitle2'>
|
||||||
@ -198,7 +197,7 @@ export const ImpactMetricsControls: FC<ImpactMetricsControlsProps> = ({
|
|||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
) : null}
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import { useTheme } from '@mui/material';
|
||||||
|
import type { ImpactMetricsSeries } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||||
|
import { useSeriesColor } from './useSeriesColor.ts';
|
||||||
|
import { getSeriesLabel } from '../utils.ts';
|
||||||
|
|
||||||
|
export const useChartData = (
|
||||||
|
timeSeriesData: ImpactMetricsSeries[] | undefined,
|
||||||
|
) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
const getSeriesColor = useSeriesColor();
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
if (!timeSeriesData || timeSeriesData.length === 0) {
|
||||||
|
return {
|
||||||
|
labels: [],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [],
|
||||||
|
borderColor: theme.palette.primary.main,
|
||||||
|
backgroundColor: theme.palette.primary.light,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeSeriesData.length === 1) {
|
||||||
|
const series = timeSeriesData[0];
|
||||||
|
const timestamps = series.data.map(
|
||||||
|
([epochTimestamp]) => new Date(epochTimestamp * 1000),
|
||||||
|
);
|
||||||
|
const values = series.data.map(([, value]) => value);
|
||||||
|
|
||||||
|
return {
|
||||||
|
labels: timestamps,
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: values,
|
||||||
|
borderColor: theme.palette.primary.main,
|
||||||
|
backgroundColor: theme.palette.primary.light,
|
||||||
|
label: getSeriesLabel(series.metric),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const allTimestamps = new Set<number>();
|
||||||
|
timeSeriesData.forEach((series) => {
|
||||||
|
series.data.forEach(([timestamp]) => {
|
||||||
|
allTimestamps.add(timestamp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const sortedTimestamps = Array.from(allTimestamps).sort(
|
||||||
|
(a, b) => a - b,
|
||||||
|
);
|
||||||
|
const labels = sortedTimestamps.map(
|
||||||
|
(timestamp) => new Date(timestamp * 1000),
|
||||||
|
);
|
||||||
|
|
||||||
|
const datasets = timeSeriesData.map((series) => {
|
||||||
|
const seriesLabel = getSeriesLabel(series.metric);
|
||||||
|
const color = getSeriesColor(seriesLabel);
|
||||||
|
|
||||||
|
const dataMap = new Map(series.data);
|
||||||
|
|
||||||
|
const data = sortedTimestamps.map(
|
||||||
|
(timestamp) => dataMap.get(timestamp) ?? null,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: seriesLabel,
|
||||||
|
data,
|
||||||
|
borderColor: color,
|
||||||
|
backgroundColor: color,
|
||||||
|
fill: false,
|
||||||
|
spanGaps: false,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
labels,
|
||||||
|
datasets,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [timeSeriesData, theme, getSeriesColor]);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user