Skip to content

Commit b2df052

Browse files
[Maps] Get number of categories from palette (elastic#66454)
1 parent 915ff5d commit b2df052

File tree

8 files changed

+225
-60
lines changed

8 files changed

+225
-60
lines changed

x-pack/plugins/maps/common/descriptor_types/descriptor_types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export type JoinDescriptor = {
115115
// todo : this union type is incompatible with dynamic extensibility of sources.
116116
// Reconsider using SourceDescriptor in type signatures for top-level classes
117117
export type SourceDescriptor =
118+
| AbstractSourceDescriptor
118119
| XYZTMSSourceDescriptor
119120
| WMSSourceDescriptor
120121
| KibanaTilemapSourceDescriptor

x-pack/plugins/maps/public/classes/fields/field.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export interface IField {
2020
isValid(): boolean;
2121
getOrdinalFieldMetaRequest(): Promise<unknown>;
2222
getCategoricalFieldMetaRequest(size: number): Promise<unknown>;
23+
supportsFieldMeta(): boolean;
2324
}
2425

2526
export class AbstractField implements IField {

x-pack/plugins/maps/public/classes/styles/vector/properties/__snapshots__/dynamic_icon_property.test.tsx.snap

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
// eslint-disable-next-line max-classes-per-file
8+
import { FIELD_ORIGIN } from '../../../../../../common/constants';
9+
import { StyleMeta } from '../../style_meta';
10+
import {
11+
CategoryFieldMeta,
12+
GeometryTypes,
13+
RangeFieldMeta,
14+
StyleMetaDescriptor,
15+
} from '../../../../../../common/descriptor_types';
16+
import { AbstractField, IField } from '../../../../fields/field';
17+
18+
class MockField extends AbstractField {
19+
async getLabel(): Promise<string> {
20+
return this.getName() + '_label';
21+
}
22+
supportsFieldMeta(): boolean {
23+
return true;
24+
}
25+
}
26+
27+
export const mockField: IField = new MockField({
28+
fieldName: 'foobar',
29+
origin: FIELD_ORIGIN.SOURCE,
30+
});
31+
32+
class MockStyle {
33+
getStyleMeta(): StyleMeta {
34+
const geomTypes: GeometryTypes = {
35+
isPointsOnly: false,
36+
isLinesOnly: false,
37+
isPolygonsOnly: false,
38+
};
39+
const rangeFieldMeta: RangeFieldMeta = { min: 0, max: 100, delta: 100 };
40+
const catFieldMeta: CategoryFieldMeta = {
41+
categories: [
42+
{
43+
key: 'US',
44+
count: 10,
45+
},
46+
{
47+
key: 'CN',
48+
count: 8,
49+
},
50+
],
51+
};
52+
53+
const styleMetaDescriptor: StyleMetaDescriptor = {
54+
geometryTypes: geomTypes,
55+
fieldMeta: {
56+
foobar: {
57+
range: rangeFieldMeta,
58+
categories: catFieldMeta,
59+
},
60+
},
61+
};
62+
63+
return new StyleMeta(styleMetaDescriptor);
64+
}
65+
}
66+
67+
export class MockLayer {
68+
getStyle() {
69+
return new MockStyle();
70+
}
71+
72+
getDataRequest() {
73+
return null;
74+
}
75+
}

x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.test.js

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,65 +15,8 @@ import React from 'react';
1515
import { shallow } from 'enzyme';
1616

1717
import { DynamicColorProperty } from './dynamic_color_property';
18-
import { StyleMeta } from '../style_meta';
19-
import { COLOR_MAP_TYPE, FIELD_ORIGIN, VECTOR_STYLES } from '../../../../../common/constants';
20-
21-
const mockField = {
22-
async getLabel() {
23-
return 'foobar_label';
24-
},
25-
getName() {
26-
return 'foobar';
27-
},
28-
getRootName() {
29-
return 'foobar';
30-
},
31-
getOrigin() {
32-
return FIELD_ORIGIN.SOURCE;
33-
},
34-
supportsFieldMeta() {
35-
return true;
36-
},
37-
};
38-
39-
class MockStyle {
40-
getStyleMeta() {
41-
return new StyleMeta({
42-
geometryTypes: {
43-
isPointsOnly: false,
44-
isLinesOnly: false,
45-
isPolygonsOnly: false,
46-
},
47-
fieldMeta: {
48-
foobar: {
49-
range: { min: 0, max: 100 },
50-
categories: {
51-
categories: [
52-
{
53-
key: 'US',
54-
count: 10,
55-
},
56-
{
57-
key: 'CN',
58-
count: 8,
59-
},
60-
],
61-
},
62-
},
63-
},
64-
});
65-
}
66-
}
67-
68-
class MockLayer {
69-
getStyle() {
70-
return new MockStyle();
71-
}
72-
73-
getDataRequest() {
74-
return null;
75-
}
76-
}
18+
import { COLOR_MAP_TYPE, VECTOR_STYLES } from '../../../../../common/constants';
19+
import { mockField, MockLayer } from './__tests__/test_util';
7720

7821
const makeProperty = (options, field = mockField) => {
7922
return new DynamicColorProperty(options, VECTOR_STYLES.LINE_COLOR, field, new MockLayer(), () => {

x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_icon_property.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export class DynamicIconProperty extends DynamicStyleProperty {
2929
return true;
3030
}
3131

32+
getNumberOfCategories() {
33+
const palette = getIconPalette(this._options.iconPaletteId);
34+
return palette ? palette.length : 0;
35+
}
36+
3237
syncIconWithMb(symbolLayerId, mbMap, iconPixelSize) {
3338
if (this._isIconDynamicConfigComplete()) {
3439
mbMap.setLayoutProperty(
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
// eslint-disable-next-line max-classes-per-file
8+
import { shallow } from 'enzyme';
9+
10+
jest.mock('ui/new_platform');
11+
jest.mock('../components/vector_style_editor', () => ({
12+
VectorStyleEditor: () => {
13+
return <div>mockVectorStyleEditor</div>;
14+
},
15+
}));
16+
17+
import React from 'react';
18+
import { VECTOR_STYLES } from '../../../../../common/constants';
19+
// @ts-ignore
20+
import { DynamicIconProperty } from './dynamic_icon_property';
21+
import { mockField, MockLayer } from './__tests__/test_util';
22+
import { IconDynamicOptions } from '../../../../../common/descriptor_types';
23+
import { IField } from '../../../fields/field';
24+
25+
const makeProperty = (options: Partial<IconDynamicOptions>, field: IField = mockField) => {
26+
return new DynamicIconProperty(
27+
{ ...options, fieldMetaOptions: { isEnabled: false } },
28+
VECTOR_STYLES.ICON,
29+
field,
30+
new MockLayer(),
31+
() => {
32+
return (x: string) => x + '_format';
33+
}
34+
);
35+
};
36+
37+
describe('DynamicIconProperty', () => {
38+
it('should derive category number from palettes', async () => {
39+
const filled = makeProperty({
40+
iconPaletteId: 'filledShapes',
41+
});
42+
expect(filled.getNumberOfCategories()).toEqual(6);
43+
const hollow = makeProperty({
44+
iconPaletteId: 'hollowShapes',
45+
});
46+
expect(hollow.getNumberOfCategories()).toEqual(5);
47+
});
48+
});
49+
50+
test('Should render categorical legend with breaks', async () => {
51+
const iconStyle = makeProperty({
52+
iconPaletteId: 'filledShapes',
53+
});
54+
55+
const legendRow = iconStyle.renderLegendDetailRow({ isPointsOnly: true, isLinesOnly: false });
56+
const component = shallow(legendRow);
57+
await new Promise(resolve => process.nextTick(resolve));
58+
component.update();
59+
60+
expect(component).toMatchSnapshot();
61+
});

x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_style_property.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
148148
if (this.isOrdinal()) {
149149
return this._field.getOrdinalFieldMetaRequest();
150150
} else if (this.isCategorical()) {
151-
return this._field.getCategoricalFieldMetaRequest(this.getNumberOfCategories());
151+
const numberOfCategories = this.getNumberOfCategories();
152+
return this._field.getCategoricalFieldMetaRequest(numberOfCategories);
152153
} else {
153154
return null;
154155
}

0 commit comments

Comments
 (0)