1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-19 17:52:45 +02:00

Show tooltip on group instead of single graph bar (#10546)

The tooltip should show you the ratio of the group and the numbers for
both archived and created.

The tooltip's position is averaged between all the bars in the group.

<img width="335" height="262" alt="image"
src="https://github.com/user-attachments/assets/d62a4bdc-ba07-4eea-8cbf-6e42793804b2"
/>


This still throws the same errors as before. Not sure exactly what's
going on with the custom tooltip, but I'll investigate it in a
follow-up.

Closes 1-4017.
This commit is contained in:
Thomas Heartman 2025-08-28 10:26:46 +02:00 committed by GitHub
parent 8ba36ee9a2
commit 9eb872de82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 157 deletions

View File

@ -5,7 +5,6 @@ import { useProjectChartData } from 'component/insights/hooks/useProjectChartDat
import { useTheme } from '@mui/material';
import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends';
import { usePlaceholderData } from 'component/insights/hooks/usePlaceholderData';
import { Chart } from 'react-chartjs-2';
import {
CategoryScale,
LinearScale,
@ -19,13 +18,11 @@ import {
Filler,
} from 'chart.js';
import { useLocationSettings } from 'hooks/useLocationSettings';
import {
ChartTooltip,
type TooltipState,
} from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import { createTooltip } from 'component/insights/components/LineChart/createTooltip';
import { CreationArchiveTooltip } from './CreationArchiveTooltip.tsx';
import type { TooltipState } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import type { WeekData, RawWeekData } from './types.ts';
import { createTooltip } from 'component/insights/components/LineChart/createTooltip.ts';
import { CreationArchiveRatioTooltip } from './CreationArchiveRatioTooltip.tsx';
import { Chart } from 'react-chartjs-2';
ChartJS.register(
CategoryScale,
@ -144,6 +141,10 @@ export const CreationArchiveChart: FC<ICreationArchiveChartProps> = ({
data={data}
options={{
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom' as const,
@ -156,7 +157,7 @@ export const CreationArchiveChart: FC<ICreationArchiveChartProps> = ({
},
tooltip: {
enabled: false,
position: 'nearest',
position: 'average',
external: createTooltip(setTooltip),
},
},
@ -187,13 +188,7 @@ export const CreationArchiveChart: FC<ICreationArchiveChartProps> = ({
height={100}
width={250}
/>
{tooltip?.dataPoints?.some(
(point) => point.dataset.label !== 'Flags archived',
) ? (
<CreationArchiveTooltip tooltip={tooltip} />
) : (
<ChartTooltip tooltip={tooltip} />
)}
<CreationArchiveRatioTooltip tooltip={tooltip} />
</>
);
};

View File

@ -1,24 +1,38 @@
import type { FC } from 'react';
import { Box, Paper, Typography, styled, useTheme } from '@mui/material';
import { Paper, Typography, styled } from '@mui/material';
import type { TooltipState } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import { ChartTooltipContainer } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import type { Theme } from '@mui/material/styles/createTheme';
import type { WeekData } from './types.ts';
const getRatioTooltipColors = (theme: Theme) => ({
CREATED: theme.palette.success.main,
ARCHIVED: theme.palette.background.application,
});
const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({
padding: theme.spacing(2),
width: 200,
}));
const StyledFlagItem = styled(Box)(({ theme }) => ({
const DataList = styled('dl')(({ theme }) => ({
margin: 0,
}));
const DataRow = styled('div', {
shouldForwardProp: (prop) => prop !== 'dataType',
})<{ dataType: 'archived' | 'created' }>(({ theme, dataType }) => ({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: theme.spacing(0.5),
whiteSpace: 'nowrap',
fontSize: theme.typography.body2.fontSize,
'::before': {
content: '" "',
display: 'inline-block',
height: '.65rem',
aspectRatio: '1/1',
borderRadius: '50%',
backgroundColor:
dataType === 'archived'
? theme.palette.charts.A2
: theme.palette.charts.A1,
},
}));
interface CreationArchiveRatioTooltipProps {
@ -28,30 +42,14 @@ interface CreationArchiveRatioTooltipProps {
export const CreationArchiveRatioTooltip: FC<
CreationArchiveRatioTooltipProps
> = ({ tooltip }) => {
const theme = useTheme();
const colors = getRatioTooltipColors(theme);
if (!tooltip?.dataPoints) {
return null;
}
const ratioDataPoint = tooltip.dataPoints.find(
(point) => point.dataset.label === 'Flags archived / Flags created',
);
if (!ratioDataPoint) {
return null;
}
const rawData = ratioDataPoint.raw as WeekData;
if (!rawData) {
return null;
}
const rawData = tooltip.dataPoints[0].raw as WeekData;
const archivedCount = rawData.archivedFlags || 0;
const createdCount = rawData.totalCreatedFlags || 0;
const ratio = Math.round(ratioDataPoint.parsed.y as number);
const ratio = Math.round((archivedCount / createdCount) * 100);
return (
<ChartTooltipContainer tooltip={tooltip}>
@ -65,35 +63,16 @@ export const CreationArchiveRatioTooltip: FC<
Ratio {ratio}%
</Typography>
<StyledFlagItem>
<Typography variant='body2' component='span'>
<Typography
sx={{ color: colors.CREATED }}
component='span'
>
{'● '}
</Typography>
Flags created
</Typography>
<Typography variant='body2' component='span'>
{createdCount}
</Typography>
</StyledFlagItem>
<StyledFlagItem>
<Typography variant='body2' component='span'>
<Typography
sx={{ color: colors.ARCHIVED }}
component='span'
>
{'● '}
</Typography>
Flags archived
</Typography>
<Typography variant='body2' component='span'>
{archivedCount}
</Typography>
</StyledFlagItem>
<DataList>
<DataRow dataType='archived'>
<dt>Flags archived</dt>
<dd>{archivedCount}</dd>
</DataRow>
<DataRow dataType='created'>
<dt>Flags created</dt>
<dd>{createdCount}</dd>
</DataRow>
</DataList>
</StyledTooltipItemContainer>
</ChartTooltipContainer>
);

View File

@ -1,77 +0,0 @@
import type { FC } from 'react';
import { Box, Paper, Typography, styled, useTheme } from '@mui/material';
import type { TooltipState } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import { ChartTooltipContainer } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip';
import { getFlagTypeColors } from './flagTypeColors.ts';
import type { WeekData } from './types.ts';
const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({
padding: theme.spacing(2),
width: 240,
}));
const StyledFlagTypeItem = styled(Box)(({ theme }) => ({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
}));
interface CreationArchiveTooltipProps {
tooltip: TooltipState | null;
}
export const CreationArchiveTooltip: FC<CreationArchiveTooltipProps> = ({
tooltip,
}) => {
const theme = useTheme();
if (!tooltip?.dataPoints) {
return null;
}
const createdFlagDataPoints = tooltip.dataPoints.filter(
(point) =>
point.dataset.label !== 'Archived flags' &&
point.dataset.label !== 'Flags archived / Flags created',
);
if (createdFlagDataPoints.length === 0) {
return null;
}
const rawData = createdFlagDataPoints[0]?.raw as WeekData;
const flagTypeNames = createdFlagDataPoints.map(
(point) => point.dataset.label || '',
);
const flagTypeColors = getFlagTypeColors(theme);
return (
<ChartTooltipContainer tooltip={tooltip}>
<StyledTooltipItemContainer elevation={3}>
<Typography
variant='body2'
component='div'
fontWeight='bold'
sx={{ marginBottom: 1 }}
>
Flag type
</Typography>
<Typography variant='body2' component='span'>
<Typography
sx={{ color: flagTypeColors[0] }}
component='span'
>
{'● '}
</Typography>
Total created:
</Typography>
<Typography variant='body2' component='span'>
{rawData.totalCreatedFlags}
</Typography>
</StyledTooltipItemContainer>
</ChartTooltipContainer>
);
};

View File

@ -1,10 +0,0 @@
// todo (lifecycleGraphs): delete this file
import type { Theme } from '@mui/material';
export const getFlagTypeColors = (theme: Theme) => [
theme.palette.success.border,
theme.palette.success.main,
theme.palette.success.dark,
'#4D8007',
'#7D935E',
];