123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import {useCallback, useMemo} from 'react';
- import type {Location} from 'history';
- import {
- FORTY_EIGHT_HOURS,
- getDiffInMinutes,
- GranularityLadder,
- ONE_WEEK,
- SIX_HOURS,
- THIRTY_DAYS,
- TWO_WEEKS,
- } from 'sentry/components/charts/utils';
- import {t} from 'sentry/locale';
- import type {PageFilters} from 'sentry/types/core';
- import {parsePeriodToHours} from 'sentry/utils/duration/parsePeriodToHours';
- import {decodeScalar} from 'sentry/utils/queryString';
- import {useLocation} from 'sentry/utils/useLocation';
- import {useNavigate} from 'sentry/utils/useNavigate';
- import usePageFilters from 'sentry/utils/usePageFilters';
- interface Options {
- location: Location;
- navigate: ReturnType<typeof useNavigate>;
- pagefilters: ReturnType<typeof usePageFilters>;
- }
- export function useChartInterval(): [
- string,
- (interval: string) => void,
- intervalOptions: {label: string; value: string}[],
- ] {
- const location = useLocation();
- const navigate = useNavigate();
- const pagefilters = usePageFilters();
- const options = {location, navigate, pagefilters};
- return useChartIntervalImpl(options);
- }
- function useChartIntervalImpl({
- location,
- navigate,
- pagefilters,
- }: Options): [
- string,
- (interval: string) => void,
- intervalOptions: {label: string; value: string}[],
- ] {
- const {datetime} = pagefilters.selection;
- const intervalOptions = useMemo(
- () => getIntervalOptionsForPageFilter(datetime),
- [datetime]
- );
- const interval: string = useMemo(() => {
- const decodedInterval = decodeScalar(location.query.interval);
- return decodedInterval &&
- intervalOptions.some(option => option.value === decodedInterval)
- ? decodedInterval
- : // Default to the second option so we're not defaulting to the smallest option
- intervalOptions[1]!.value;
- }, [location.query.interval, intervalOptions]);
- const setInterval = useCallback(
- (newInterval: string) => {
- navigate({
- ...location,
- query: {
- ...location.query,
- interval: newInterval,
- },
- });
- },
- [location, navigate]
- );
- return [interval, setInterval, intervalOptions];
- }
- const ALL_INTERVAL_OPTIONS = [
- {value: '1m', label: t('1 minute')},
- {value: '5m', label: t('5 minutes')},
- {value: '15m', label: t('15 minutes')},
- {value: '30m', label: t('30 minutes')},
- {value: '1h', label: t('1 hour')},
- {value: '3h', label: t('3 hours')},
- {value: '12h', label: t('12 hours')},
- {value: '1d', label: t('1 day')},
- ];
- /**
- * The minimum interval is chosen in such a way that there will be
- * at most 1000 data points per series for the chosen period.
- */
- const MINIMUM_INTERVAL = new GranularityLadder([
- [THIRTY_DAYS, '3h'],
- [TWO_WEEKS, '1h'],
- [ONE_WEEK, '30m'],
- [FORTY_EIGHT_HOURS, '15m'],
- [SIX_HOURS, '5m'],
- [0, '1m'],
- ]);
- const MAXIMUM_INTERVAL = new GranularityLadder([
- [THIRTY_DAYS, '1d'],
- [TWO_WEEKS, '1d'],
- [ONE_WEEK, '1d'],
- [FORTY_EIGHT_HOURS, '4h'],
- [SIX_HOURS, '1h'],
- [0, '15m'],
- ]);
- export function getIntervalOptionsForPageFilter(datetime: PageFilters['datetime']) {
- const diffInMinutes = getDiffInMinutes(datetime);
- const minimumOption = MINIMUM_INTERVAL.getInterval(diffInMinutes);
- const minimumOptionInHours = parsePeriodToHours(minimumOption);
- const maximumOption = MAXIMUM_INTERVAL.getInterval(diffInMinutes);
- const maximumOptionInHours = parsePeriodToHours(maximumOption);
- return ALL_INTERVAL_OPTIONS.filter(option => {
- const optionInHours = parsePeriodToHours(option.value);
- return optionInHours >= minimumOptionInHours && optionInHours <= maximumOptionInHours;
- });
- }
|