mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
Closes HDX-3220 Closes HDX-1718 Closes HDX-3205 # Summary This PR adds an option that allows users to customize the 0-fill behavior on time charts. The default behavior remains to fill all empty intervals with 0. The user can now disable the filling behavior. When fill is disabled, series will appear to be interpolated. This PR also consolidates various display settings into a drawer, replacing the existing Number Format drawer. In the process, various form-related bugs were fixed in the drawer, and micro/nano second input factors were added. ## New Chart Display Settings Drawer <img width="1697" height="979" alt="Screenshot 2026-01-20 at 9 10 59 AM" src="https://github.com/user-attachments/assets/1683666a-7c56-4018-8e5b-2c6c814f0cd2" /> ## Zero-fill behavior Enabled (default): <img width="1458" height="494" alt="Screenshot 2026-01-20 at 9 12 45 AM" src="https://github.com/user-attachments/assets/0306644e-d2ff-46d6-998b-eb458d5c9ccc" /> Disabled: <img width="1456" height="505" alt="Screenshot 2026-01-20 at 9 12 37 AM" src="https://github.com/user-attachments/assets/f084887e-4099-4365-af4f-73eceaf5dc3d" />
144 lines
3.9 KiB
TypeScript
144 lines
3.9 KiB
TypeScript
import { useCallback } from 'react';
|
|
import { useForm, useWatch } from 'react-hook-form';
|
|
import {
|
|
ChartConfigWithDateRange,
|
|
DisplayType,
|
|
} from '@hyperdx/common-utils/dist/types';
|
|
import {
|
|
Box,
|
|
Button,
|
|
Checkbox,
|
|
Divider,
|
|
Drawer,
|
|
Group,
|
|
Stack,
|
|
} from '@mantine/core';
|
|
|
|
import { shouldFillNullsWithZero } from '@/ChartUtils';
|
|
import { FormatTime } from '@/useFormatTime';
|
|
|
|
import { DEFAULT_NUMBER_FORMAT, NumberFormatForm } from './NumberFormat';
|
|
|
|
export type ChartConfigDisplaySettings = Pick<
|
|
ChartConfigWithDateRange,
|
|
| 'numberFormat'
|
|
| 'alignDateRangeToGranularity'
|
|
| 'fillNulls'
|
|
| 'compareToPreviousPeriod'
|
|
>;
|
|
|
|
interface ChartDisplaySettingsDrawerProps {
|
|
opened: boolean;
|
|
settings: ChartConfigDisplaySettings;
|
|
displayType: DisplayType;
|
|
previousDateRange?: [Date, Date];
|
|
onChange: (settings: ChartConfigDisplaySettings) => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
function applyDefaultSettings({
|
|
numberFormat,
|
|
alignDateRangeToGranularity,
|
|
compareToPreviousPeriod,
|
|
fillNulls,
|
|
}: ChartConfigDisplaySettings): ChartConfigDisplaySettings {
|
|
return {
|
|
numberFormat: numberFormat ?? DEFAULT_NUMBER_FORMAT,
|
|
alignDateRangeToGranularity:
|
|
alignDateRangeToGranularity == null ? true : alignDateRangeToGranularity,
|
|
fillNulls: fillNulls ?? 0,
|
|
compareToPreviousPeriod: compareToPreviousPeriod ?? false,
|
|
};
|
|
}
|
|
|
|
export default function ChartDisplaySettingsDrawer({
|
|
settings,
|
|
opened,
|
|
displayType,
|
|
onChange,
|
|
onClose,
|
|
previousDateRange,
|
|
}: ChartDisplaySettingsDrawerProps) {
|
|
const { control, handleSubmit, register, reset, setValue } =
|
|
useForm<ChartConfigDisplaySettings>({
|
|
defaultValues: applyDefaultSettings(settings),
|
|
});
|
|
|
|
const fillNulls = useWatch({ control, name: 'fillNulls' });
|
|
const isFillNullsEnabled = shouldFillNullsWithZero(fillNulls);
|
|
|
|
const handleClose = useCallback(() => {
|
|
reset(applyDefaultSettings(settings)); // Reset to default values, without saving
|
|
onClose();
|
|
}, [onClose, reset, settings]);
|
|
|
|
const applyChanges = useCallback(() => {
|
|
handleSubmit(onChange)();
|
|
onClose();
|
|
}, [onChange, handleSubmit, onClose]);
|
|
|
|
const resetToDefaults = useCallback(() => {
|
|
reset(applyDefaultSettings({}));
|
|
}, [reset]);
|
|
|
|
const isTimeChart =
|
|
displayType === DisplayType.Line || displayType === DisplayType.StackedBar;
|
|
|
|
return (
|
|
<Drawer
|
|
title="Display Settings"
|
|
opened={opened}
|
|
onClose={handleClose}
|
|
position="right"
|
|
>
|
|
<Stack>
|
|
{isTimeChart && (
|
|
<>
|
|
<Checkbox
|
|
size="xs"
|
|
label="Show Complete Intervals"
|
|
{...register('alignDateRangeToGranularity')}
|
|
/>
|
|
<Box>
|
|
<Checkbox
|
|
size="xs"
|
|
label="Fill Missing Intervals with Zero"
|
|
checked={isFillNullsEnabled}
|
|
onChange={e => {
|
|
setValue('fillNulls', e.currentTarget.checked ? 0 : false);
|
|
}}
|
|
/>
|
|
</Box>
|
|
<Checkbox
|
|
size="xs"
|
|
label="Compare to Previous Period"
|
|
description={
|
|
previousDateRange && (
|
|
<>
|
|
(
|
|
<FormatTime value={previousDateRange[0]} format="short" />
|
|
{' - '}
|
|
<FormatTime value={previousDateRange[1]} format="short" />)
|
|
</>
|
|
)
|
|
}
|
|
{...register('compareToPreviousPeriod')}
|
|
/>
|
|
<Divider />
|
|
</>
|
|
)}
|
|
|
|
<NumberFormatForm control={control} />
|
|
<Divider />
|
|
<Group gap="xs" mt="xs" justify="space-between">
|
|
<Button type="submit" variant="secondary" onClick={resetToDefaults}>
|
|
Reset to Defaults
|
|
</Button>
|
|
<Button type="submit" variant="primary" onClick={applyChanges}>
|
|
Apply
|
|
</Button>
|
|
</Group>
|
|
</Stack>
|
|
</Drawer>
|
|
);
|
|
}
|