Skip to content

Commit

Permalink
wip: break out pieces into components to reduce file size. use getBou…
Browse files Browse the repository at this point in the history
…ndsRoundedToInterval from package
  • Loading branch information
alvarezmelissa87 committed Dec 3, 2024
1 parent 01de887 commit 5d994f4
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export { SingleMetricViewerTitle } from './timeseriesexplorer_title';
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { FC } from 'react';
import React, { Fragment } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiTextColor } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import type { MlEntity } from '../../../../embeddables/types';
import { TimeSeriesExplorerHelpPopover } from '../../timeseriesexplorer_help_popover';

// Used to indicate the chart is being plotted across
// all partition field values, where the cardinality of the field cannot be
// obtained as it is not aggregatable e.g. 'all distinct kpi_indicator values'
const allValuesLabel = i18n.translate('xpack.ml.timeSeriesExplorer.allPartitionValuesLabel', {
defaultMessage: 'all',
});

export const SingleMetricViewerTitle: FC<{
entityData: { entities: MlEntity[]; count: number };
functionLabel: string;
}> = ({ entityData, functionLabel }) => (
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem grow={false}>
<EuiTitle size={'xs'}>
<h2>
<span>
{i18n.translate('xpack.ml.timeSeriesExplorer.singleTimeSeriesAnalysisTitle', {
defaultMessage: 'Single time series analysis of {functionLabel}',
values: { functionLabel },
})}
</span>
&nbsp;
{entityData.count === 1 && (
<EuiTextColor color={'success'} size={'s'} component={'span'}>
{entityData.entities.length > 0 && '('}
{entityData.entities
.map((entity) => {
return `${entity.fieldName}: ${entity.fieldValue}`;
})
.join(', ')}
{entityData.entities.length > 0 && ')'}
</EuiTextColor>
)}
{entityData.count !== 1 && (
<EuiTextColor color={'success'} size={'s'} component={'span'}>
{entityData.entities.map((countData, i) => {
return (
<Fragment key={countData.fieldName}>
{i18n.translate(
'xpack.ml.timeSeriesExplorer.countDataInChartDetailsDescription',
{
defaultMessage:
'{openBrace}{cardinalityValue} distinct {fieldName} {cardinality, plural, one {} other { values}}{closeBrace}',
values: {
openBrace: i === 0 ? '(' : '',
closeBrace: i === entityData.entities.length - 1 ? ')' : '',
cardinalityValue:
countData.cardinality === 0 ? allValuesLabel : countData.cardinality,
cardinality: countData.cardinality,
fieldName: countData.fieldName,
},
}
)}
{i !== entityData.entities.length - 1 ? ', ' : ''}
</Fragment>
);
})}
</EuiTextColor>
)}
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<TimeSeriesExplorerHelpPopover />
</EuiFlexItem>
</EuiFlexGroup>
);
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
EuiTitle,
EuiAccordion,
EuiBadge,
EuiTextColor,
} from '@elastic/eui';

import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -67,7 +66,7 @@ import { toastNotificationServiceProvider } from '../services/toast_notification
import { ForecastingModal } from './components/forecasting_modal/forecasting_modal';
import { TimeseriesexplorerNoChartData } from './components/timeseriesexplorer_no_chart_data';
import { TimeSeriesExplorerPage } from './timeseriesexplorer_page';
import { TimeSeriesExplorerHelpPopover } from './timeseriesexplorer_help_popover';
import { SingleMetricViewerTitle } from './components/timeseriesexplorer_title';

import {
APP_STATE_ACTION,
Expand All @@ -89,13 +88,6 @@ import { getDataViewsAndIndicesWithGeoFields } from '../explorer/explorer_utils'
import { indexServiceFactory } from '../util/index_service';
import { TimeSeriesExplorerControls } from './components/timeseriesexplorer_controls';

// Used to indicate the chart is being plotted across
// all partition field values, where the cardinality of the field cannot be
// obtained as it is not aggregatable e.g. 'all distinct kpi_indicator values'
const allValuesLabel = i18n.translate('xpack.ml.timeSeriesExplorer.allPartitionValuesLabel', {
defaultMessage: 'all',
});

const containerPadding = 34;

export class TimeSeriesExplorer extends React.Component {
Expand Down Expand Up @@ -1116,70 +1108,10 @@ export class TimeSeriesExplorer extends React.Component {
(fullRefresh === false || loading === false) &&
hasResults === true && (
<div>
<EuiFlexGroup gutterSize="xs" alignItems="center">
<EuiFlexItem grow={false}>
<EuiTitle size={'xs'}>
<h2>
<span>
{i18n.translate(
'xpack.ml.timeSeriesExplorer.singleTimeSeriesAnalysisTitle',
{
defaultMessage: 'Single time series analysis of {functionLabel}',
values: { functionLabel: chartDetails.functionLabel },
}
)}
</span>
&nbsp;
{chartDetails.entityData.count === 1 && (
<EuiTextColor color={'success'} size={'s'} component={'span'}>
{chartDetails.entityData.entities.length > 0 && '('}
{chartDetails.entityData.entities
.map((entity) => {
return `${entity.fieldName}: ${entity.fieldValue}`;
})
.join(', ')}
{chartDetails.entityData.entities.length > 0 && ')'}
</EuiTextColor>
)}
{chartDetails.entityData.count !== 1 && (
<EuiTextColor color={'success'} size={'s'} component={'span'}>
{chartDetails.entityData.entities.map((countData, i) => {
return (
<Fragment key={countData.fieldName}>
{i18n.translate(
'xpack.ml.timeSeriesExplorer.countDataInChartDetailsDescription',
{
defaultMessage:
'{openBrace}{cardinalityValue} distinct {fieldName} {cardinality, plural, one {} other { values}}{closeBrace}',
values: {
openBrace: i === 0 ? '(' : '',
closeBrace:
i === chartDetails.entityData.entities.length - 1
? ')'
: '',
cardinalityValue:
countData.cardinality === 0
? allValuesLabel
: countData.cardinality,
cardinality: countData.cardinality,
fieldName: countData.fieldName,
},
}
)}
{i !== chartDetails.entityData.entities.length - 1 ? ', ' : ''}
</Fragment>
);
})}
</EuiTextColor>
)}
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<TimeSeriesExplorerHelpPopover />
</EuiFlexItem>
</EuiFlexGroup>
<SingleMetricViewerTitle
entityData={chartDetails.entityData}
functionLabel={chartDetails.functionLabel}
/>

<TimeSeriesExplorerControls
forecastId={this.props.selectedForecastId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { context } from '@kbn/kibana-react-plugin/public';
import { ML_JOB_AGGREGATION, aggregationTypeTransform } from '@kbn/ml-anomaly-utils';
import { getBoundsRoundedToInterval } from '@kbn/ml-time-buckets';

import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';

Expand All @@ -54,12 +55,12 @@ import { TimeSeriesChartWithTooltips } from '../components/timeseries_chart/time
import { isMetricDetector } from '../get_function_description';
import { TimeseriesexplorerChartDataError } from '../components/timeseriesexplorer_chart_data_error';
import { TimeseriesExplorerCheckbox } from './timeseriesexplorer_checkbox';
import { timeBucketsServiceFactory } from '../../util/time_buckets_service';
import { timeSeriesExplorerServiceFactory } from '../../util/time_series_explorer_service';
import { getTimeseriesexplorerDefaultState } from '../timeseriesexplorer_utils';
import { mlJobServiceFactory } from '../../services/job_service';
import { forecastServiceFactory } from '../../services/forecast_service';
import { SingleMetricViewerTitle } from './timeseriesexplorer_title';
import { SingleMetricViewerTitleWithFilters } from './timeseriesexplorer_title';
import { TimeSeriesExplorerEmbeddableControls } from './timeseriesexplorer_embeddable_controls';

export class TimeSeriesExplorerEmbeddableChart extends React.Component {
static propTypes = {
Expand Down Expand Up @@ -102,7 +103,6 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
*/
static contextType = context;

getBoundsRoundedToInterval;
mlTimeSeriesExplorer;
mlForecastService;

Expand Down Expand Up @@ -215,7 +215,7 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
// Ensure the search bounds align to the bucketing interval so that the first and last buckets are complete.
// For sum or count detectors, short buckets would hold smaller values, and model bounds would also be affected
// to some extent with all detector functions if not searching complete buckets.
const searchBounds = this.getBoundsRoundedToInterval(bounds, focusAggregationInterval, false);
const searchBounds = getBoundsRoundedToInterval(bounds, focusAggregationInterval, false);

return this.mlTimeSeriesExplorer.getFocusData(
this.getCriteriaFields(selectedDetectorIndex, entityControls),
Expand Down Expand Up @@ -465,7 +465,7 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
// Ensure the search bounds align to the bucketing interval so that the first and last buckets are complete.
// For sum or count detectors, short buckets would hold smaller values, and model bounds would also be affected
// to some extent with all detector functions if not searching complete buckets.
const searchBounds = this.getBoundsRoundedToInterval(
const searchBounds = getBoundsRoundedToInterval(
bounds,
stateUpdate.contextAggregationInterval,
false
Expand Down Expand Up @@ -623,10 +623,6 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
}

async componentDidMount() {
this.getBoundsRoundedToInterval = timeBucketsServiceFactory(
this.context.services.uiSettings
).getBoundsRoundedToInterval;

this.mlTimeSeriesExplorer = timeSeriesExplorerServiceFactory(
this.context.services.uiSettings,
this.context.services.mlServices.mlApi,
Expand Down Expand Up @@ -681,7 +677,7 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
// Ensure the search bounds align to the bucketing interval so that the first and last buckets are complete.
// For sum or count detectors, short buckets would hold smaller values, and model bounds would also be affected
// to some extent with all detector functions if not searching complete buckets.
const searchBounds = this.getBoundsRoundedToInterval(
const searchBounds = getBoundsRoundedToInterval(
bounds,
this.getFocusAggregationInterval({
from: selection.from,
Expand Down Expand Up @@ -917,50 +913,23 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component {
(fullRefresh === false || loading === false) &&
hasResults === true && (
<div>
<SingleMetricViewerTitle
<SingleMetricViewerTitleWithFilters
api={this.props.api}
functionLabel={chartDetails.functionLabel}
entityData={chartDetails.entityData}
/>
<EuiFlexGroup style={{ float: 'right' }} alignItems="center">
{showModelBoundsCheckbox && (
<TimeseriesExplorerCheckbox
id="toggleModelBoundsCheckbox"
label={i18n.translate('xpack.ml.timeSeriesExplorer.showModelBoundsLabel', {
defaultMessage: 'show model bounds',
})}
checked={showModelBounds}
onChange={this.toggleShowModelBoundsHandler}
/>
)}

{showAnnotationsCheckbox && (
<TimeseriesExplorerCheckbox
id="toggleAnnotationsCheckbox"
label={i18n.translate('xpack.ml.timeSeriesExplorer.annotationsLabel', {
defaultMessage: 'annotations',
})}
checked={showAnnotations}
onChange={this.toggleShowAnnotationsHandler}
/>
)}

{showForecastCheckbox && (
<EuiFlexItem grow={false}>
<TimeseriesExplorerCheckbox
id="toggleShowForecastCheckbox"
label={
<span data-test-subj={'mlForecastCheckbox'}>
{i18n.translate('xpack.ml.timeSeriesExplorer.showForecastLabel', {
defaultMessage: 'show forecast',
})}
</span>
}
checked={showForecast}
onChange={this.toggleShowForecastHandler}
/>
</EuiFlexItem>
)}
<TimeSeriesExplorerEmbeddableControls
showAnnotations={showAnnotations}
showAnnotationsCheckbox={showAnnotationsCheckbox}
showForecast={showForecast}
showForecastCheckbox={showForecastCheckbox}
showModelBounds={showModelBounds}
showModelBoundsCheckbox={showModelBoundsCheckbox}
onShowAnnotationsChange={this.toggleShowAnnotationsHandler}
onShowForecastChange={this.toggleShowForecastHandler}
onShowModelBoundsChange={this.toggleShowModelBoundsHandler}
/>

{arePartitioningFieldsProvided &&
selectedJob &&
Expand Down
Loading

0 comments on commit 5d994f4

Please sign in to comment.