Skip to content

Commit 0d886b3

Browse files
authored
feat(aci): Register new metric detector chartcuterie chart in frontend (#101171)
1 parent d070b74 commit 0d886b3

File tree

7 files changed

+598
-5
lines changed

7 files changed

+598
-5
lines changed

static/app/chartcuterie/config.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {lightTheme} from 'sentry/utils/theme/theme';
1313

1414
import {makeDiscoverCharts} from './discover';
1515
import {makeMetricAlertCharts} from './metricAlert';
16+
import {makeMetricDetectorCharts} from './metricDetector';
1617
import {makePerformanceCharts} from './performance';
1718
import type {
1819
ChartcuterieConfig,
@@ -42,6 +43,7 @@ const register = (renderDescriptor: RenderDescriptor<ChartType>) =>
4243

4344
makeDiscoverCharts(lightTheme).forEach(register);
4445
makeMetricAlertCharts(lightTheme).forEach(register);
46+
makeMetricDetectorCharts(lightTheme).forEach(register);
4547
makePerformanceCharts(lightTheme).forEach(register);
4648

4749
export default config;
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import type {Theme} from '@emotion/react';
2+
import type {LineSeriesOption, YAXisComponentOption} from 'echarts';
3+
4+
import type {AreaChartSeries} from 'sentry/components/charts/areaChart';
5+
import XAxis from 'sentry/components/charts/components/xAxis';
6+
import AreaSeries from 'sentry/components/charts/series/areaSeries';
7+
import type {SessionApiResponse} from 'sentry/types/organization';
8+
import {
9+
getMetricDetectorChartOption,
10+
transformSessionResponseToSeries,
11+
type MetricDetectorChartData,
12+
} from 'sentry/views/detectors/components/details/metric/charts/metricDetectorChartOptions';
13+
14+
import {DEFAULT_FONT_FAMILY, makeSlackChartDefaults, slackChartSize} from './slack';
15+
import type {RenderDescriptor} from './types';
16+
import {ChartType} from './types';
17+
18+
function transformAreaSeries(series: AreaChartSeries[]): LineSeriesOption[] {
19+
return series.map(({seriesName, data, ...otherSeriesProps}) => {
20+
const areaSeries = AreaSeries({
21+
name: seriesName,
22+
data: data.map(({name, value}) => [name, value]),
23+
lineStyle: {
24+
opacity: 1,
25+
width: 0.4,
26+
},
27+
areaStyle: {
28+
opacity: 1.0,
29+
},
30+
animation: false,
31+
animationThreshold: 1,
32+
animationDuration: 0,
33+
...otherSeriesProps,
34+
});
35+
36+
// Fix incident label font family, cannot use Rubik
37+
if (areaSeries.markLine?.label) {
38+
areaSeries.markLine.label.fontFamily = DEFAULT_FONT_FAMILY;
39+
}
40+
41+
return areaSeries;
42+
});
43+
}
44+
45+
export function makeMetricDetectorCharts(
46+
theme: Theme
47+
): Array<RenderDescriptor<ChartType>> {
48+
const slackChartDefaults = makeSlackChartDefaults(theme);
49+
const metricDetectorCharts: Array<RenderDescriptor<ChartType>> = [];
50+
51+
const metricDetectorXaxis = XAxis({
52+
theme,
53+
splitNumber: 3,
54+
isGroupedByDate: true,
55+
axisLabel: {fontSize: 11, fontFamily: DEFAULT_FONT_FAMILY},
56+
});
57+
const metricDetectorYaxis: YAXisComponentOption = {
58+
axisLabel: {fontSize: 11, fontFamily: DEFAULT_FONT_FAMILY},
59+
splitLine: {
60+
lineStyle: {
61+
color: theme.chartLineColor,
62+
opacity: 0.3,
63+
},
64+
},
65+
};
66+
67+
metricDetectorCharts.push({
68+
key: ChartType.SLACK_METRIC_DETECTOR_EVENTS,
69+
getOption: (data: MetricDetectorChartData) => {
70+
const {chartOption} = getMetricDetectorChartOption(data, theme);
71+
72+
return {
73+
...chartOption,
74+
backgroundColor: theme.background,
75+
series: transformAreaSeries(chartOption.series),
76+
xAxis: metricDetectorXaxis,
77+
yAxis: {
78+
...chartOption.yAxis,
79+
...metricDetectorYaxis,
80+
axisLabel: {
81+
...chartOption.yAxis!.axisLabel,
82+
...metricDetectorYaxis.axisLabel,
83+
},
84+
},
85+
grid: slackChartDefaults.grid,
86+
};
87+
},
88+
...slackChartSize,
89+
});
90+
91+
interface MetricDetectorSessionData
92+
extends Omit<MetricDetectorChartData, 'timeseriesData'> {
93+
sessionResponse: SessionApiResponse;
94+
}
95+
96+
metricDetectorCharts.push({
97+
key: ChartType.SLACK_METRIC_DETECTOR_SESSIONS,
98+
getOption: (data: MetricDetectorSessionData) => {
99+
const {sessionResponse, detector, ...rest} = data;
100+
const {chartOption} = getMetricDetectorChartOption(
101+
{
102+
...rest,
103+
detector,
104+
timeseriesData: transformSessionResponseToSeries(sessionResponse, detector),
105+
},
106+
theme
107+
);
108+
109+
return {
110+
...chartOption,
111+
backgroundColor: theme.background,
112+
series: transformAreaSeries(chartOption.series),
113+
xAxis: metricDetectorXaxis,
114+
yAxis: {
115+
...chartOption.yAxis,
116+
...metricDetectorYaxis,
117+
axisLabel: {
118+
...chartOption.yAxis!.axisLabel,
119+
...metricDetectorYaxis.axisLabel,
120+
},
121+
},
122+
grid: slackChartDefaults.grid,
123+
};
124+
},
125+
...slackChartSize,
126+
});
127+
128+
return metricDetectorCharts;
129+
}

static/app/chartcuterie/types.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export enum ChartType {
1616
SLACK_DISCOVER_PREVIOUS_PERIOD = 'slack:discover.previousPeriod',
1717
SLACK_METRIC_ALERT_EVENTS = 'slack:metricAlert.events',
1818
SLACK_METRIC_ALERT_SESSIONS = 'slack:metricAlert.sessions',
19+
SLACK_METRIC_DETECTOR_EVENTS = 'slack:metricDetector.events',
20+
SLACK_METRIC_DETECTOR_SESSIONS = 'slack:metricDetector.sessions',
1921
SLACK_PERFORMANCE_ENDPOINT_REGRESSION = 'slack:performance.endpointRegression',
2022
SLACK_PERFORMANCE_FUNCTION_REGRESSION = 'slack:performance.functionRegression',
2123
}

static/app/types/workflowEngine/detectors.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export interface SnubaQueryDataSource extends BaseDataSource {
4848
snubaQuery: SnubaQuery;
4949
status: number;
5050
subscription: string;
51-
} | null;
51+
};
5252
type: 'snuba_query_subscription';
5353
}
5454

0 commit comments

Comments
 (0)