Skip to content

Commit

Permalink
[7.x] [ML] Redesign index-based Data Visualizer (#85726) (#86029)
Browse files Browse the repository at this point in the history
  • Loading branch information
qn895 authored Dec 15, 2020
1 parent 4e8c0ad commit f412820
Show file tree
Hide file tree
Showing 62 changed files with 2,292 additions and 1,136 deletions.
20 changes: 10 additions & 10 deletions x-pack/plugins/ml/common/constants/field_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/

export enum ML_JOB_FIELD_TYPES {
BOOLEAN = 'boolean',
DATE = 'date',
GEO_POINT = 'geo_point',
IP = 'ip',
KEYWORD = 'keyword',
NUMBER = 'number',
TEXT = 'text',
UNKNOWN = 'unknown',
}
export const ML_JOB_FIELD_TYPES = {
BOOLEAN: 'boolean',
DATE: 'date',
GEO_POINT: 'geo_point',
IP: 'ip',
KEYWORD: 'keyword',
NUMBER: 'number',
TEXT: 'text',
UNKNOWN: 'unknown',
} as const;

export const MLCATEGORY = 'mlcategory';

Expand Down
24 changes: 24 additions & 0 deletions x-pack/plugins/ml/common/types/datavisualizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export interface AggregatableField {
fieldName: string;
stats: {
cardinality?: number;
count?: number;
sampleCount?: number;
};
existsInDocs: boolean;
}

export type NonAggregatableField = Omit<AggregatableField, 'stats'>;
export interface OverallStats {
totalCount: number;
aggregatableExistsFields: AggregatableField[];
aggregatableNotExistsFields: NonAggregatableField[];
nonAggregatableExistsFields: AggregatableField[];
nonAggregatableNotExistsFields: NonAggregatableField[];
}
9 changes: 9 additions & 0 deletions x-pack/plugins/ml/common/types/field_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ML_JOB_FIELD_TYPES } from '../constants/field_types';

export type MlJobFieldType = typeof ML_JOB_FIELD_TYPES[keyof typeof ML_JOB_FIELD_TYPES];
29 changes: 24 additions & 5 deletions x-pack/plugins/ml/common/types/ml_url_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { RefreshInterval, TimeRange } from '../../../../../src/plugins/data/common/query';
import { JobId } from './anomaly_detection_jobs/job';
import type {
Query,
RefreshInterval,
TimeRange,
} from '../../../../../src/plugins/data/common/query';
import type { JobId } from './anomaly_detection_jobs/job';
import { ML_PAGES } from '../constants/ml_url_generator';
import { DataFrameAnalysisConfigType } from './data_frame_analytics';
import { SearchQueryLanguage } from '../constants/search';
import { ListingPageUrlState } from './common';
import type { DataFrameAnalysisConfigType } from './data_frame_analytics';
import type { SearchQueryLanguage } from '../constants/search';
import type { ListingPageUrlState } from './common';

type OptionalPageState = object | undefined;

Expand Down Expand Up @@ -38,6 +42,21 @@ export interface MlGenericUrlPageState extends MlIndexBasedSearchState {
[key: string]: any;
}

export interface DataVisualizerIndexBasedAppState {
pageIndex: number;
pageSize: number;
sortField: string;
sortDirection: string;
searchString?: Query['query'];
searchQuery?: Query['query'];
searchQueryLanguage?: SearchQueryLanguage;
visibleFieldTypes?: string[];
visibleFieldNames?: string[];
samplerShardSize?: number;
showDistributions?: boolean;
showAllFields?: boolean;
showEmptyFields?: boolean;
}
export type MlGenericUrlState = MLPageState<
| typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER
| typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,41 @@ interface Props {
chartData: ChartData;
columnType: EuiDataGridColumn;
dataTestSubj: string;
hideLabel?: boolean;
maxChartColumns?: number;
}

export const ColumnChart: FC<Props> = ({ chartData, columnType, dataTestSubj }) => {
const { data, legendText, xScaleType } = useColumnChart(chartData, columnType);
const columnChartTheme = {
background: { color: 'transparent' },
chartMargins: {
left: 0,
right: 0,
top: 0,
bottom: 1,
},
chartPaddings: {
left: 0,
right: 0,
top: 0,
bottom: 0,
},
scales: { barsPadding: 0.1 },
};
export const ColumnChart: FC<Props> = ({
chartData,
columnType,
dataTestSubj,
hideLabel,
maxChartColumns,
}) => {
const { data, legendText, xScaleType } = useColumnChart(chartData, columnType, maxChartColumns);

return (
<div data-test-subj={dataTestSubj}>
{!isUnsupportedChartData(chartData) && data.length > 0 && (
<div className="mlDataGridChart__histogram" data-test-subj={`${dataTestSubj}-histogram`}>
<Chart>
<Settings
theme={{
background: { color: 'transparent' },
chartMargins: {
left: 0,
right: 0,
top: 0,
bottom: 1,
},
chartPaddings: {
left: 0,
right: 0,
top: 0,
bottom: 0,
},
scales: { barsPadding: 0.1 },
}}
/>
<Settings theme={columnChartTheme} />
<BarSeries
id="histogram"
name="count"
Expand All @@ -68,7 +75,7 @@ export const ColumnChart: FC<Props> = ({ chartData, columnType, dataTestSubj })
>
{legendText}
</div>
<div data-test-subj={`${dataTestSubj}-id`}>{columnType.id}</div>
{!hideLabel && <div data-test-subj={`${dataTestSubj}-id`}>{columnType.id}</div>}
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ export const isNumericChartData = (arg: any): arg is NumericChartData => {
);
};

interface OrdinalDataItem {
export interface OrdinalDataItem {
key: string;
key_as_string?: string;
doc_count: number;
}

interface OrdinalChartData {
export interface OrdinalChartData {
type: 'ordinal' | 'boolean';
cardinality: number;
data: OrdinalDataItem[];
Expand All @@ -120,11 +120,14 @@ export const isUnsupportedChartData = (arg: any): arg is UnsupportedChartData =>
return arg.hasOwnProperty('type') && arg.type === 'unsupported';
};

type ChartDataItem = NumericDataItem | OrdinalDataItem;
export type ChartDataItem = NumericDataItem | OrdinalDataItem;
export type ChartData = NumericChartData | OrdinalChartData | UnsupportedChartData;

type LegendText = string | JSX.Element;
const getLegendText = (chartData: ChartData): LegendText => {
export const getLegendText = (
chartData: ChartData,
maxChartColumns = MAX_CHART_COLUMNS
): LegendText => {
if (chartData.type === 'unsupported') {
return i18n.translate('xpack.ml.dataGridChart.histogramNotAvailable', {
defaultMessage: 'Chart not supported.',
Expand All @@ -150,17 +153,17 @@ const getLegendText = (chartData: ChartData): LegendText => {
);
}

if (isOrdinalChartData(chartData) && chartData.cardinality <= MAX_CHART_COLUMNS) {
if (isOrdinalChartData(chartData) && chartData.cardinality <= maxChartColumns) {
return i18n.translate('xpack.ml.dataGridChart.singleCategoryLegend', {
defaultMessage: `{cardinality, plural, one {# category} other {# categories}}`,
values: { cardinality: chartData.cardinality },
});
}

if (isOrdinalChartData(chartData) && chartData.cardinality > MAX_CHART_COLUMNS) {
if (isOrdinalChartData(chartData) && chartData.cardinality > maxChartColumns) {
return i18n.translate('xpack.ml.dataGridChart.topCategoriesLegend', {
defaultMessage: `top {MAX_CHART_COLUMNS} of {cardinality} categories`,
values: { cardinality: chartData.cardinality, MAX_CHART_COLUMNS },
defaultMessage: `top {maxChartColumns} of {cardinality} categories`,
values: { cardinality: chartData.cardinality, maxChartColumns },
});
}

Expand All @@ -182,7 +185,8 @@ interface ColumnChart {

export const useColumnChart = (
chartData: ChartData,
columnType: EuiDataGridColumn
columnType: EuiDataGridColumn,
maxChartColumns?: number
): ColumnChart => {
const fieldType = getFieldType(columnType.schema);

Expand Down Expand Up @@ -244,7 +248,7 @@ export const useColumnChart = (

return {
data,
legendText: getLegendText(chartData),
legendText: getLegendText(chartData, maxChartColumns),
xScaleType,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import { i18n } from '@kbn/i18n';

import { getMLJobTypeAriaLabel } from '../../util/field_types_utils';
import { ML_JOB_FIELD_TYPES } from '../../../../common/constants/field_types';
import type { MlJobFieldType } from '../../../../common/types/field_types';

interface FieldTypeIconProps {
tooltipEnabled: boolean;
type: ML_JOB_FIELD_TYPES;
type: MlJobFieldType;
fieldName?: string;
needsAria: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export { MultiSelectPicker, Option } from './multi_select_picker';
Loading

0 comments on commit f412820

Please sign in to comment.