import {Fragment} from 'react'; import {useTheme} from '@emotion/react'; import type {Query} from 'history'; import EventsRequest from 'sentry/components/charts/eventsRequest'; import {HeaderTitleLegend} from 'sentry/components/charts/styles'; import {getInterval, getSeriesSelection} from 'sentry/components/charts/utils'; import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse'; import QuestionTooltip from 'sentry/components/questionTooltip'; import {t, tct} from 'sentry/locale'; import type {OrganizationSummary} from 'sentry/types/organization'; import {browserHistory} from 'sentry/utils/browserHistory'; import {getUtcToLocalDateObject} from 'sentry/utils/dates'; import {parseFunction} from 'sentry/utils/discover/fields'; import useApi from 'sentry/utils/useApi'; import {useLocation} from 'sentry/utils/useLocation'; import useRouter from 'sentry/utils/useRouter'; import type {ViewProps} from '../../../types'; import { SPAN_OPERATION_BREAKDOWN_FILTER_TO_FIELD, SpanOperationBreakdownFilter, } from '../../filter'; import Content from './content'; type Props = ViewProps & { currentFilter: SpanOperationBreakdownFilter; organization: OrganizationSummary; queryExtra: Query; withoutZerofill: boolean; queryExtras?: Record; }; const yAxisValues = ['p50', 'p75', 'p95', 'p99', 'p100', 'avg']; /** * Fetch and render a stacked area chart that shows duration percentiles over * the past 7 days */ function DurationChart({ project, environment, organization, query, statsPeriod, queryExtra, currentFilter, withoutZerofill, start: propsStart, end: propsEnd, queryExtras, }: Props) { const router = useRouter(); const location = useLocation(); const api = useApi(); const theme = useTheme(); function handleLegendSelectChanged(legendChange: { name: string; selected: Record; type: string; }) { const {selected} = legendChange; const unselected = Object.keys(selected).filter(key => !selected[key]); const to = { ...location, query: { ...location.query, unselectedSeries: unselected, }, }; browserHistory.push(to); } const start = propsStart ? getUtcToLocalDateObject(propsStart) : null; const end = propsEnd ? getUtcToLocalDateObject(propsEnd) : null; const utc = normalizeDateTimeParams(location.query).utc === 'true'; const period = statsPeriod; const legend = {right: 10, top: 5, selected: getSeriesSelection(location)}; const datetimeSelection = {start, end, period}; const contentCommonProps = { theme, router, start, end, utc, legend, queryExtra, period, projects: project, environments: environment, onLegendSelectChanged: handleLegendSelectChanged, }; const requestCommonProps = { api, start, end, project, environment, query, period, interval: getInterval(datetimeSelection, 'high'), }; const parameter = SPAN_OPERATION_BREAKDOWN_FILTER_TO_FIELD[currentFilter] ?? 'transaction.duration'; const header = ( {currentFilter === SpanOperationBreakdownFilter.NONE ? t('Duration Breakdown') : tct('Span Operation Breakdown - [operationName]', { operationName: currentFilter, })} ); const yAxis = yAxisValues.map(v => `${v}(${parameter})`); return ( {header} {({results, errored, loading, reloading, timeframe: timeFrame}) => { const stripParamsForLegend = seriesResults => seriesResults?.map(series => ({ ...series, seriesName: `${parseFunction(series.seriesName)?.name}()`, })); return ( ); }} ); } export default DurationChart;