Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Single Metric Viewer embeddable: Adds action for dashboard to apply filter from the embeddable to the page #198869

Merged
merged 17 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ interface EntityFilterProps {
}) => void;
influencerFieldName: string;
influencerFieldValue: string;
isEmbeddable?: boolean;
}
export const EntityFilter: FC<EntityFilterProps> = ({
onFilter,
influencerFieldName,
influencerFieldValue,
isEmbeddable,
}) => {
return (
<React.Fragment>
<EuiToolTip
content={
<FormattedMessage
id="xpack.ml.entityFilter.addFilterTooltip"
defaultMessage="Add filter"
defaultMessage="Filter for"
/>
}
>
Expand All @@ -57,10 +59,17 @@ export const EntityFilter: FC<EntityFilterProps> = ({
</EuiToolTip>
<EuiToolTip
content={
<FormattedMessage
id="xpack.ml.entityFilter.removeFilterTooltip"
defaultMessage="Remove filter"
/>
isEmbeddable ? (
<FormattedMessage
id="xpack.ml.entityFilter.filterOutTooltip"
defaultMessage={'Filter out'}
/>
) : (
<FormattedMessage
id="xpack.ml.entityFilter.removeFilterTooltip"
defaultMessage={'Remove filter'}
/>
)
}
>
<EuiButtonIcon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function ExplorerChartLabel({
detectorLabel,
entityFields,
infoTooltip,
isEmbeddable,
wrapLabel = false,
onSelectEntity,
}) {
Expand All @@ -34,9 +35,9 @@ export function ExplorerChartLabel({
// Using &nbsp;s here to make sure those spaces get rendered.
const labelSeparator =
wrapLabel === true || entityFields.length === 0 || detectorLabel.length === 0 ? (
<React.Fragment>&nbsp;</React.Fragment>
<>&nbsp;</>
) : (
<React.Fragment>&nbsp;&ndash;&nbsp;</React.Fragment>
<>&nbsp;&ndash;&nbsp;</>
);

const applyFilter = useCallback(
Expand All @@ -52,6 +53,7 @@ export function ExplorerChartLabel({
<ExplorerChartLabelBadge entity={entity} />
{onSelectEntity !== undefined && (
<EntityFilter
isEmbeddable={isEmbeddable}
onFilter={applyFilter}
influencerFieldName={entity.fieldName}
influencerFieldValue={entity.fieldValue}
Expand All @@ -73,25 +75,26 @@ export function ExplorerChartLabel({
);

return (
<React.Fragment>
<>
<span className="ml-explorer-chart-label">
<span className="ml-explorer-chart-label-detector">
{detectorLabel}
{labelSeparator}
</span>
{wrapLabel && infoIcon}
{!wrapLabel && (
<React.Fragment>
<>
{entityFieldBadges} {infoIcon}
</React.Fragment>
</>
)}
</span>
{wrapLabel && <span className="ml-explorer-chart-label-badges">{entityFieldBadges}</span>}
</React.Fragment>
</>
);
}
ExplorerChartLabel.propTypes = {
detectorLabel: PropTypes.object.isRequired,
isEmbeddable: PropTypes.boolean,
entityFields: PropTypes.arrayOf(ExplorerChartLabelBadge.propTypes.entity),
infoTooltip: PropTypes.object.isRequired,
wrapLabel: PropTypes.bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const ExplorerAnomaliesContainer: FC<ExplorerAnomaliesContainerProps> = (
<ExplorerChartsContainer
{...{
...chartsData,
isEmbeddable: true,
severity: severity.val,
mlLocator,
tableData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ function getChartId(series, randomId) {
// Wrapper for a single explorer chart
function ExplorerChartContainer({
id,
isEmbeddable,
series,
severity,
tooManyBuckets,
Expand Down Expand Up @@ -251,6 +252,7 @@ function ExplorerChartContainer({
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<ExplorerChartLabel
isEmbeddable={isEmbeddable}
detectorLabel={DetectorLabel}
entityFields={entityFields}
infoTooltip={{ ...series.infoTooltip, chartType }}
Expand Down Expand Up @@ -376,6 +378,7 @@ function ExplorerChartContainer({
// Flex layout wrapper for all explorer charts
export const ExplorerChartsContainerUI = ({
id: uuid,
isEmbeddable,
chartsPerRow,
seriesToPlot,
severity,
Expand Down Expand Up @@ -443,6 +446,7 @@ export const ExplorerChartsContainerUI = ({
<ExplorerChartContainer
key={chartId}
id={chartId}
isEmbeddable={isEmbeddable}
series={series}
severity={severity}
tooManyBuckets={tooManyBuckets}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,7 @@ 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 {
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiTitle,
EuiTextColor,
} from '@elastic/eui';
import { TimeSeriesExplorerHelpPopover } from '../timeseriesexplorer_help_popover';
import { EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';

import { ANOMALIES_TABLE_DEFAULT_QUERY_SIZE } from '../../../../common/constants/search';
import {
Expand Down Expand Up @@ -67,16 +59,11 @@ import { timeSeriesExplorerServiceFactory } from '../../util/time_series_explore
import { getTimeseriesexplorerDefaultState } from '../timeseriesexplorer_utils';
import { mlJobServiceFactory } from '../../services/job_service';
import { forecastServiceFactory } from '../../services/forecast_service';

// 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',
});
import { SingleMetricViewerTitle } from './timeseriesexplorer_title';

export class TimeSeriesExplorerEmbeddableChart extends React.Component {
static propTypes = {
api: PropTypes.object,
appStateHandler: PropTypes.func.isRequired,
autoZoomDuration: PropTypes.number.isRequired,
bounds: PropTypes.object.isRequired,
Expand Down Expand Up @@ -930,70 +917,11 @@ export class TimeSeriesExplorerEmbeddableChart 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 embeddableMode />
</EuiFlexItem>
</EuiFlexGroup>
<SingleMetricViewerTitle
api={this.props.api}
functionLabel={chartDetails.functionLabel}
entityData={chartDetails.entityData}
/>
<EuiFlexGroup style={{ float: 'right' }} alignItems="center">
{showModelBoundsCheckbox && (
<TimeseriesExplorerCheckbox
Expand Down
Loading