Skip to content

Commit

Permalink
[ML] Fix toast notif show if no annotation data
Browse files Browse the repository at this point in the history
  • Loading branch information
qn895 committed Nov 3, 2020
1 parent d20aa19 commit 3fb8c08
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,46 @@ import { i18n } from '@kbn/i18n';
import { MlTooltipComponent } from '../../../components/chart_tooltip';
import { TimeseriesChart } from './timeseries_chart';
import { CombinedJob } from '../../../../../common/types/anomaly_detection_jobs';
import { ml } from '../../../services/ml_api_service';
import { ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE } from '../../../../../common/constants/search';
import { extractErrorMessage } from '../../../../../common/util/errors';
import { Annotation } from '../../../../../common/types/annotations';
import { useNotifications } from '../../../contexts/kibana';
import { useMlKibana, useNotifications } from '../../../contexts/kibana';
import { getBoundsRoundedToInterval } from '../../../util/time_buckets';
import { ANNOTATION_EVENT_USER } from '../../../../../common/constants/annotations';
import { getControlsForDetector } from '../../get_controls_for_detector';

interface TimeSeriesChartWithTooltipsProps {
bounds: any;
selectedDetectorIndex: number;
detectorIndex: number;
renderFocusChartOnly: boolean;
selectedJob: CombinedJob;
selectedEntities: Record<string, any>;
showAnnotations: boolean;
showForecast: boolean;
showModelBounds: boolean;
chartProps: any;
lastRefresh: number;
contextAggregationInterval: any;
}
export const TimeSeriesChartWithTooltips: FC<TimeSeriesChartWithTooltipsProps> = ({
bounds,
selectedDetectorIndex,
detectorIndex,
renderFocusChartOnly,
selectedJob,
selectedEntities,
showAnnotations,
showForecast,
showModelBounds,
chartProps,
lastRefresh,
contextAggregationInterval,
}) => {
const { toasts: toastNotifications } = useNotifications();
const {
services: {
mlServices: { mlApiServices },
},
} = useMlKibana();

const [annotationData, setAnnotationData] = useState<Annotation[]>([]);

Expand All @@ -55,24 +66,36 @@ export const TimeSeriesChartWithTooltips: FC<TimeSeriesChartWithTooltipsProps> =

useEffect(() => {
let unmounted = false;
const entities = getControlsForDetector(detectorIndex, selectedEntities, selectedJob.job_id);
const nonBlankEntities = Array.isArray(entities)
? entities.filter((entity) => entity.fieldValue !== null)
: undefined;
const searchBounds = getBoundsRoundedToInterval(bounds, contextAggregationInterval, false);

/**
* Loads the full list of annotations for job without any aggs or time boundaries
* used to indicate existence of annotations that are beyond the selected time
* in the time series brush area
*/
const loadAnnotations = async (jobId: string) => {
try {
const resp = await ml.annotations.getAnnotations({
const resp = await mlApiServices.annotations.getAnnotations({
jobIds: [jobId],
earliestMs: null,
latestMs: null,
earliestMs: searchBounds.min.valueOf(),
latestMs: searchBounds.max.valueOf(),
maxAnnotations: ANNOTATIONS_TABLE_DEFAULT_QUERY_SIZE,
fields: [
{
field: 'event',
missing: ANNOTATION_EVENT_USER,
},
],
detectorIndex,
entities: nonBlankEntities,
});
if (!unmounted) {
if (Array.isArray(resp.annotations[jobId])) {
setAnnotationData(resp.annotations[jobId]);
} else {
showAnnotationErrorToastNotification();
}
}
} catch (error) {
Expand All @@ -83,9 +106,16 @@ export const TimeSeriesChartWithTooltips: FC<TimeSeriesChartWithTooltipsProps> =
loadAnnotations(selectedJob.job_id);

return () => {
unmounted = false;
unmounted = true;
};
}, [selectedJob.job_id, selectedDetectorIndex, lastRefresh]);
}, [
selectedJob.job_id,
detectorIndex,
lastRefresh,
selectedEntities,
bounds,
contextAggregationInterval,
]);

return (
<div className="ml-timeseries-chart" data-test-subj="mlSingleMetricViewerChart">
Expand All @@ -95,7 +125,7 @@ export const TimeSeriesChartWithTooltips: FC<TimeSeriesChartWithTooltipsProps> =
{...chartProps}
annotationData={annotationData}
bounds={bounds}
detectorIndex={selectedDetectorIndex}
detectorIndex={detectorIndex}
renderFocusChartOnly={renderFocusChartOnly}
selectedJob={selectedJob}
showAnnotations={showAnnotations}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,59 +378,6 @@ export class TimeSeriesExplorer extends React.Component {
);
};

/**
* Loads available entity values.
* @param {Array} entities - Entity controls configuration
* @param {Object} searchTerm - Search term for partition, e.g. { partition_field: 'partition' }
*/
loadEntityValues = async (entities, searchTerm = {}) => {
this.setState({ entitiesLoading: true });

const { bounds, selectedJobId, selectedDetectorIndex } = this.props;
const selectedJob = mlJobService.getJob(selectedJobId);

// Populate the entity input datalists with the values from the top records by score
// for the selected detector across the full time range. No need to pass through finish().
const detectorIndex = selectedDetectorIndex;

const {
partition_field: partitionField,
over_field: overField,
by_field: byField,
} = await mlResultsService
.fetchPartitionFieldsValues(
selectedJob.job_id,
searchTerm,
[
{
fieldName: 'detector_index',
fieldValue: detectorIndex,
},
],
bounds.min.valueOf(),
bounds.max.valueOf()
)
.toPromise();

const entityValues = {};
entities.forEach((entity) => {
let fieldValues;

if (partitionField?.name === entity.fieldName) {
fieldValues = partitionField.values;
}
if (overField?.name === entity.fieldName) {
fieldValues = overField.values;
}
if (byField?.name === entity.fieldName) {
fieldValues = byField.values;
}
entityValues[entity.fieldName] = fieldValues;
});

this.setState({ entitiesLoading: false, entityValues });
};

setForecastId = (forecastId) => {
this.props.appStateHandler(APP_STATE_ACTION.SET_FORECAST_ID, forecastId);
};
Expand Down Expand Up @@ -1188,10 +1135,12 @@ export class TimeSeriesExplorer extends React.Component {
</EuiFlexGroup>
<TimeSeriesChartWithTooltips
chartProps={chartProps}
contextAggregationInterval={contextAggregationInterval}
bounds={bounds}
detectorIndex={selectedDetectorIndex}
renderFocusChartOnly={renderFocusChartOnly}
selectedJob={selectedJob}
selectedEntities={this.props.selectedEntities}
showAnnotations={showAnnotations}
showForecast={showForecast}
showModelBounds={showModelBounds}
Expand Down

0 comments on commit 3fb8c08

Please sign in to comment.