Skip to content

Commit 63cedf0

Browse files
authored
feat(ui): Update Trigger colors in Metric Alerts (#16334)
Also fix trigger threshold areas when window is resized.
1 parent a141a2f commit 63cedf0

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

src/sentry/static/sentry/app/views/settings/incidentRules/triggers/chart/thresholdsChart.tsx

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {ECharts, EChartOption} from 'echarts';
22
import React from 'react';
3+
import color from 'color';
34
import debounce from 'lodash/debounce';
45
import flatten from 'lodash/flatten';
56

@@ -31,6 +32,22 @@ const CHART_GRID = {
3132
bottom: space(1),
3233
};
3334

35+
// Colors to use for trigger thresholds
36+
const COLOR = {
37+
RESOLUTION_FILL: color(theme.greenLight)
38+
.alpha(0.1)
39+
.rgb()
40+
.string(),
41+
CRITICAL_FILL: color(theme.redLight)
42+
.alpha(0.25)
43+
.rgb()
44+
.string(),
45+
WARNING_FILL: color(theme.yellowLight)
46+
.alpha(0.1)
47+
.rgb()
48+
.string(),
49+
};
50+
3451
/**
3552
* This chart displays shaded regions that represent different Trigger thresholds in a
3653
* Metric Alert rule.
@@ -75,6 +92,9 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
7592
}
7693
};
7794

95+
/**
96+
* Updates the chart so that yAxis is within bounds of our max value
97+
*/
7898
updateChartAxis = debounce((threshold: number) => {
7999
const {maxValue} = this.props;
80100
if (typeof maxValue !== 'undefined' && threshold > maxValue) {
@@ -86,20 +106,31 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
86106
}
87107
}, 150);
88108

109+
/**
110+
* Syncs component state with the chart's width/heights
111+
*/
112+
updateDimensions = (chartRef: ECharts | null = this.chartRef) => {
113+
if (!chartRef) {
114+
return;
115+
}
116+
117+
const width = chartRef.getWidth();
118+
const height = chartRef.getHeight();
119+
if (width !== this.state.width || height !== this.state.height) {
120+
this.setState({
121+
width,
122+
height,
123+
});
124+
}
125+
};
126+
89127
handleRef = (ref: ReactEchartsRef): void => {
90128
// When chart initially renders, we want to update state with its width, as well as initialize starting
91129
// locations (on y axis) for the draggable lines
92130
if (ref && typeof ref.getEchartsInstance === 'function' && !this.chartRef) {
93131
this.chartRef = ref.getEchartsInstance();
94-
const width = this.chartRef.getWidth();
95-
const height = this.chartRef.getHeight();
132+
this.updateDimensions(this.chartRef);
96133
this.handleUpdateChartAxis();
97-
if (width !== this.state.width || height !== this.state.height) {
98-
this.setState({
99-
width,
100-
height,
101-
});
102-
}
103134
}
104135

105136
if (!ref) {
@@ -109,6 +140,10 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
109140

110141
/**
111142
* Draws the boundary lines and shaded areas for the chart.
143+
*
144+
* May need to refactor so that they are aware of other trigger thresholds.
145+
*
146+
* e.g. draw warning from threshold -> critical threshold instead of the entire height of chart
112147
*/
113148
getThresholdLine = (
114149
trigger: Trigger,
@@ -126,8 +161,9 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
126161
const yAxisPixelPosition = this.chartRef.convertToPixel({yAxisIndex: 0}, '0');
127162
const yAxisPosition = typeof yAxisPixelPosition === 'number' ? yAxisPixelPosition : 0;
128163

164+
const isCritical = trigger.label === 'critical';
129165
const LINE_STYLE = {
130-
stroke: theme.purpleLight,
166+
stroke: isResolution ? theme.greenDark : isCritical ? theme.redDark : theme.yellow,
131167
lineDash: [2],
132168
};
133169

@@ -145,7 +181,7 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
145181
},
146182

147183
// Shaded area for incident/resolutions to show user when they can expect to be alerted
148-
// for incidents (or when they will be considered as resolved)
184+
// (or when they will be considered as resolved)
149185
//
150186
// Resolution is considered "off" if it is -1
151187
...(position !== null && [
@@ -161,7 +197,11 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
161197
},
162198

163199
style: {
164-
fill: isResolution ? 'rgba(87, 190, 140, 0.1)' : 'rgba(220, 107, 107, 0.18)',
200+
fill: isResolution
201+
? COLOR.RESOLUTION_FILL
202+
: isCritical
203+
? COLOR.CRITICAL_FILL
204+
: COLOR.WARNING_FILL,
165205
},
166206

167207
// This needs to be below the draggable line
@@ -195,6 +235,15 @@ export default class ThresholdsChart extends React.PureComponent<Props, State> {
195235
),
196236
})}
197237
series={data}
238+
onFinished={() => {
239+
// We want to do this whenever the chart finishes re-rendering so that we can update the dimensions of
240+
// any graphics related to the triggers (e.g. the threshold areas + boundaries)
241+
if (!this.chartRef) {
242+
return;
243+
}
244+
245+
this.updateDimensions(this.chartRef);
246+
}}
198247
/>
199248
);
200249
}

0 commit comments

Comments
 (0)