Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
61f9729
init
thomasneirynck Nov 12, 2020
18dac03
Fix tests/rename
thomasneirynck Nov 12, 2020
934d689
Type fixes
thomasneirynck Nov 12, 2020
dca9608
adding descriptors
thomasneirynck Nov 12, 2020
ef00fdd
remove fluffy export
thomasneirynck Nov 12, 2020
e640b9d
remove redundant cast
thomasneirynck Nov 12, 2020
6e3463f
rename to count-agg field
thomasneirynck Nov 12, 2020
fa0d459
extract types
thomasneirynck Nov 12, 2020
750eb78
rename
thomasneirynck Nov 12, 2020
cb331e0
boilerplate
thomasneirynck Nov 12, 2020
8380a56
remove switching
thomasneirynck Nov 12, 2020
0577e9d
remove count type-checking
thomasneirynck Nov 12, 2020
05f7fdc
Merge branch 'maps/add_descriptors' into maps/add_percentile
thomasneirynck Nov 12, 2020
82863b7
more boilerplate
thomasneirynck Nov 12, 2020
0c8ea4f
simplify
thomasneirynck Nov 12, 2020
43ef71b
move files
thomasneirynck Nov 12, 2020
d2aa300
Merge branch 'maps/add_descriptors' into maps/add_percentile
thomasneirynck Nov 12, 2020
d3103e9
boilerplate
thomasneirynck Nov 16, 2020
e1fca30
type fix
thomasneirynck Nov 16, 2020
dce131d
Merge branch 'master' of github.com:elastic/kibana into maps/add_perc…
thomasneirynck Nov 16, 2020
25f5960
add slider
thomasneirynck Nov 16, 2020
211bb3c
type fixes
thomasneirynck Nov 16, 2020
6105ba7
init commit
thomasneirynck Nov 17, 2020
47560f9
some type fixes
thomasneirynck Nov 18, 2020
f54ca8a
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 18, 2020
71e49df
add type check
thomasneirynck Nov 18, 2020
b7d8bbd
only take into account invalid dynamic fields
thomasneirynck Nov 18, 2020
c507a77
tmp debug
thomasneirynck Nov 18, 2020
e861f26
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 20, 2020
ffad517
ts type fixes
thomasneirynck Nov 20, 2020
e002047
retype
thomasneirynck Nov 23, 2020
ef1f225
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 23, 2020
9590abd
fix field-lookup after refactor
thomasneirynck Nov 23, 2020
e1e7ea0
type fixes
thomasneirynck Nov 23, 2020
c941774
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 24, 2020
54eacb3
add test covergage
thomasneirynck Nov 24, 2020
001e0e1
add edge case test
thomasneirynck Nov 24, 2020
6b70fcb
fix test for new behavior
thomasneirynck Nov 24, 2020
361486a
fix rum test
thomasneirynck Nov 24, 2020
67c1362
type fix
thomasneirynck Nov 24, 2020
4f72d40
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 24, 2020
4475c94
Merge branch 'master' of github.com:elastic/kibana into maps/add_perc…
thomasneirynck Nov 24, 2020
c2b0750
type fixes
thomasneirynck Nov 24, 2020
a14e3f0
type fix
thomasneirynck Nov 25, 2020
2069fcd
fix test
thomasneirynck Nov 25, 2020
ab8f0a5
Merge branch 'maps/update_style' into maps/add_percentile
thomasneirynck Nov 25, 2020
f23c642
simplify
thomasneirynck Nov 25, 2020
caaebb0
Merge branch 'master' of github.com:elastic/kibana into maps/add_perc…
thomasneirynck Nov 25, 2020
f794114
Merge branch 'master' into maps/update_style
thomasneirynck Nov 25, 2020
09e8dba
Merge branch 'master' of github.com:elastic/kibana into maps/update_s…
thomasneirynck Nov 25, 2020
0efe401
revert uptime change
thomasneirynck Nov 25, 2020
3f9ffdf
Merge branch 'master' into maps/update_style
kibanamachine Nov 30, 2020
b4f3ea2
Merge branch 'maps/update_style' into maps/add_percentile
thomasneirynck Nov 30, 2020
dc5c8c8
fix term join parsing
thomasneirynck Nov 30, 2020
6ea286b
feedback
thomasneirynck Nov 30, 2020
5d6fa3e
rearrange
thomasneirynck Nov 30, 2020
ac2f943
switch inner-outer loop
thomasneirynck Nov 30, 2020
bb65b1d
use foreach
thomasneirynck Nov 30, 2020
9eee260
Merge branch 'maps/update_style' into maps/add_percentile
thomasneirynck Dec 1, 2020
1029527
Merge branch 'master' of github.com:elastic/kibana into maps/add_perc…
thomasneirynck Dec 9, 2020
13a408a
implement new stylemeta api
thomasneirynck Dec 9, 2020
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
2 changes: 2 additions & 0 deletions x-pack/plugins/maps/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export enum AGG_TYPE {
MIN = 'min',
SUM = 'sum',
TERMS = 'terms',
PERCENTILE = 'percentile',
UNIQUE_COUNT = 'cardinality',
}

Expand All @@ -171,6 +172,7 @@ export const GEOTILE_GRID_AGG_NAME = 'gridSplit';
export const GEOCENTROID_AGG_NAME = 'gridCentroid';

export const TOP_TERM_PERCENTAGE_SUFFIX = '__percentage';
export const DEFAULT_PERCENTILE = 50;

export const COUNT_PROP_LABEL = i18n.translate('xpack.maps.aggs.defaultCountLabel', {
defaultMessage: 'count',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ export type FieldedAggDescriptor = AbstractAggDescriptor & {
field?: string;
};

export type AggDescriptor = CountAggDescriptor | FieldedAggDescriptor;
export type PercentileAggDescriptor = AbstractAggDescriptor & {
type: AGG_TYPE.PERCENTILE;
field?: string;
percentile?: number;
};

export type AggDescriptor = CountAggDescriptor | FieldedAggDescriptor | PercentileAggDescriptor;

export type AbstractESAggSourceDescriptor = AbstractESSourceDescriptor & {
metrics: AggDescriptor[];
Expand Down
18 changes: 16 additions & 2 deletions x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { i18n } from '@kbn/i18n';
import _ from 'lodash';
import { IndexPattern, IFieldType } from '../../../../../src/plugins/data/common';
import { TOP_TERM_PERCENTAGE_SUFFIX } from '../constants';
import { AGG_TYPE, JOIN_FIELD_NAME_PREFIX, TOP_TERM_PERCENTAGE_SUFFIX } from '../constants';

export type BucketProperties = Record<string | number, unknown>;
export type PropertiesMap = Map<string, BucketProperties>;
Expand Down Expand Up @@ -46,6 +46,7 @@ export function extractPropertiesFromBucket(
continue;
}

// todo: push these implementations in the IAggFields
if (_.has(bucket[key], 'value')) {
properties[key] = bucket[key].value;
} else if (_.has(bucket[key], 'buckets')) {
Expand All @@ -63,7 +64,20 @@ export function extractPropertiesFromBucket(
);
}
} else {
properties[key] = bucket[key];
if (
key.startsWith(AGG_TYPE.PERCENTILE) ||
key.startsWith(JOIN_FIELD_NAME_PREFIX + AGG_TYPE.PERCENTILE)
) {
const values = bucket[key].values;
for (const k in values) {
if (values.hasOwnProperty(k)) {
properties[key] = values[k];
break;
}
}
} else {
properties[key] = bucket[key];
}
}
}
return properties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import { IESAggField, CountAggFieldParams } from './agg_field_types';

// Agg without field. Essentially a count-aggregation.
export class CountAggField implements IESAggField {
private readonly _source: IESAggSource;
protected readonly _source: IESAggSource;
private readonly _origin: FIELD_ORIGIN;
private readonly _label?: string;
protected readonly _label?: string;
private readonly _canReadFromGeoJson: boolean;

constructor({ label, source, origin, canReadFromGeoJson = true }: CountAggFieldParams) {
Expand Down
18 changes: 17 additions & 1 deletion x-pack/plugins/maps/public/classes/fields/agg/es_agg_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

import { AggDescriptor } from '../../../../common/descriptor_types';
import { IESAggSource } from '../../sources/es_agg_source';
import { AGG_TYPE, FIELD_ORIGIN } from '../../../../common/constants';
import { AGG_TYPE, DEFAULT_PERCENTILE, FIELD_ORIGIN } from '../../../../common/constants';
import { ESDocField } from '../es_doc_field';
import { TopTermPercentageField } from './top_term_percentage_field';
import { CountAggField } from './count_agg_field';
import { IESAggField } from './agg_field_types';
import { AggField } from './agg_field';
import { PercentileAggField } from './percentile_agg_field';

export function esAggFieldsFactory(
aggDescriptor: AggDescriptor,
Expand All @@ -27,6 +28,21 @@ export function esAggFieldsFactory(
origin,
canReadFromGeoJson,
});
} else if (aggDescriptor.type === AGG_TYPE.PERCENTILE) {
aggField = new PercentileAggField({
label: aggDescriptor.label,
esDocField:
'field' in aggDescriptor && aggDescriptor.field
? new ESDocField({ fieldName: aggDescriptor.field, source, origin })
: undefined,
percentile:
'percentile' in aggDescriptor && typeof aggDescriptor.percentile === 'number'
? aggDescriptor.percentile
: DEFAULT_PERCENTILE,
source,
origin,
canReadFromGeoJson,
});
} else {
aggField = new AggField({
label: aggDescriptor.label,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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 { IndexPattern } from 'src/plugins/data/common/index_patterns/index_patterns';
import { AGG_TYPE } from '../../../../common/constants';
import { IESAggField, CountAggFieldParams } from './agg_field_types';
import { CountAggField } from './count_agg_field';
import { addFieldToDSL, getField } from '../../../../common/elasticsearch_util';
import { ESDocField } from '../es_doc_field';

export interface PercentileAggParams extends CountAggFieldParams {
esDocField?: ESDocField;
percentile: number;
}

export class PercentileAggField extends CountAggField implements IESAggField {
private readonly _percentile: number;
private readonly _esDocField?: ESDocField;
constructor(params: PercentileAggParams) {
super(params);
this._esDocField = params.esDocField;
this._percentile = params.percentile;
}

supportsFieldMeta(): boolean {
return true;
}

canValueBeFormatted(): boolean {
return true;
}

async getLabel(): Promise<string> {
const suffix = this._percentile === 1 ? 'st' : this._percentile === 2 ? 'nd' : 'th';
return this._label
? this._label
: `${this._percentile}${suffix} ${this._source.getAggLabel(
this._getAggType(),
this.getRootName()
)}`;
}

getName() {
return `${super.getName()}_${this._percentile}`;
}

getRootName(): string {
return this._esDocField ? this._esDocField.getName() : '';
}

getValueAggDsl(indexPattern: IndexPattern): unknown {
const field = getField(indexPattern, this.getRootName());
const dsl: Record<string, unknown> = addFieldToDSL({}, field);
dsl.percents = [this._percentile];
return {
percentiles: dsl,
};
}

_getAggType(): AGG_TYPE {
return AGG_TYPE.PERCENTILE;
}

async getExtendedStatsFieldMetaRequest(): Promise<unknown | null> {
return this._esDocField ? await this._esDocField.getExtendedStatsFieldMetaRequest() : null;
}

async getCategoricalFieldMetaRequest(size: number): Promise<unknown | null> {
return this._esDocField ? await this._esDocField.getCategoricalFieldMetaRequest(size) : null;
}

async getPercentilesFieldMetaRequest(percentiles: number[]): Promise<unknown | null> {
return this._esDocField
? await this._esDocField.getPercentilesFieldMetaRequest(percentiles)
: null;
}

isValid(): boolean {
return !!this._esDocField;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ interface CountData {
isSyncClustered: boolean;
}

function getAggType(dynamicProperty: IDynamicStyleProperty<DynamicStylePropertyOptions>): AGG_TYPE {
function getAggType(
dynamicProperty: IDynamicStyleProperty<DynamicStylePropertyOptions>
): AGG_TYPE.AVG | AGG_TYPE.TERMS {
return dynamicProperty.isOrdinal() ? AGG_TYPE.AVG : AGG_TYPE.TERMS;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
import { VectorStyle } from '../styles/vector/vector_style';
import { EMSFileSource } from '../sources/ems_file_source';
// @ts-ignore
import { ESGeoGridSource } from '../sources/es_geo_grid_source';
import { VectorLayer } from './vector_layer/vector_layer';
import { getDefaultDynamicProperties } from '../styles/vector/vector_style_defaults';
import { NUMERICAL_COLOR_PALETTES } from '../styles/color_palettes';
Expand All @@ -35,9 +34,13 @@ export function createAggDescriptor(metricAgg: string, metricFieldName?: string)
});
const aggType = aggTypeKey ? AGG_TYPE[aggTypeKey as keyof typeof AGG_TYPE] : undefined;

return aggType && metricFieldName
? { type: aggType, field: metricFieldName }
: { type: AGG_TYPE.COUNT };
if (!aggType || aggType === AGG_TYPE.COUNT || !metricFieldName) {
return { type: AGG_TYPE.COUNT };
} else if (aggType === AGG_TYPE.PERCENTILE) {
return { type: aggType, field: metricFieldName, percentile: 50 };
} else {
return { type: aggType, field: metricFieldName };
}
}

export function createRegionMapLayerDescriptor({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import {
AGG_TYPE,
COLOR_MAP_TYPE,
DEFAULT_PERCENTILE,
FIELD_ORIGIN,
GRID_RESOLUTION,
RENDER_AS,
Expand Down Expand Up @@ -59,9 +60,18 @@ export function createAggDescriptor(
});
const aggType = aggTypeKey ? AGG_TYPE[aggTypeKey as keyof typeof AGG_TYPE] : undefined;

return aggType && metricFieldName && (!isHeatmap(mapType) || isMetricCountable(aggType))
? { type: aggType, field: metricFieldName }
: { type: AGG_TYPE.COUNT };
if (
!aggType ||
aggType === AGG_TYPE.COUNT ||
!metricFieldName ||
(isHeatmap(mapType) && !isMetricCountable(aggType))
) {
return { type: AGG_TYPE.COUNT };
}

return aggType === AGG_TYPE.PERCENTILE
? { type: aggType, field: metricFieldName, percentile: DEFAULT_PERCENTILE }
: { type: aggType, field: metricFieldName };
}

export function createTileMapLayerDescriptor({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface IESAggSource extends IESSource {
getValueAggsDsl(indexPattern: IndexPattern): { [key: string]: unknown };
}

export abstract class AbstractESAggSource extends AbstractESSource {
export abstract class AbstractESAggSource extends AbstractESSource implements IESAggSource {
private readonly _metricFields: IESAggField[];
private readonly _canReadFromGeoJson: boolean;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export class DynamicColorProperty extends DynamicStyleProperty<ColorDynamicOptio
this._options.color ? this._options.color : null,
percentilesFieldMeta
);

if (!colorStops) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
LAYER_STYLE_TYPE,
SOURCE_FORMATTERS_DATA_REQUEST_ID,
STYLE_TYPE,
TOP_TERM_PERCENTAGE_SUFFIX,
VECTOR_SHAPE_TYPE,
VECTOR_STYLES,
} from '../../../../common/constants';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { ChangeEvent, Fragment } from 'react';
import React, { ChangeEvent, Fragment, MouseEvent } from 'react';
import { i18n } from '@kbn/i18n';

import { EuiButtonEmpty, EuiComboBoxOptionOption, EuiFieldText, EuiFormRow } from '@elastic/eui';
import {
EuiButtonEmpty,
EuiComboBoxOptionOption,
EuiFieldText,
EuiFormRow,
EuiRange,
} from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { MetricSelect } from './metric_select';
import { SingleFieldSelect } from '../single_field_select';
import { AggDescriptor } from '../../../common/descriptor_types';
import { AGG_TYPE } from '../../../common/constants';
import { AGG_TYPE, DEFAULT_PERCENTILE } from '../../../common/constants';
import { getTermsFields } from '../../index_pattern_util';
import { IFieldType } from '../../../../../../src/plugins/data/public';

Expand Down Expand Up @@ -70,10 +76,18 @@ export function MetricEditor({

const fieldsForNewAggType = filterFieldsForAgg(fields, metricAggregationType);
const found = fieldsForNewAggType.find((field) => field.name === metric.field);
onChange({
const newDescriptor = {
...descriptor,
field: found ? metric.field : undefined,
});
};
if (metricAggregationType === AGG_TYPE.PERCENTILE) {
onChange({
...newDescriptor,
percentile: 'percentile' in metric ? metric.percentile : DEFAULT_PERCENTILE,
});
} else {
onChange(newDescriptor);
}
};
const onFieldChange = (fieldName?: string) => {
if (!fieldName || metric.type === AGG_TYPE.COUNT) {
Expand All @@ -85,6 +99,16 @@ export function MetricEditor({
field: fieldName,
});
};

const onPercentileChange = (e: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLButtonElement>) => {
if (metric.type !== AGG_TYPE.PERCENTILE) {
return;
}
onChange({
...metric,
percentile: parseInt((e.target as HTMLInputElement).value, 10),
});
};
const onLabelChange = (e: ChangeEvent<HTMLInputElement>) => {
onChange({
...metric,
Expand Down Expand Up @@ -115,6 +139,29 @@ export function MetricEditor({
);
}

let percentileSelect;
if (metric.type === AGG_TYPE.PERCENTILE) {
percentileSelect = (
<EuiFormRow
label={i18n.translate('xpack.maps.metricsEditor.selectPercentileLabel', {
defaultMessage: 'Percentile',
})}
display="columnCompressed"
>
<EuiRange
min={0}
max={100}
step={1}
value={typeof metric.percentile === 'number' ? metric.percentile : DEFAULT_PERCENTILE}
onChange={onPercentileChange}
showLabels
showValue
aria-label="percentile select"
/>
</EuiFormRow>
);
}

let labelInput;
if (metric.type) {
labelInput = (
Expand Down Expand Up @@ -172,6 +219,7 @@ export function MetricEditor({
</EuiFormRow>

{fieldSelect}
{percentileSelect}
{labelInput}
{removeButton}
</Fragment>
Expand Down
Loading