123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- import {Fragment} from 'react';
- import {browserHistory} from 'react-router';
- 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';
- 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<string, string>;
- };
- 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<string, boolean>;
- 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 = (
- <HeaderTitleLegend>
- {currentFilter === SpanOperationBreakdownFilter.NONE
- ? t('Duration Breakdown')
- : tct('Span Operation Breakdown - [operationName]', {
- operationName: currentFilter,
- })}
- <QuestionTooltip
- size="sm"
- position="top"
- title={t(
- `Duration Breakdown reflects transaction durations by percentile over time.`
- )}
- />
- </HeaderTitleLegend>
- );
- const yAxis = yAxisValues.map(v => `${v}(${parameter})`);
- return (
- <Fragment>
- {header}
- <EventsRequest
- {...requestCommonProps}
- organization={organization}
- showLoading={false}
- includePrevious={false}
- yAxis={yAxis}
- partial
- withoutZerofill={withoutZerofill}
- referrer="api.performance.transaction-summary.duration-chart"
- queryExtras={queryExtras}
- >
- {({results, errored, loading, reloading, timeframe: timeFrame}) => {
- const stripParamsForLegend = seriesResults =>
- seriesResults?.map(series => ({
- ...series,
- seriesName: `${parseFunction(series.seriesName)?.name}()`,
- }));
- return (
- <Content
- series={stripParamsForLegend(results)}
- errored={errored}
- loading={loading}
- reloading={reloading}
- timeFrame={timeFrame}
- {...contentCommonProps}
- />
- );
- }}
- </EventsRequest>
- </Fragment>
- );
- }
- export default DurationChart;
|