Skip to content

Commit

Permalink
feat: add UI to variant metrics (#3697)
Browse files Browse the repository at this point in the history
  • Loading branch information
sjaanus committed May 8, 2023
1 parent 6053963 commit bacb736
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 19 deletions.
Expand Up @@ -7,7 +7,6 @@ import { Badge } from 'component/common/Badge/Badge';
import { GroupCardActions } from './GroupCardActions/GroupCardActions';
import TopicOutlinedIcon from '@mui/icons-material/TopicOutlined';
import { IProjectRole } from 'interfaces/role';
import { IProject } from 'interfaces/project';

const StyledLink = styled(Link)(({ theme }) => ({
textDecoration: 'none',
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/component/archive/ArchiveTable/ArchiveTable.tsx
Expand Up @@ -34,7 +34,6 @@ import { ArchivedFeatureDeleteConfirm } from './ArchivedFeatureActionCell/Archiv
import { IFeatureToggle } from 'interfaces/featureToggle';
import { useConditionallyHiddenColumns } from 'hooks/useConditionallyHiddenColumns';
import { RowSelectCell } from '../../project/Project/ProjectFeatureToggles/RowSelectCell/RowSelectCell';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { BatchSelectionActionsBar } from '../../common/BatchSelectionActionsBar/BatchSelectionActionsBar';
import { ArchiveBatchActions } from './ArchiveBatchActions';

Expand Down Expand Up @@ -64,7 +63,6 @@ export const ArchiveTable = ({
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const isMediumScreen = useMediaQuery(theme.breakpoints.down('lg'));
const { setToastData, setToastApiError } = useToast();
const { uiConfig } = useUiConfig();

const [deleteModalOpen, setDeleteModalOpen] = useState(false);
const [deletedFeature, setDeletedFeature] = useState<IFeatureToggle>();
Expand Down
Expand Up @@ -5,7 +5,6 @@ import Input from 'component/common/Input/Input';
import { formatUnknownError } from 'utils/formatUnknownError';
import useToast from 'hooks/useToast';
import useProjectApi from 'hooks/api/actions/useProjectApi/useProjectApi';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';

interface IArchivedFeatureDeleteConfirmProps {
deletedFeatures: string[];
Expand Down Expand Up @@ -35,8 +34,7 @@ export const ArchivedFeatureDeleteConfirm = ({
}: IArchivedFeatureDeleteConfirmProps) => {
const [confirmName, setConfirmName] = useState('');
const { setToastData, setToastApiError } = useToast();
const { deleteFeature, deleteFeatures } = useProjectApi();
const { uiConfig } = useUiConfig();
const { deleteFeatures } = useProjectApi();

const onDeleteFeatureToggle = async () => {
try {
Expand Down
Expand Up @@ -13,9 +13,7 @@ import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled';
import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
import { changesCount } from '../../../changesCount';
import {
Box,
IconButton,
Link,
ListItemIcon,
ListItemText,
MenuItem,
Expand All @@ -25,7 +23,7 @@ import {
Tooltip,
Typography,
} from '@mui/material';
import { Delete, Edit, GroupRounded, MoreVert } from '@mui/icons-material';
import { Delete, Edit, MoreVert } from '@mui/icons-material';
import { EditChange } from './EditChange';

const useShowActions = (changeRequest: IChangeRequest, change: IChange) => {
Expand Down
@@ -1,7 +1,6 @@
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { Link, styled, Typography } from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
import { useTheme } from '@mui/system';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';

interface IChangeRequestTitleCellProps {
Expand Down
Expand Up @@ -4,9 +4,10 @@ import { ILocationSettings } from 'hooks/useLocationSettings';
import 'chartjs-adapter-date-fns';
import { Theme } from '@mui/material/styles/createTheme';

interface IPoint {
export interface IPoint {
x: string;
y: number;
variants: Record<string, number>;
}

export const createChartData = (
Expand All @@ -15,7 +16,7 @@ export const createChartData = (
locationSettings: ILocationSettings
): ChartData<'line', IPoint[], string> => {
const requestsSeries = {
label: 'total requests',
label: 'Total requests',
borderColor: theme.palette.primary.main,
backgroundColor: theme.palette.primary.main,
data: createChartPoints(metrics, locationSettings, m => m.yes + m.no),
Expand All @@ -31,7 +32,7 @@ export const createChartData = (
};

const yesSeries = {
label: 'exposed',
label: 'Exposed',
borderColor: theme.palette.success.main,
backgroundColor: theme.palette.success.main,
data: createChartPoints(metrics, locationSettings, m => m.yes),
Expand All @@ -44,7 +45,7 @@ export const createChartData = (
};

const noSeries = {
label: 'not exposed',
label: 'Not exposed',
borderColor: theme.palette.error.main,
backgroundColor: theme.palette.error.main,
data: createChartPoints(metrics, locationSettings, m => m.no),
Expand All @@ -57,7 +58,9 @@ export const createChartData = (
},
};

return { datasets: [yesSeries, noSeries, requestsSeries] };
return {
datasets: [yesSeries, noSeries, requestsSeries],
};
};

const createChartPoints = (
Expand All @@ -68,5 +71,6 @@ const createChartPoints = (
return metrics.map(metric => ({
x: metric.timestamp,
y: y(metric),
variants: metric.variants,
}));
};
Expand Up @@ -4,6 +4,17 @@ import { ChartOptions, defaults } from 'chart.js';
import { IFeatureMetricsRaw } from 'interfaces/featureToggle';
import { formatDateHM } from 'utils/formatDate';
import { Theme } from '@mui/material/styles/createTheme';
import { IPoint } from './createChartData';

const formatVariantEntry = (
variant: [string, number],
totalExposure: number
) => {
if (totalExposure === 0) return '';
const [key, value] = variant;
const percentage = Math.floor((Number(value) / totalExposure) * 100);
return `${value} (${percentage}%) - ${key}`;
};

export const createChartOptions = (
theme: Theme,
Expand All @@ -30,15 +41,38 @@ export const createChartOptions = (
padding: 10,
boxPadding: 5,
usePointStyle: true,
itemSort: (a, b) => {
const order = ['Total requests', 'Exposed', 'Not exposed'];
const aIndex = order.indexOf(a.dataset.label!);
const bIndex = order.indexOf(b.dataset.label!);
return aIndex - bIndex;
},
callbacks: {
label: item => {
return `${item.formattedValue} - ${item.dataset.label}`;
},
afterLabel: item => {
const data = item.dataset.data[
item.dataIndex
] as unknown as IPoint;

if (
item.dataset.label !== 'Exposed' ||
data.variants === undefined
) {
return '';
}
const { disabled, ...actualVariants } = data.variants;
return Object.entries(actualVariants)
.map(entry => formatVariantEntry(entry, data.y))
.join('\n');
},
title: items =>
formatDateHM(
`Time: ${formatDateHM(
items[0].parsed.x,
locationSettings.locale
),
)}`,
},
// Sort tooltip items in the same order as the lines in the chart.
itemSort: (a, b) => b.parsed.y - a.parsed.y,
},
legend: {
position: 'top',
Expand Down
1 change: 1 addition & 0 deletions frontend/src/interfaces/featureToggle.ts
Expand Up @@ -88,4 +88,5 @@ export interface IFeatureMetricsRaw {
timestamp: string;
yes: number;
no: number;
variants: Record<string, number>;
}

0 comments on commit bacb736

Please sign in to comment.