Browse Source

feat(cmp_alerts): Change alert data in dashed line in alert details (#29623)

* use basechart in test too

* more mock

* revert back to area chart

* fix series

* complete bypass area chart

* feat(cmp_alerts): Change alert data in dashed line in alert details

* use additionalSeries for line chart too

* fix marklines to render
Taylan Gocmen 3 years ago
parent
commit
2875a3b5de

+ 133 - 0
static/app/views/alerts/changeAlerts/comparisonMarklines.tsx

@@ -0,0 +1,133 @@
+import MarkLine from 'app/components/charts/components/markLine';
+import {LineChartSeries} from 'app/components/charts/lineChart';
+import {t} from 'app/locale';
+import {Series} from 'app/types/echarts';
+import {MINUTE} from 'app/utils/formatters';
+import theme from 'app/utils/theme';
+import {AlertRuleThresholdType, Trigger} from 'app/views/alerts/incidentRules/types';
+
+const checkChangeStatus = (
+  value: number,
+  thresholdType: AlertRuleThresholdType,
+  triggers: Trigger[]
+): string => {
+  const criticalTrigger = triggers?.find(trig => trig.label === 'critical');
+  const warningTrigger = triggers?.find(trig => trig.label === 'warning');
+  const criticalTriggerAlertThreshold =
+    typeof criticalTrigger?.alertThreshold === 'number'
+      ? criticalTrigger.alertThreshold
+      : undefined;
+  const warningTriggerAlertThreshold =
+    typeof warningTrigger?.alertThreshold === 'number'
+      ? warningTrigger.alertThreshold
+      : undefined;
+
+  // Need to catch the critical threshold cases before warning threshold cases
+  if (
+    thresholdType === AlertRuleThresholdType.ABOVE &&
+    criticalTriggerAlertThreshold &&
+    value >= criticalTriggerAlertThreshold
+  ) {
+    return 'critical';
+  }
+  if (
+    thresholdType === AlertRuleThresholdType.ABOVE &&
+    warningTriggerAlertThreshold &&
+    value >= warningTriggerAlertThreshold
+  ) {
+    return 'warning';
+  }
+  // When threshold is below(lower than in comparison alerts) the % diff value is negative
+  // It crosses the threshold if its abs value is greater than threshold
+  // -80% change crosses below 60% threshold -1 * (-80) > 60
+  if (
+    thresholdType === AlertRuleThresholdType.BELOW &&
+    criticalTriggerAlertThreshold &&
+    -1 * value >= criticalTriggerAlertThreshold
+  ) {
+    return 'critical';
+  }
+  if (
+    thresholdType === AlertRuleThresholdType.BELOW &&
+    warningTriggerAlertThreshold &&
+    -1 * value >= warningTriggerAlertThreshold
+  ) {
+    return 'warning';
+  }
+
+  return '';
+};
+
+export const getComparisonMarkLines = (
+  timeseriesData: Series[] = [],
+  comparisonTimeseriesData: Series[] = [],
+  timeWindow: number,
+  triggers: Trigger[],
+  thresholdType: AlertRuleThresholdType
+): LineChartSeries[] => {
+  const changeStatuses: {name: number | string; status: string}[] = [];
+
+  if (
+    timeseriesData?.[0]?.data !== undefined &&
+    timeseriesData[0].data.length > 1 &&
+    comparisonTimeseriesData?.[0]?.data !== undefined &&
+    comparisonTimeseriesData[0].data.length > 1
+  ) {
+    const changeData = comparisonTimeseriesData[0].data;
+    const baseData = timeseriesData[0].data;
+
+    if (triggers.some(({alertThreshold}) => typeof alertThreshold === 'number')) {
+      const lastPointLimit =
+        (baseData[changeData.length - 1].name as number) - timeWindow * MINUTE;
+      changeData.forEach(({name, value: comparisonValue}, idx) => {
+        const baseValue = baseData[idx].value;
+        const comparisonPercentage =
+          comparisonValue === 0
+            ? baseValue === 0
+              ? 0
+              : Infinity
+            : ((baseValue - comparisonValue) / comparisonValue) * 100;
+        const status = checkChangeStatus(comparisonPercentage, thresholdType, triggers);
+        if (
+          idx === 0 ||
+          idx === changeData.length - 1 ||
+          status !== changeStatuses[changeStatuses.length - 1].status
+        ) {
+          changeStatuses.push({name, status});
+        }
+      });
+
+      return changeStatuses.slice(0, -1).map(({name, status}, idx) => ({
+        seriesName: t('status'),
+        type: 'line',
+        markLine: MarkLine({
+          silent: true,
+          lineStyle: {
+            color:
+              status === 'critical'
+                ? theme.red300
+                : status === 'warning'
+                ? theme.yellow300
+                : theme.green300,
+            type: 'solid',
+            width: 4,
+          },
+          data: [
+            [
+              {coord: [name, 0]},
+              {
+                coord: [
+                  Math.min(changeStatuses[idx + 1].name as number, lastPointLimit),
+                  0,
+                ],
+              },
+            ] as any,
+          ],
+        }),
+        data: [],
+      }));
+    }
+  }
+
+  return [];
+};

+ 0 - 0
static/app/views/alerts/issueRuleEditor/constants/changeAlerts.tsx → static/app/views/alerts/changeAlerts/constants.tsx


+ 11 - 131
static/app/views/alerts/incidentRules/triggers/chart/index.tsx

@@ -8,7 +8,6 @@ import minBy from 'lodash/minBy';
 import {fetchTotalCount} from 'app/actionCreators/events';
 import {fetchTotalCount} from 'app/actionCreators/events';
 import {Client} from 'app/api';
 import {Client} from 'app/api';
 import Feature from 'app/components/acl/feature';
 import Feature from 'app/components/acl/feature';
-import MarkLine from 'app/components/charts/components/markLine';
 import EventsRequest from 'app/components/charts/eventsRequest';
 import EventsRequest from 'app/components/charts/eventsRequest';
 import {LineChartSeries} from 'app/components/charts/lineChart';
 import {LineChartSeries} from 'app/components/charts/lineChart';
 import OptionSelector from 'app/components/charts/optionSelector';
 import OptionSelector from 'app/components/charts/optionSelector';
@@ -25,13 +24,12 @@ import {t} from 'app/locale';
 import space from 'app/styles/space';
 import space from 'app/styles/space';
 import {Organization, Project} from 'app/types';
 import {Organization, Project} from 'app/types';
 import {Series, SeriesDataUnit} from 'app/types/echarts';
 import {Series, SeriesDataUnit} from 'app/types/echarts';
-import {MINUTE} from 'app/utils/formatters';
 import {
 import {
   getCrashFreeRateSeries,
   getCrashFreeRateSeries,
   MINUTES_THRESHOLD_TO_DISPLAY_SECONDS,
   MINUTES_THRESHOLD_TO_DISPLAY_SECONDS,
 } from 'app/utils/sessions';
 } from 'app/utils/sessions';
-import theme from 'app/utils/theme';
 import withApi from 'app/utils/withApi';
 import withApi from 'app/utils/withApi';
+import {getComparisonMarkLines} from 'app/views/alerts/changeAlerts/comparisonMarklines';
 import {COMPARISON_DELTA_OPTIONS} from 'app/views/alerts/incidentRules/constants';
 import {COMPARISON_DELTA_OPTIONS} from 'app/views/alerts/incidentRules/constants';
 import {isSessionAggregate, SESSION_AGGREGATE_TO_FIELD} from 'app/views/alerts/utils';
 import {isSessionAggregate, SESSION_AGGREGATE_TO_FIELD} from 'app/views/alerts/utils';
 import {AlertWizardAlertNames} from 'app/views/alerts/wizard/options';
 import {AlertWizardAlertNames} from 'app/views/alerts/wizard/options';
@@ -39,7 +37,6 @@ import {getAlertTypeFromAggregateDataset} from 'app/views/alerts/wizard/utils';
 
 
 import {
 import {
   AlertRuleComparisonType,
   AlertRuleComparisonType,
-  AlertRuleThresholdType,
   Dataset,
   Dataset,
   IncidentRule,
   IncidentRule,
   SessionsAggregate,
   SessionsAggregate,
@@ -227,80 +224,6 @@ class TriggersChart extends React.PureComponent<Props, State> {
     );
     );
   }
   }
 
 
-  getComparisonMarkLines(
-    timeseriesData: Series[] = [],
-    comparisonTimeseriesData: Series[] = []
-  ): LineChartSeries[] {
-    const {timeWindow} = this.props;
-    const changeStatuses: {name: number | string; status: string}[] = [];
-
-    if (
-      timeseriesData?.[0]?.data !== undefined &&
-      timeseriesData[0].data.length > 1 &&
-      comparisonTimeseriesData?.[0]?.data !== undefined &&
-      comparisonTimeseriesData[0].data.length > 1
-    ) {
-      const changeData = comparisonTimeseriesData[0].data;
-      const baseData = timeseriesData[0].data;
-
-      if (
-        this.props.triggers.some(({alertThreshold}) => typeof alertThreshold === 'number')
-      ) {
-        const lastPointLimit =
-          (baseData[changeData.length - 1].name as number) - timeWindow * MINUTE;
-        changeData.forEach(({name, value: comparisonValue}, idx) => {
-          const baseValue = baseData[idx].value;
-          const comparisonPercentage =
-            comparisonValue === 0
-              ? baseValue === 0
-                ? 0
-                : Infinity
-              : ((baseValue - comparisonValue) / comparisonValue) * 100;
-          const status = this.checkChangeStatus(comparisonPercentage);
-          if (
-            idx === 0 ||
-            idx === changeData.length - 1 ||
-            status !== changeStatuses[changeStatuses.length - 1].status
-          ) {
-            changeStatuses.push({name, status});
-          }
-        });
-
-        return changeStatuses.slice(0, -1).map(({name, status}, idx) => ({
-          seriesName: t('status'),
-          type: 'line',
-          markLine: MarkLine({
-            silent: true,
-            lineStyle: {
-              color:
-                status === 'critical'
-                  ? theme.red300
-                  : status === 'warning'
-                  ? theme.yellow300
-                  : theme.green300,
-              type: 'solid',
-              width: 4,
-            },
-            data: [
-              [
-                {coord: [name, 0]},
-                {
-                  coord: [
-                    Math.min(changeStatuses[idx + 1].name as number, lastPointLimit),
-                    0,
-                  ],
-                },
-              ] as any,
-            ],
-          }),
-          data: [],
-        }));
-      }
-    }
-
-    return [];
-  }
-
   async fetchTotalCount() {
   async fetchTotalCount() {
     const {api, organization, environment, projects, query} = this.props;
     const {api, organization, environment, projects, query} = this.props;
     const statsPeriod = this.getStatsPeriod();
     const statsPeriod = this.getStatsPeriod();
@@ -318,55 +241,6 @@ class TriggersChart extends React.PureComponent<Props, State> {
     }
     }
   }
   }
 
 
-  checkChangeStatus(value: number): string {
-    const {thresholdType, triggers} = this.props;
-    const criticalTrigger = triggers?.find(trig => trig.label === 'critical');
-    const warningTrigger = triggers?.find(trig => trig.label === 'warning');
-    const criticalTriggerAlertThreshold =
-      typeof criticalTrigger?.alertThreshold === 'number'
-        ? criticalTrigger.alertThreshold
-        : undefined;
-    const warningTriggerAlertThreshold =
-      typeof warningTrigger?.alertThreshold === 'number'
-        ? warningTrigger.alertThreshold
-        : undefined;
-
-    // Need to catch the critical threshold cases before warning threshold cases
-    if (
-      thresholdType === AlertRuleThresholdType.ABOVE &&
-      criticalTriggerAlertThreshold &&
-      value >= criticalTriggerAlertThreshold
-    ) {
-      return 'critical';
-    }
-    if (
-      thresholdType === AlertRuleThresholdType.ABOVE &&
-      warningTriggerAlertThreshold &&
-      value >= warningTriggerAlertThreshold
-    ) {
-      return 'warning';
-    }
-    // When threshold is below(lower than in comparison alerts) the % diff value is negative
-    // It crosses the threshold if its abs value is greater than threshold
-    // -80% change crosses below 60% threshold -1 * (-80) > 60
-    if (
-      thresholdType === AlertRuleThresholdType.BELOW &&
-      criticalTriggerAlertThreshold &&
-      -1 * value >= criticalTriggerAlertThreshold
-    ) {
-      return 'critical';
-    }
-    if (
-      thresholdType === AlertRuleThresholdType.BELOW &&
-      warningTriggerAlertThreshold &&
-      -1 * value >= warningTriggerAlertThreshold
-    ) {
-      return 'warning';
-    }
-
-    return '';
-  }
-
   renderChart(
   renderChart(
     timeseriesData: Series[] = [],
     timeseriesData: Series[] = [],
     isLoading: boolean,
     isLoading: boolean,
@@ -448,11 +322,14 @@ class TriggersChart extends React.PureComponent<Props, State> {
       aggregate,
       aggregate,
       environment,
       environment,
       comparisonDelta,
       comparisonDelta,
+      triggers,
+      thresholdType,
     } = this.props;
     } = this.props;
 
 
     const period = this.getStatsPeriod();
     const period = this.getStatsPeriod();
-    const renderComparisonStats =
-      organization.features.includes('change-alerts') && comparisonDelta;
+    const renderComparisonStats = Boolean(
+      organization.features.includes('change-alerts') && comparisonDelta
+    );
 
 
     return isSessionAggregate(aggregate) ? (
     return isSessionAggregate(aggregate) ? (
       <SessionsRequest
       <SessionsRequest
@@ -513,9 +390,12 @@ class TriggersChart extends React.PureComponent<Props, State> {
               {({loading, reloading, timeseriesData, comparisonTimeseriesData}) => {
               {({loading, reloading, timeseriesData, comparisonTimeseriesData}) => {
                 let comparisonMarkLines: LineChartSeries[] = [];
                 let comparisonMarkLines: LineChartSeries[] = [];
                 if (renderComparisonStats && comparisonTimeseriesData) {
                 if (renderComparisonStats && comparisonTimeseriesData) {
-                  comparisonMarkLines = this.getComparisonMarkLines(
+                  comparisonMarkLines = getComparisonMarkLines(
                     timeseriesData,
                     timeseriesData,
-                    comparisonTimeseriesData
+                    comparisonTimeseriesData,
+                    timeWindow,
+                    triggers,
+                    thresholdType
                   );
                   );
                 }
                 }
 
 

+ 1 - 1
static/app/views/alerts/issueRuleEditor/index.tsx

@@ -44,7 +44,7 @@ import withTeams from 'app/utils/withTeams';
 import {
 import {
   CHANGE_ALERT_CONDITION_IDS,
   CHANGE_ALERT_CONDITION_IDS,
   CHANGE_ALERT_PLACEHOLDERS_LABELS,
   CHANGE_ALERT_PLACEHOLDERS_LABELS,
-} from 'app/views/alerts/issueRuleEditor/constants/changeAlerts';
+} from 'app/views/alerts/changeAlerts/constants';
 import AsyncView from 'app/views/asyncView';
 import AsyncView from 'app/views/asyncView';
 import Input from 'app/views/settings/components/forms/controls/input';
 import Input from 'app/views/settings/components/forms/controls/input';
 import Field from 'app/views/settings/components/forms/field';
 import Field from 'app/views/settings/components/forms/field';

+ 3 - 3
static/app/views/alerts/issueRuleEditor/ruleNodeList.tsx

@@ -12,14 +12,14 @@ import {
   IssueAlertRuleCondition,
   IssueAlertRuleCondition,
   IssueAlertRuleConditionTemplate,
   IssueAlertRuleConditionTemplate,
 } from 'app/types/alerts';
 } from 'app/types/alerts';
-import {EVENT_FREQUENCY_PERCENT_CONDITION} from 'app/views/projectInstall/issueAlertOptions';
-
 import {
 import {
   CHANGE_ALERT_CONDITION_IDS,
   CHANGE_ALERT_CONDITION_IDS,
   COMPARISON_INTERVAL_CHOICES,
   COMPARISON_INTERVAL_CHOICES,
   COMPARISON_TYPE_CHOICE_VALUES,
   COMPARISON_TYPE_CHOICE_VALUES,
   COMPARISON_TYPE_CHOICES,
   COMPARISON_TYPE_CHOICES,
-} from './constants/changeAlerts';
+} from 'app/views/alerts/changeAlerts/constants';
+import {EVENT_FREQUENCY_PERCENT_CONDITION} from 'app/views/projectInstall/issueAlertOptions';
+
 import RuleNode from './ruleNode';
 import RuleNode from './ruleNode';
 
 
 type Props = {
 type Props = {

+ 55 - 6
static/app/views/alerts/rules/details/metricChart.tsx

@@ -2,6 +2,7 @@ import * as React from 'react';
 import {withRouter, WithRouterProps} from 'react-router';
 import {withRouter, WithRouterProps} from 'react-router';
 import styled from '@emotion/styled';
 import styled from '@emotion/styled';
 import color from 'color';
 import color from 'color';
+import capitalize from 'lodash/capitalize';
 import moment from 'moment';
 import moment from 'moment';
 import momentTimezone from 'moment-timezone';
 import momentTimezone from 'moment-timezone';
 
 
@@ -14,6 +15,7 @@ import MarkArea from 'app/components/charts/components/markArea';
 import MarkLine from 'app/components/charts/components/markLine';
 import MarkLine from 'app/components/charts/components/markLine';
 import EventsRequest from 'app/components/charts/eventsRequest';
 import EventsRequest from 'app/components/charts/eventsRequest';
 import LineChart, {LineChartSeries} from 'app/components/charts/lineChart';
 import LineChart, {LineChartSeries} from 'app/components/charts/lineChart';
+import LineSeries from 'app/components/charts/series/lineSeries';
 import SessionsRequest from 'app/components/charts/sessionsRequest';
 import SessionsRequest from 'app/components/charts/sessionsRequest';
 import {SectionHeading} from 'app/components/charts/styles';
 import {SectionHeading} from 'app/components/charts/styles';
 import {
 import {
@@ -36,6 +38,7 @@ import {
 } from 'app/utils/sessions';
 } from 'app/utils/sessions';
 import theme from 'app/utils/theme';
 import theme from 'app/utils/theme';
 import {alertDetailsLink} from 'app/views/alerts/details';
 import {alertDetailsLink} from 'app/views/alerts/details';
+import {COMPARISON_DELTA_OPTIONS} from 'app/views/alerts/incidentRules/constants';
 import {makeDefaultCta} from 'app/views/alerts/incidentRules/incidentRulePresets';
 import {makeDefaultCta} from 'app/views/alerts/incidentRules/incidentRulePresets';
 import {Dataset, IncidentRule} from 'app/views/alerts/incidentRules/types';
 import {Dataset, IncidentRule} from 'app/views/alerts/incidentRules/types';
 import {AlertWizardAlertNames} from 'app/views/alerts/wizard/options';
 import {AlertWizardAlertNames} from 'app/views/alerts/wizard/options';
@@ -326,7 +329,8 @@ class MetricChart extends React.PureComponent<Props, State> {
   renderChart(
   renderChart(
     loading: boolean,
     loading: boolean,
     timeseriesData?: Series[],
     timeseriesData?: Series[],
-    minutesThresholdToDisplaySeconds?: number
+    minutesThresholdToDisplaySeconds?: number,
+    comparisonTimeseriesData?: Series[]
   ) {
   ) {
     const {
     const {
       router,
       router,
@@ -382,6 +386,7 @@ class MetricChart extends React.PureComponent<Props, State> {
     series.push(
     series.push(
       createStatusAreaSeries(theme.green300, firstPoint, lastPoint, minChartValue)
       createStatusAreaSeries(theme.green300, firstPoint, lastPoint, minChartValue)
     );
     );
+
     if (incidents) {
     if (incidents) {
       // select incidents that fall within the graph range
       // select incidents that fall within the graph range
       const periodStart = moment.utc(firstPoint);
       const periodStart = moment.utc(firstPoint);
@@ -520,6 +525,11 @@ class MetricChart extends React.PureComponent<Props, State> {
       maxThresholdValue = Math.max(maxThresholdValue, alertThreshold);
       maxThresholdValue = Math.max(maxThresholdValue, alertThreshold);
     }
     }
 
 
+    const comparisonSeriesName = capitalize(
+      COMPARISON_DELTA_OPTIONS.find(({value}) => value === rule.comparisonDelta)?.label ||
+        ''
+    );
+
     return (
     return (
       <ChartPanel>
       <ChartPanel>
         <StyledPanelBody withPadding>
         <StyledPanelBody withPadding>
@@ -566,6 +576,20 @@ class MetricChart extends React.PureComponent<Props, State> {
                       min: minChartValue || undefined,
                       min: minChartValue || undefined,
                     }}
                     }}
                     series={[...series, ...areaSeries]}
                     series={[...series, ...areaSeries]}
+                    additionalSeries={[
+                      ...(comparisonTimeseriesData || []).map(
+                        ({data: _data, ...otherSeriesProps}) =>
+                          LineSeries({
+                            name: comparisonSeriesName,
+                            data: _data.map(({name, value}) => [name, value]),
+                            lineStyle: {color: theme.gray200, type: 'dashed', width: 1},
+                            animation: false,
+                            animationThreshold: 1,
+                            animationDuration: 0,
+                            ...otherSeriesProps,
+                          })
+                      ),
+                    ]}
                     graphic={Graphic({
                     graphic={Graphic({
                       elements: this.getRuleChangeThresholdElements(timeseriesData),
                       elements: this.getRuleChangeThresholdElements(timeseriesData),
                     })}
                     })}
@@ -582,6 +606,19 @@ class MetricChart extends React.PureComponent<Props, State> {
                           seriesName ?? '',
                           seriesName ?? '',
                           rule.aggregate
                           rule.aggregate
                         );
                         );
+
+                        const comparisonSeries = pointSeries.find(
+                          ({seriesName: _seriesName}) =>
+                            _seriesName === comparisonSeriesName
+                        );
+                        const comparisonPointY = comparisonSeries
+                          ? alertTooltipValueFormatter(
+                              comparisonSeries.data[1],
+                              seriesName ?? '',
+                              rule.aggregate
+                            )
+                          : null;
+
                         const isModified =
                         const isModified =
                           dateModified && pointX <= new Date(dateModified).getTime();
                           dateModified && pointX <= new Date(dateModified).getTime();
 
 
@@ -600,17 +637,26 @@ class MetricChart extends React.PureComponent<Props, State> {
                         const title = isModified
                         const title = isModified
                           ? `<strong>${t('Alert Rule Modified')}</strong>`
                           ? `<strong>${t('Alert Rule Modified')}</strong>`
                           : `${marker} <strong>${seriesName}</strong>`;
                           : `${marker} <strong>${seriesName}</strong>`;
+
                         const value = isModified
                         const value = isModified
                           ? `${seriesName} ${pointYFormatted}`
                           ? `${seriesName} ${pointYFormatted}`
                           : pointYFormatted;
                           : pointYFormatted;
 
 
+                        const comparisonTitle = isModified
+                          ? `<span>${comparisonSeriesName}</span>`
+                          : `<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:transparent;"></span><strong>${comparisonSeriesName}</strong>`;
+
                         return [
                         return [
-                          `<div class="tooltip-series"><div>`,
-                          `<span class="tooltip-label">${title}</span>${value}`,
-                          `</div></div>`,
+                          `<div class="tooltip-series">`,
+                          `<div><span class="tooltip-label">${title}</span>${value}</div>`,
+                          comparisonSeries &&
+                            `<div><span class="tooltip-label">${comparisonTitle}</span>${comparisonPointY}</div>`,
+                          `</div>`,
                           `<div class="tooltip-date">${startTime} &mdash; ${endTime}</div>`,
                           `<div class="tooltip-date">${startTime} &mdash; ${endTime}</div>`,
                           `<div class="tooltip-arrow"></div>`,
                           `<div class="tooltip-arrow"></div>`,
-                        ].join('');
+                        ]
+                          .filter(e => e)
+                          .join('');
                       },
                       },
                     }}
                     }}
                     onFinished={() => {
                     onFinished={() => {
@@ -703,6 +749,7 @@ class MetricChart extends React.PureComponent<Props, State> {
           .filter(p => p && p.slug)
           .filter(p => p && p.slug)
           .map(project => Number(project.id))}
           .map(project => Number(project.id))}
         interval={interval}
         interval={interval}
+        comparisonDelta={rule.comparisonDelta ? rule.comparisonDelta * 60 : undefined}
         start={viableStartDate}
         start={viableStartDate}
         end={viableEndDate}
         end={viableEndDate}
         yAxis={aggregate}
         yAxis={aggregate}
@@ -711,7 +758,9 @@ class MetricChart extends React.PureComponent<Props, State> {
         partial={false}
         partial={false}
         referrer="api.alerts.alert-rule-chart"
         referrer="api.alerts.alert-rule-chart"
       >
       >
-        {({loading, timeseriesData}) => this.renderChart(loading, timeseriesData)}
+        {({loading, timeseriesData, comparisonTimeseriesData}) =>
+          this.renderChart(loading, timeseriesData, undefined, comparisonTimeseriesData)
+        }
       </EventsRequest>
       </EventsRequest>
     );
     );
   }
   }