Skip to content

ref(insights): Refactor PerformanceScoreBreakdownChart #89632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {Series} from 'sentry/types/echarts';
import {ORDER} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreChart';
import type {WebVitalsScoreBreakdown} from 'sentry/views/insights/browser/webVitals/queries/storedScoreQueries/useProjectWebVitalsScoresTimeseriesQuery';
import type {WebVitals} from 'sentry/views/insights/browser/webVitals/types';

export function formatTimeSeriesResultsToChartData(
data: WebVitalsScoreBreakdown,
segmentColors: string[],
order: WebVitals[] = ORDER
): Series[] {
return order.map((webVital, index) => {
const series = data[webVital];
const color = segmentColors[index];
return {
seriesName: webVital.toUpperCase(),
data: series.map(({name, value}) => ({
name,
value: Math.round(value),
})),
color,
};
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestin

import {useLocation} from 'sentry/utils/useLocation';
import usePageFilters from 'sentry/utils/usePageFilters';
import {
formatTimeSeriesResultsToChartData,
PerformanceScoreBreakdownChart,
} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreBreakdownChart';
import {formatTimeSeriesResultsToChartData} from 'sentry/views/insights/browser/webVitals/components/charts/formatTimeSeriesResultsToChartData';
import {PerformanceScoreBreakdownChartWidget} from 'sentry/views/insights/common/components/widgets/performanceScoreBreakdownChartWidget';

jest.mock('sentry/utils/useLocation');
jest.mock('sentry/utils/usePageFilters');

describe('PerformanceScoreBreakdownChart', function () {
describe('PerformanceScoreBreakdownChartWidget', function () {
const organization = OrganizationFixture();
let eventsStatsMock: jest.Mock;

Expand Down Expand Up @@ -75,7 +73,7 @@ describe('PerformanceScoreBreakdownChart', function () {
action: 'PUSH',
key: '',
});
render(<PerformanceScoreBreakdownChart />, {organization});
render(<PerformanceScoreBreakdownChartWidget />, {organization});
await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator'));

expect(eventsStatsMock).toHaveBeenCalledWith(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,17 @@ import {DEFAULT_RELATIVE_PERIODS} from 'sentry/constants';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import usePageFilters from 'sentry/utils/usePageFilters';
import {PerformanceScoreBreakdownChart} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreBreakdownChart';
import PerformanceScoreRingWithTooltips from 'sentry/views/insights/browser/webVitals/components/performanceScoreRingWithTooltips';
import {MODULE_DOC_LINK} from 'sentry/views/insights/browser/webVitals/settings';
import type {
ProjectScore,
WebVitals,
} from 'sentry/views/insights/browser/webVitals/types';
import type {BrowserType} from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType';
import type {SubregionCode} from 'sentry/views/insights/types';
import {PerformanceScoreBreakdownChartWidget} from 'sentry/views/insights/common/components/widgets/performanceScoreBreakdownChartWidget';

type Props = {
browserTypes?: BrowserType[];
isProjectScoreLoading?: boolean;
projectScore?: ProjectScore;
subregions?: SubregionCode[];
transaction?: string;
webVital?: WebVitals | null;
};

Expand All @@ -33,10 +28,7 @@ export const ORDER: WebVitals[] = ['lcp', 'fcp', 'inp', 'cls', 'ttfb'];
export function PerformanceScoreChart({
projectScore,
webVital,
transaction,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only pageOverview passes transaction, and it comes from query params, so this was moved into the new widget

isProjectScoreLoading,
browserTypes,
subregions,
Comment on lines -38 to -39
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto re: query params and moving to new widget

}: Props) {
const theme = useTheme();
const pageFilters = usePageFilters();
Expand Down Expand Up @@ -101,15 +93,17 @@ export function PerformanceScoreChart({
</EmptyStateWarning>
)}
</PerformanceScoreLabelContainer>
<PerformanceScoreBreakdownChart
transaction={transaction}
browserTypes={browserTypes}
subregions={subregions}
/>
<ChartContainer>
<PerformanceScoreBreakdownChartWidget />
</ChartContainer>
</Flex>
);
}

const ChartContainer = styled('div')`
flex: 1 1 0%;
`;

const Flex = styled('div')`
display: flex;
flex-direction: row;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import useOrganization from 'sentry/utils/useOrganization';
import useProjects from 'sentry/utils/useProjects';
import useRouter from 'sentry/utils/useRouter';
import BrowserTypeSelector from 'sentry/views/insights/browser/webVitals/components/browserTypeSelector';
import {PerformanceScoreBreakdownChart} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreBreakdownChart';
import {PageOverviewSidebar} from 'sentry/views/insights/browser/webVitals/components/pageOverviewSidebar';
import {PageOverviewWebVitalsDetailPanel} from 'sentry/views/insights/browser/webVitals/components/pageOverviewWebVitalsDetailPanel';
import {PageSamplePerformanceTable} from 'sentry/views/insights/browser/webVitals/components/tables/pageSamplePerformanceTable';
Expand All @@ -32,6 +31,7 @@ import {WebVitalMetersPlaceholder} from 'sentry/views/insights/browser/webVitals
import {ModulePageFilterBar} from 'sentry/views/insights/common/components/modulePageFilterBar';
import {ModulePageProviders} from 'sentry/views/insights/common/components/modulePageProviders';
import {ModuleBodyUpsellHook} from 'sentry/views/insights/common/components/moduleUpsellHookWrapper';
import {PerformanceScoreBreakdownChartWidget} from 'sentry/views/insights/common/components/widgets/performanceScoreBreakdownChartWidget';
import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL';
import {useWebVitalsDrawer} from 'sentry/views/insights/common/utils/useWebVitalsDrawer';
import {FrontendHeader} from 'sentry/views/insights/pages/frontend/frontendPageHeader';
Expand Down Expand Up @@ -196,11 +196,9 @@ export function PageOverview() {
<BrowserTypeSelector />
</TopMenuContainer>
<Flex>
<PerformanceScoreBreakdownChart
transaction={transaction}
browserTypes={browserTypes}
subregions={subregions}
/>
<ChartContainer>
<PerformanceScoreBreakdownChartWidget />
</ChartContainer>
</Flex>
<WebVitalMetersContainer>
{(isPending || isProjectScoresLoading) && <WebVitalMetersPlaceholder />}
Expand Down Expand Up @@ -267,6 +265,10 @@ const Flex = styled('div')`
gap: ${space(1)};
`;

const ChartContainer = styled('div')`
flex: 1 1 0%;
`;

const PageSamplePerformanceTableContainer = styled('div')`
margin-top: ${space(1)};
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ export function WebVitalsLandingPage() {
projectScore={projectScore}
isProjectScoreLoading={isPending || isProjectScoresLoading}
webVital={state.webVital}
browserTypes={browserTypes}
subregions={subregions}
Comment on lines -98 to -99
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new widget grabs these itself from query params

/>
</PerformanceScoreChartContainer>
<WebVitalMetersContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,42 @@
import {useTheme} from '@emotion/react';
import styled from '@emotion/styled';

import {t} from 'sentry/locale';
import type {Series} from 'sentry/types/echarts';
import {decodeList} from 'sentry/utils/queryString';
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
import useLocationQuery from 'sentry/utils/url/useLocationQuery';
import {ORDER} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreChart';
import type {WebVitalsScoreBreakdown} from 'sentry/views/insights/browser/webVitals/queries/storedScoreQueries/useProjectWebVitalsScoresTimeseriesQuery';
import {WebVitalsWeightList} from 'sentry/views/insights/browser/webVitals/components/charts/webVitalWeightList';
import type {WebVitals} from 'sentry/views/insights/browser/webVitals/types';
import {getWeights} from 'sentry/views/insights/browser/webVitals/utils/getWeights';
import type {BrowserType} from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType';
import decodeBrowserTypes from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType';
import {useDefaultWebVitalsQuery} from 'sentry/views/insights/browser/webVitals/utils/useDefaultQuery';
import {InsightsTimeSeriesWidget} from 'sentry/views/insights/common/components/insightsTimeSeriesWidget';
import type {LoadableChartWidgetProps} from 'sentry/views/insights/common/components/widgets/types';
import {
type DiscoverSeries,
useMetricsSeries,
} from 'sentry/views/insights/common/queries/useDiscoverSeries';
import {SpanMetricsField, type SubregionCode} from 'sentry/views/insights/types';
import {SpanIndexedField, SpanMetricsField} from 'sentry/views/insights/types';

import {WebVitalsWeightList} from './webVitalWeightList';

type Props = {
browserTypes?: BrowserType[];
subregions?: SubregionCode[];
transaction?: string;
};

export function formatTimeSeriesResultsToChartData(
data: WebVitalsScoreBreakdown,
segmentColors: string[],
order: WebVitals[] = ORDER
): Series[] {
return order.map((webVital, index) => {
const series = data[webVital];
const color = segmentColors[index];
return {
seriesName: webVital.toUpperCase(),
data: series.map(({name, value}) => ({
name,
value: Math.round(value),
})),
color,
};
export function PerformanceScoreBreakdownChartWidget(props: LoadableChartWidgetProps) {
const {
transaction,
[SpanIndexedField.BROWSER_NAME]: browserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: subregions,
} = useLocationQuery({
fields: {
[SpanIndexedField.BROWSER_NAME]: decodeBrowserTypes,
[SpanIndexedField.USER_GEO_SUBREGION]: decodeList,
transaction: decodeList,
},
});
}

export function PerformanceScoreBreakdownChart({
transaction,
browserTypes,
subregions,
}: Props) {
const theme = useTheme();
const segmentColors = theme.chart.getColorPalette(3).slice(0, 5);
const defaultQuery = useDefaultWebVitalsQuery();

const search = new MutableSearch(`${defaultQuery} has:measurements.score.total`);

if (transaction) {
search.addFilterValue('transaction', transaction);
if (transaction.length && transaction[0]) {
search.addFilterValue('transaction', transaction[0]);
}

if (subregions) {
Expand Down Expand Up @@ -84,7 +64,8 @@ export function PerformanceScoreBreakdownChart({
],
transformAliasToInputFormat: true,
},
'api.performance.browser.web-vitals.timeseries-scores2'
'api.performance.browser.web-vitals.timeseries-scores2',
props.pageFilters
);

const webVitalsThatHaveData: WebVitals[] = vitalScoresData
Expand Down Expand Up @@ -127,20 +108,14 @@ export function PerformanceScoreBreakdownChart({
: [];

return (
<ChartContainer>
<InsightsTimeSeriesWidget
title={t('Score Breakdown')}
height="100%"
visualizationType="area"
isLoading={areVitalScoresLoading}
error={vitalScoresError}
series={allSeries}
description={<WebVitalsWeightList weights={weights} />}
/>
</ChartContainer>
<InsightsTimeSeriesWidget
title={t('Score Breakdown')}
height="100%"
visualizationType="area"
isLoading={areVitalScoresLoading}
error={vitalScoresError}
series={allSeries}
description={<WebVitalsWeightList weights={weights} />}
/>
);
}

const ChartContainer = styled('div')`
flex: 1 1 0%;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ export const useEAPSeries = <

export const useMetricsSeries = <Fields extends MetricsProperty[]>(
options: UseMetricsSeriesOptions<Fields> = {},
referrer: string
referrer: string,
pageFilters?: PageFilters
) => {
const useEap = useInsightsEap();
return useDiscoverSeries<Fields>(
options,
useEap ? DiscoverDatasets.SPANS_EAP_RPC : DiscoverDatasets.METRICS,
referrer
referrer,
pageFilters
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import LoadingIndicator from 'sentry/components/loadingIndicator';
import Truncate from 'sentry/components/truncate';
import {t} from 'sentry/locale';
import {useLocation} from 'sentry/utils/useLocation';
import {formatTimeSeriesResultsToChartData} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreBreakdownChart';
import {formatTimeSeriesResultsToChartData} from 'sentry/views/insights/browser/webVitals/components/charts/formatTimeSeriesResultsToChartData';
import {ORDER} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreChart';
import {PerformanceBadge} from 'sentry/views/insights/browser/webVitals/components/performanceBadge';
import {useProjectWebVitalsScoresQuery} from 'sentry/views/insights/browser/webVitals/queries/storedScoreQueries/useProjectWebVitalsScoresQuery';
Expand Down
Loading