From e4187b601f6ae1f07534ccae5f0264c733430f53 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 5 May 2020 08:21:48 -0600 Subject: [PATCH] [Maps] add categorical palettes with 20 and 30 categories (#64701) * [Maps] add categorical palettes with 20 and 30 categories * fix ts-lint Co-authored-by: Elastic Machine --- x-pack/plugins/maps/common/constants.ts | 2 - .../public/layers/blended_vector_layer.ts | 53 +++++++++++-------- .../maps/public/layers/fields/es_agg_field.ts | 4 +- .../maps/public/layers/fields/es_doc_field.ts | 7 ++- .../maps/public/layers/fields/field.ts | 4 +- .../maps/public/layers/styles/color_utils.js | 13 +++-- .../properties/dynamic_color_property.js | 5 ++ .../properties/dynamic_style_property.d.ts | 1 + .../properties/dynamic_style_property.js | 18 +++---- .../maps/public/layers/vector_layer.js | 2 +- 10 files changed, 63 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index b1a613e789e85..e95fe9500746c 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -174,8 +174,6 @@ export const COLOR_MAP_TYPE = { ORDINAL: 'ORDINAL', }; -export const COLOR_PALETTE_MAX_SIZE = 10; - export const CATEGORICAL_DATA_TYPES = ['string', 'ip', 'boolean']; export const ORDINAL_DATA_TYPES = ['number', 'date']; diff --git a/x-pack/plugins/maps/public/layers/blended_vector_layer.ts b/x-pack/plugins/maps/public/layers/blended_vector_layer.ts index 5c486200977d7..adf04b4155659 100644 --- a/x-pack/plugins/maps/public/layers/blended_vector_layer.ts +++ b/x-pack/plugins/maps/public/layers/blended_vector_layer.ts @@ -260,33 +260,40 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer { prevDataRequest: this.getDataRequest(dataRequestId), nextMeta: searchFilters, }); - if (canSkipFetch) { - return; - } - - let isSyncClustered; - try { - syncContext.startLoading(dataRequestId, requestToken, searchFilters); - const searchSource = await this._documentSource.makeSearchSource(searchFilters, 0); - const resp = await searchSource.fetch(); - const maxResultWindow = await this._documentSource.getMaxResultWindow(); - isSyncClustered = resp.hits.total > maxResultWindow; - syncContext.stopLoading(dataRequestId, requestToken, { isSyncClustered }, searchFilters); - } catch (error) { - if (!(error instanceof DataRequestAbortError)) { - syncContext.onLoadError(dataRequestId, requestToken, error.message); - } - return; - } let activeSource; let activeStyle; - if (isSyncClustered) { - activeSource = this._clusterSource; - activeStyle = this._clusterStyle; + if (canSkipFetch) { + // Even when source fetch is skipped, need to call super._syncData to sync StyleMeta and formatters + if (this._isClustered) { + activeSource = this._clusterSource; + activeStyle = this._clusterStyle; + } else { + activeSource = this._documentSource; + activeStyle = this._documentStyle; + } } else { - activeSource = this._documentSource; - activeStyle = this._documentStyle; + let isSyncClustered; + try { + syncContext.startLoading(dataRequestId, requestToken, searchFilters); + const searchSource = await this._documentSource.makeSearchSource(searchFilters, 0); + const resp = await searchSource.fetch(); + const maxResultWindow = await this._documentSource.getMaxResultWindow(); + isSyncClustered = resp.hits.total > maxResultWindow; + syncContext.stopLoading(dataRequestId, requestToken, { isSyncClustered }, searchFilters); + } catch (error) { + if (!(error instanceof DataRequestAbortError)) { + syncContext.onLoadError(dataRequestId, requestToken, error.message); + } + return; + } + if (isSyncClustered) { + activeSource = this._clusterSource; + activeStyle = this._clusterStyle; + } else { + activeSource = this._documentSource; + activeStyle = this._documentStyle; + } } super._syncData(syncContext, activeSource, activeStyle); diff --git a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts index 34f7dd4b9578f..4a3ac6390c5a7 100644 --- a/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/es_agg_field.ts @@ -125,8 +125,8 @@ export class ESAggField implements IESAggField { return this._esDocField ? this._esDocField.getOrdinalFieldMetaRequest() : null; } - async getCategoricalFieldMetaRequest(): Promise { - return this._esDocField ? this._esDocField.getCategoricalFieldMetaRequest() : null; + async getCategoricalFieldMetaRequest(size: number): Promise { + return this._esDocField ? this._esDocField.getCategoricalFieldMetaRequest(size) : null; } } diff --git a/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts b/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts index b7647d881fcf6..670b3ba32888b 100644 --- a/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts +++ b/x-pack/plugins/maps/public/layers/fields/es_doc_field.ts @@ -7,7 +7,6 @@ import { FIELD_ORIGIN } from '../../../common/constants'; import { ESTooltipProperty } from '../tooltips/es_tooltip_property'; import { ITooltipProperty, TooltipProperty } from '../tooltips/tooltip_property'; -import { COLOR_PALETTE_MAX_SIZE } from '../../../common/constants'; import { indexPatterns } from '../../../../../../src/plugins/data/public'; import { IFieldType } from '../../../../../../src/plugins/data/public'; import { IField, AbstractField } from './field'; @@ -89,16 +88,16 @@ export class ESDocField extends AbstractField implements IField { }; } - async getCategoricalFieldMetaRequest(): Promise { + async getCategoricalFieldMetaRequest(size: number): Promise { const indexPatternField = await this._getIndexPatternField(); - if (!indexPatternField) { + if (!indexPatternField || size <= 0) { return null; } // TODO remove local typing once Kibana has figured out a core place for Elasticsearch aggregation request types // https://github.com/elastic/kibana/issues/60102 const topTerms: { size: number; script?: unknown; field?: string } = { - size: COLOR_PALETTE_MAX_SIZE - 1, // need additional color for the "other"-value + size: size - 1, // need additional color for the "other"-value }; if (indexPatternField.scripted) { topTerms.script = { diff --git a/x-pack/plugins/maps/public/layers/fields/field.ts b/x-pack/plugins/maps/public/layers/fields/field.ts index b431be4aa6cb8..539d0ab4d6ade 100644 --- a/x-pack/plugins/maps/public/layers/fields/field.ts +++ b/x-pack/plugins/maps/public/layers/fields/field.ts @@ -19,7 +19,7 @@ export interface IField { getOrigin(): FIELD_ORIGIN; isValid(): boolean; getOrdinalFieldMetaRequest(): Promise; - getCategoricalFieldMetaRequest(): Promise; + getCategoricalFieldMetaRequest(size: number): Promise; } export class AbstractField implements IField { @@ -76,7 +76,7 @@ export class AbstractField implements IField { return null; } - async getCategoricalFieldMetaRequest(): Promise { + async getCategoricalFieldMetaRequest(size: number): Promise { return null; } } diff --git a/x-pack/plugins/maps/public/layers/styles/color_utils.js b/x-pack/plugins/maps/public/layers/styles/color_utils.js index 23b61b07bf871..ec90ea08adeae 100644 --- a/x-pack/plugins/maps/public/layers/styles/color_utils.js +++ b/x-pack/plugins/maps/public/layers/styles/color_utils.js @@ -9,7 +9,6 @@ import tinycolor from 'tinycolor2'; import chroma from 'chroma-js'; import { euiPaletteColorBlind } from '@elastic/eui/lib/services'; import { ColorGradient } from './components/color_gradient'; -import { COLOR_PALETTE_MAX_SIZE } from '../../../common/constants'; import { vislibColorMaps } from '../../../../../../src/plugins/charts/public'; const GRADIENT_INTERVALS = 8; @@ -120,7 +119,15 @@ export function getLinearGradient(colorStrings) { const COLOR_PALETTES_CONFIGS = [ { id: 'palette_0', - colors: DEFAULT_FILL_COLORS.slice(0, COLOR_PALETTE_MAX_SIZE), + colors: euiPaletteColorBlind(), + }, + { + id: 'palette_20', + colors: euiPaletteColorBlind(2), + }, + { + id: 'palette_30', + colors: euiPaletteColorBlind(3), }, ]; @@ -133,7 +140,7 @@ export const COLOR_PALETTES = COLOR_PALETTES_CONFIGS.map(palette => { const paletteDisplay = palette.colors.map(color => { const style = { backgroundColor: color, - width: '10%', + width: `${100 / palette.colors.length}%`, position: 'relative', height: '100%', display: 'inline-block', diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index e671f00b78381..0afc784c482c5 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -90,6 +90,11 @@ export class DynamicColorProperty extends DynamicStyleProperty { return this._options.type === COLOR_MAP_TYPE.CATEGORICAL; } + getNumberOfCategories() { + const colors = getColorPalette(this._options.colorCategory); + return colors ? colors.length : 0; + } + supportsMbFeatureState() { return true; } diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts index 72ca7def73908..b53623ab52edb 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.d.ts @@ -23,6 +23,7 @@ export interface IDynamicStyleProperty extends IStyleProperty { getFieldOrigin(): FIELD_ORIGIN | undefined; getRangeFieldMeta(): RangeFieldMeta; getCategoryFieldMeta(): CategoryFieldMeta; + getNumberOfCategories(): number; isFieldMetaEnabled(): boolean; isOrdinal(): boolean; supportsFieldMeta(): boolean; diff --git a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index 8cef78f9a8f21..451a79dd3864a 100644 --- a/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -7,12 +7,7 @@ import _ from 'lodash'; import { AbstractStyleProperty } from './style_property'; import { DEFAULT_SIGMA } from '../vector_style_defaults'; -import { - COLOR_PALETTE_MAX_SIZE, - STYLE_TYPE, - SOURCE_META_ID_ORIGIN, - FIELD_ORIGIN, -} from '../../../../../common/constants'; +import { STYLE_TYPE, SOURCE_META_ID_ORIGIN, FIELD_ORIGIN } from '../../../../../common/constants'; import React from 'react'; import { OrdinalLegend } from './components/ordinal_legend'; import { CategoricalLegend } from './components/categorical_legend'; @@ -120,6 +115,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty { return false; } + getNumberOfCategories() { + return 0; + } + hasOrdinalBreaks() { return false; } @@ -149,7 +148,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty { if (this.isOrdinal()) { return this._field.getOrdinalFieldMetaRequest(); } else if (this.isCategorical()) { - return this._field.getCategoricalFieldMetaRequest(); + return this._field.getCategoricalFieldMetaRequest(this.getNumberOfCategories()); } else { return null; } @@ -190,7 +189,8 @@ export class DynamicStyleProperty extends AbstractStyleProperty { } pluckCategoricalStyleMetaFromFeatures(features) { - if (!this.isCategorical()) { + const size = this.getNumberOfCategories(); + if (!this.isCategorical() || size <= 0) { return null; } @@ -217,7 +217,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty { ordered.sort((a, b) => { return b.count - a.count; }); - const truncated = ordered.slice(0, COLOR_PALETTE_MAX_SIZE); + const truncated = ordered.slice(0, size); return { categories: truncated, }; diff --git a/x-pack/plugins/maps/public/layers/vector_layer.js b/x-pack/plugins/maps/public/layers/vector_layer.js index 582e34bce2e98..74ddf11c6beb4 100644 --- a/x-pack/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/plugins/maps/public/layers/vector_layer.js @@ -464,7 +464,7 @@ export class VectorLayer extends AbstractLayer { } const dynamicStyleFields = dynamicStyleProps.map(dynamicStyleProp => { - return dynamicStyleProp.getField().getName(); + return `${dynamicStyleProp.getField().getName()}${dynamicStyleProp.getNumberOfCategories()}`; }); const nextMeta = {