Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Add UX support for HC detector #314

Merged
49 changes: 19 additions & 30 deletions public/pages/AnomalyCharts/containers/AnomaliesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ interface AnomaliesChartProps {
dateRange: DateRange;
isLoading: boolean;
showAlerts?: boolean;
detectorId: string;
detectorName: string;
detector?: Detector;
detectorInterval?: number;
unit?: string;
detector: Detector;
monitor?: Monitor;
children: React.ReactNode | React.ReactNode[];
isHCDetector?: boolean;
Expand Down Expand Up @@ -153,10 +149,14 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => {
const setUpAlertsButton = () => (
<AlertsButton
monitor={props.monitor}
detectorId={props.detectorId}
detectorName={props.detectorName}
detectorInterval={get(props, 'detectorInterval', 1)}
unit={get(props, 'unit', 'Minutes')}
detectorId={get(props.detector, 'id', '')}
detectorName={get(props.detector, 'name', '')}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval',
1
)}
unit={get(props.detector, 'detectionInterval.period.unit', 'Minutes')}
/>
);
ohltyler marked this conversation as resolved.
Show resolved Hide resolved

Expand Down Expand Up @@ -204,17 +204,23 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => {
) : (
[
<AnomalyHeatmapChart
detectorId={props.detectorId}
detectorName={props.detectorName}
detectorId={get(props.detector, 'id', '')}
detectorName={get(props.detector, 'name', '')}
dateRange={props.dateRange}
//@ts-ignore
title={props.detectorCategoryField[0]}
anomalies={anomalies}
isLoading={props.isLoading}
showAlerts={props.showAlerts}
monitor={props.monitor}
detectorInterval={props.detectorInterval}
unit={props.unit}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(
props.detector,
'detectionInterval.period.unit'
)}
onHeatmapCellSelected={props.onHeatmapCellSelected}
/>,
props.showAlerts !== true
Expand All @@ -240,17 +246,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => {
props.showAlerts
)}
showAlerts={props.showAlerts}
detectorId={props.detectorId}
detectorName={props.detectorName}
detector={props.detector}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(
props.detector,
'detectionInterval.period.unit'
)}
isHCDetector={props.isHCDetector}
selectedHeatmapCell={props.selectedHeatmapCell}
/>,
Expand Down Expand Up @@ -294,14 +290,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => {
anomalyGradeSeriesName={getAnomalyGradeWording(props.showAlerts)}
confidenceSeriesName={getConfidenceWording(props.showAlerts)}
showAlerts={props.showAlerts}
detectorId={props.detectorId}
detectorName={props.detectorName}
detector={props.detector}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(props.detector, 'detectionInterval.period.unit')}
monitor={props.monitor}
isHCDetector={props.isHCDetector}
onDatePickerRangeChange={handleDatePickerRangeChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,7 @@ interface AnomalyDetailsChartProps {
showAlerts?: boolean;
anomalyGradeSeriesName: string;
confidenceSeriesName: string;
detectorId: string;
detectorName: string;
detector?: Detector;
detectorInterval?: number;
unit?: string;
detector: Detector;
monitor?: Monitor;
isHCDetector?: boolean;
selectedHeatmapCell?: HeatmapCell;
Expand Down Expand Up @@ -356,9 +352,7 @@ export const AnomalyDetailsChart = React.memo(

{showAlertsFlyout ? (
<AlertsFlyout
// @ts-ignore
detectorId={get(props.detector, 'id', '')}
// @ts-ignore
detectorName={get(props.detector, 'name', '')}
detectorInterval={get(
props.detector,
Expand Down
13 changes: 1 addition & 12 deletions public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ interface AnomalyOccurrenceChartProps {
showAlerts?: boolean;
anomalyGradeSeriesName: string;
confidenceSeriesName: string;
detectorId: string;
detectorName: string;
detector?: Detector;
detectorInterval?: number;
unit?: string;
detector: Detector;
monitor?: Monitor;
isHCDetector?: boolean;
selectedHeatmapCell?: HeatmapCell;
Expand Down Expand Up @@ -99,14 +95,7 @@ export const AnomalyOccurrenceChart = React.memo(
anomalyGradeSeriesName={props.anomalyGradeSeriesName}
confidenceSeriesName={props.confidenceSeriesName}
showAlerts={props.showAlerts}
detectorId={props.detector ? props.detector.id : ''}
detectorName={props.detector ? props.detector.name : ''}
detector={props.detector}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(props.detector, 'detectionInterval.period.unit')}
monitor={props.monitor}
isHCDetector={props.isHCDetector}
selectedHeatmapCell={props.selectedHeatmapCell}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import moment from 'moment';
import { initialState, mockedStore } from '../../../../redux/utils/testUtils';
import { Provider } from 'react-redux';
import { INITIAL_ANOMALY_SUMMARY } from '../../utils/constants';
import { getRandomDetector } from '../../../../redux/reducers/__tests__/utils';

const initialStartTime = moment('2019-10-10T09:00:00');
const initialEndTime = initialStartTime.clone().add(2, 'd');
Expand Down Expand Up @@ -73,9 +74,8 @@ const renderDataFilter = () => ({
anomalySummary={INITIAL_ANOMALY_SUMMARY}
dateRange={dateRange}
isLoading={false}
detectorId="testDetectorId"
detectorName="testDetectorName"
anomaliesResult={anomaliesResult}
detector={getRandomDetector(true)}
/>
</Provider>
),
Expand Down
41 changes: 22 additions & 19 deletions public/pages/AnomalyCharts/utils/anomalyChartUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ export const getAnomaliesHeatmapData = (
sortType: AnomalyHeatmapSortType = AnomalyHeatmapSortType.SEVERITY,
displayTopNum: number
): PlotData[] => {
const entityAnomaliesMap = getEntityAnomaliesMap(anomalies);
const entityAnomalyResultMap = getEntityAnomaliesMap(anomalies);
const entityAnomaliesMap = filterEntityAnomalyResultMap(
entityAnomalyResultMap
);
if (isEmpty(entityAnomaliesMap)) {
// put placeholder data so that heatmap won't look empty
for (let i = 0; i < displayTopNum; i++) {
Expand All @@ -236,24 +239,7 @@ export const getAnomaliesHeatmapData = (
entityAnomaliesMap.forEach((entityAnomalies, entity) => {
const maxAnomalyGradesForEntity = [] as number[];
const numAnomalyGradesForEntity = [] as number[];
if (
(isEmpty(entityAnomalies) ||
isEmpty(
entityAnomalies.filter(
(anomaly) => get(anomaly, 'anomalyGrade', 0) > 0
)
)) &&
!isEmpty(entity.trim())
) {
console.log(
`find entity ${entity} with empty anomalies`,
entityAnomalies
);
// skip non-blank entity with empty anomalies,
// keep blank entity as it is placeholder data
// for totally emtpy anomaly data state
return;
}

entityValues.push(entity);
timeWindows.forEach((timeWindow) => {
const anomaliesInWindow = entityAnomalies.filter(
Expand Down Expand Up @@ -328,6 +314,23 @@ const getEntityAnomaliesMap = (anomalies: any[]): Map<string, any[]> => {
return entityAnomaliesMap;
};

const filterEntityAnomalyResultMap = (
entityAnomalyResultMap: Map<string, any[]>
) => {
const entityAnomaliesMap = new Map<string, any[]>();
entityAnomalyResultMap.forEach((entityAnomalies, entity) => {
if (
!isEmpty(entityAnomalies) &&
!isEmpty(
entityAnomalies.filter((anomaly) => get(anomaly, 'anomalyGrade', 0) > 0)
)
) {
entityAnomaliesMap.set(entity, entityAnomalies);
}
});
return entityAnomaliesMap;
};

export const filterHeatmapPlotDataByY = (
heatmapData: PlotData,
selectedYs: Datum[],
Expand Down
17 changes: 0 additions & 17 deletions public/pages/DetectorResults/containers/AnomalyHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => {
anomalySummary={bucketizedAnomalySummary}
isLoading={isLoading || isLoadingAnomalyResults}
showAlerts={true}
detectorId={props.detector.id}
detectorName={props.detector.name}
detector={props.detector}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(props.detector, 'detectionInterval.period.unit')}
monitor={props.monitor}
isHCDetector={isHCDetector}
detectorCategoryField={detectorCategoryField}
Expand Down Expand Up @@ -392,17 +385,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => {
anomalyGradeSeriesName="Anomaly grade"
confidenceSeriesName="Confidence"
showAlerts={true}
detectorId={props.detector.id}
detectorName={props.detector.name}
detector={props.detector}
detectorInterval={get(
props.detector,
'detectionInterval.period.interval'
)}
unit={get(
props.detector,
'detectionInterval.period.unit'
)}
monitor={props.monitor}
isHCDetector={isHCDetector}
selectedHeatmapCell={selectedHeatmapCell}
Expand Down
21 changes: 11 additions & 10 deletions public/pages/DetectorResults/containers/AnomalyResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import { ListControls } from '../components/ListControls/ListControls';
import { DetectorResultsQueryParams } from 'server/models/types';
import { AnomalyData } from '../../../models/interfaces';
import { getTitleWithCount } from '../../../utils/utils';
import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart';

interface AnomalyResultsTableProps {
anomalies: AnomalyData[];
Expand Down Expand Up @@ -73,17 +72,19 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) {
};

useEffect(() => {
const anomalies = props.anomalies
? props.anomalies
.filter((anomaly) => anomaly.anomalyGrade > 0)
.map((anomaly) => {
return {
...anomaly,
[ENTITY_VALUE_FIELD]: get(anomaly, 'entity[0].value'),
};
})
let anomalies = props.anomalies
? props.anomalies.filter((anomaly) => anomaly.anomalyGrade > 0)
: [];

if (props.isHCDetector) {
anomalies = anomalies.map((anomaly) => {
return {
...anomaly,
[ENTITY_VALUE_FIELD]: get(anomaly, 'entity[0].value'),
};
});
}

anomalies.sort(
sortFieldCompare(
state.queryParams.sortField,
Expand Down
5 changes: 3 additions & 2 deletions public/pages/EditFeatures/containers/SampleAnomalies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,9 @@ export function SampleAnomalies(props: SampleAnomaliesProps) {
onZoomRangeChange={handleZoomChange}
isLoading={isLoading}
dateRange={dateRange}
detectorId={props.detector.id}
detectorName={props.detector.name}
// detectorId={props.detector.id}
// detectorName={props.detector.name}
detector={props.detector}
yizheliu-amazon marked this conversation as resolved.
Show resolved Hide resolved
isHCDetector={isHCDetector}
detectorCategoryField={newDetector.categoryField}
onHeatmapCellSelected={handleHeatmapCellSelected}
Expand Down