mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[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 <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
1bb1091abe
commit
f2d1095d46
10 changed files with 63 additions and 46 deletions
|
@ -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'];
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -125,8 +125,8 @@ export class ESAggField implements IESAggField {
|
|||
return this._esDocField ? this._esDocField.getOrdinalFieldMetaRequest() : null;
|
||||
}
|
||||
|
||||
async getCategoricalFieldMetaRequest(): Promise<unknown> {
|
||||
return this._esDocField ? this._esDocField.getCategoricalFieldMetaRequest() : null;
|
||||
async getCategoricalFieldMetaRequest(size: number): Promise<unknown> {
|
||||
return this._esDocField ? this._esDocField.getCategoricalFieldMetaRequest(size) : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<unknown> {
|
||||
async getCategoricalFieldMetaRequest(size: number): Promise<unknown> {
|
||||
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 = {
|
||||
|
|
|
@ -19,7 +19,7 @@ export interface IField {
|
|||
getOrigin(): FIELD_ORIGIN;
|
||||
isValid(): boolean;
|
||||
getOrdinalFieldMetaRequest(): Promise<unknown>;
|
||||
getCategoricalFieldMetaRequest(): Promise<unknown>;
|
||||
getCategoricalFieldMetaRequest(size: number): Promise<unknown>;
|
||||
}
|
||||
|
||||
export class AbstractField implements IField {
|
||||
|
@ -76,7 +76,7 @@ export class AbstractField implements IField {
|
|||
return null;
|
||||
}
|
||||
|
||||
async getCategoricalFieldMetaRequest(): Promise<unknown> {
|
||||
async getCategoricalFieldMetaRequest(size: number): Promise<unknown> {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue