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:
parent
8ba36ee9a2
commit
9eb872de82
@ -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} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
@ -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',
|
||||
];
|
Loading…
Reference in New Issue
Block a user