[Maps] label zoom range style property (#136690)

* [Maps] label visibility style property

* add slider

* set label zoom range

* rename

* fix jest test

* tslint

* fix jest tests

* update jest expects

* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'

* doc updates and change 'Label zoom range' to 'Label visibility'

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2022-07-25 10:04:11 -06:00 committed by GitHub
parent 3d62cc3201
commit 8bedc3c980
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 331 additions and 513 deletions

View file

@ -14,6 +14,8 @@ You can add text labels to your Point features by configuring label style proper
|===
|*Label*
|Specifies label content.
|*Label visibility*
|Specifies the zoom range for which labels are displayed.
|*Label color*
|The text color.
|*Label size*
@ -83,6 +85,8 @@ Manage your custom icons in <<maps-settings, Map settings>>.
|The fill color of the polygon features.
|*Label*
|Specifies label content. For polygons, the label is positioned at the polygon centroid. For multi-polygons, the label is positioned at the largest polygon centroid.
|*Label visibility*
|Specifies the zoom range for which labels are displayed.
|*Label color*
|The text color.
|*Label size*
@ -106,6 +110,8 @@ Manage your custom icons in <<maps-settings, Map settings>>.
|The width of the line features.
|*Label*
|Specifies label content. For lines, the label is positioned at the center of the line. For multi-lines, the label is positioned at the center of the longest line.
|*Label visibility*
|Specifies the zoom range for which labels are displayed.
|*Label color*
|The text color.
|*Label size*

View file

@ -241,6 +241,7 @@ export enum VECTOR_STYLES {
ICON_SIZE = 'iconSize',
ICON_ORIENTATION = 'iconOrientation',
LABEL_TEXT = 'labelText',
LABEL_ZOOM_RANGE = 'labelZoomRange',
LABEL_COLOR = 'labelColor',
LABEL_SIZE = 'labelSize',
LABEL_BORDER_COLOR = 'labelBorderColor',

View file

@ -35,6 +35,14 @@ export type LabelBorderSizeStylePropertyDescriptor = {
options: LabelBorderSizeOptions;
};
export type LabelZoomRangeStylePropertyDescriptor = {
options: {
useLayerZoomRange: boolean;
minZoom: number;
maxZoom: number;
};
};
// Static/dynamic options
export type FieldMetaOptions = {
@ -200,6 +208,7 @@ export type VectorStylePropertiesDescriptor = {
[VECTOR_STYLES.ICON_SIZE]: SizeStylePropertyDescriptor;
[VECTOR_STYLES.ICON_ORIENTATION]: OrientationStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_TEXT]: LabelStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_ZOOM_RANGE]: LabelZoomRangeStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_COLOR]: ColorStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_SIZE]: SizeStylePropertyDescriptor;
[VECTOR_STYLES.LABEL_BORDER_COLOR]: ColorStylePropertyDescriptor;
@ -262,6 +271,7 @@ export type EMSVectorTileStyleDescriptor = StyleDescriptor & {
export type StylePropertyOptions =
| LabelBorderSizeOptions
| LabelZoomRangeStylePropertyDescriptor['options']
| SymbolizeAsOptions
| DynamicStylePropertyOptions
| StaticStylePropertyOptions;

View file

@ -110,7 +110,14 @@ describe('isInitialDataLoadComplete', () => {
layerDescriptor: {
__dataRequests: [sourceDataRequestDescriptor],
} as unknown as VectorLayerDescriptor,
source: {} as unknown as IVectorSource,
source: {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorSource,
});
expect(layer.isInitialDataLoadComplete()).toBe(false);
});
@ -122,7 +129,14 @@ describe('isInitialDataLoadComplete', () => {
__areTilesLoaded: false,
__dataRequests: [sourceDataRequestDescriptor],
} as unknown as VectorLayerDescriptor,
source: {} as unknown as IVectorSource,
source: {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorSource,
});
expect(layer.isInitialDataLoadComplete()).toBe(false);
});
@ -134,7 +148,14 @@ describe('isInitialDataLoadComplete', () => {
__areTilesLoaded: true,
__dataRequests: [sourceDataRequestDescriptor],
} as unknown as VectorLayerDescriptor,
source: {} as unknown as IVectorSource,
source: {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorSource,
});
expect(layer.isInitialDataLoadComplete()).toBe(true);
});
@ -163,7 +184,14 @@ describe('isInitialDataLoadComplete', () => {
},
],
} as unknown as VectorLayerDescriptor,
source: {} as unknown as IVectorSource,
source: {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorSource,
});
expect(layer.isInitialDataLoadComplete()).toBe(false);
});
@ -194,7 +222,14 @@ describe('isInitialDataLoadComplete', () => {
},
],
} as unknown as VectorLayerDescriptor,
source: {} as unknown as IVectorSource,
source: {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorSource,
});
expect(layer.isInitialDataLoadComplete()).toBe(true);
});

View file

@ -861,7 +861,6 @@ export class AbstractVectorLayer extends AbstractLayer implements IVectorLayer {
});
this.syncVisibilityWithMb(mbMap, labelLayerId);
mbMap.setLayerZoomRange(labelLayerId, this.getMinZoom(), this.getMaxZoom());
}
_getMbPointLayerId() {

View file

@ -6,6 +6,7 @@
*/
import { emsWorldLayerId } from '../../../../../../common/constants';
import { getDefaultStaticProperties } from '../../../../styles/vector/vector_style_defaults';
jest.mock('../../../../../kibana_services', () => {
return {
@ -82,6 +83,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: 'Green to Red',
@ -98,70 +100,12 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 6,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#3d3d3d',
},
type: 'STATIC',
},
lineWidth: {
options: {
size: 1,
},
type: 'STATIC',
},
symbolizeAs: {
options: {
value: 'circle',
},
},
},
type: 'VECTOR',
},
@ -253,6 +197,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: 'Green to Red',
@ -269,18 +214,6 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
field: {
@ -296,52 +229,12 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#3d3d3d',
},
type: 'STATIC',
},
lineWidth: {
options: {
size: 1,
},
type: 'STATIC',
},
symbolizeAs: {
options: {
value: 'circle',
},
},
},
type: 'VECTOR',
},

View file

@ -5,6 +5,8 @@
* 2.0.
*/
import { getDefaultStaticProperties } from '../../../../styles/vector/vector_style_defaults';
jest.mock('../../../../../kibana_services', () => {
return {
getIsDarkMode() {
@ -65,6 +67,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#6092C0',
@ -77,47 +80,12 @@ describe('createLayerDescriptor', () => {
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -175,6 +143,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#D36086',
@ -187,47 +156,12 @@ describe('createLayerDescriptor', () => {
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -283,59 +217,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
fillColor: {
options: {
color: '#54B399',
},
type: 'STATIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 6,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
...getDefaultStaticProperties(),
lineColor: {
options: {
color: '#6092C0',
@ -357,11 +239,6 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
symbolizeAs: {
options: {
value: 'circle',
},
},
},
type: 'VECTOR',
},
@ -407,6 +284,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#6092C0',
@ -419,47 +297,12 @@ describe('createLayerDescriptor', () => {
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -517,59 +360,19 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#D36086',
},
type: 'STATIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -625,59 +428,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
fillColor: {
options: {
color: '#54B399',
},
type: 'STATIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 6,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
...getDefaultStaticProperties(),
lineColor: {
options: {
color: '#6092C0',
@ -699,11 +450,6 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
symbolizeAs: {
options: {
value: 'circle',
},
},
},
type: 'VECTOR',
},
@ -749,6 +495,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#6092C0',
@ -761,47 +508,12 @@ describe('createLayerDescriptor', () => {
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -859,59 +571,19 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
...getDefaultStaticProperties(),
fillColor: {
options: {
color: '#D36086',
},
type: 'STATIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 8,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
lineColor: {
options: {
color: '#FFFFFF',
@ -967,59 +639,7 @@ describe('createLayerDescriptor', () => {
style: {
isTimeAware: true,
properties: {
fillColor: {
options: {
color: '#54B399',
},
type: 'STATIC',
},
icon: {
options: {
value: 'marker',
},
type: 'STATIC',
},
iconOrientation: {
options: {
orientation: 0,
},
type: 'STATIC',
},
iconSize: {
options: {
size: 6,
},
type: 'STATIC',
},
labelBorderColor: {
options: {
color: '#FFFFFF',
},
type: 'STATIC',
},
labelBorderSize: {
options: {
size: 'SMALL',
},
},
labelColor: {
options: {
color: '#000000',
},
type: 'STATIC',
},
labelSize: {
options: {
size: 14,
},
type: 'STATIC',
},
labelText: {
options: {
value: '',
},
type: 'STATIC',
},
...getDefaultStaticProperties(),
lineColor: {
options: {
color: '#6092C0',
@ -1041,11 +661,6 @@ describe('createLayerDescriptor', () => {
},
type: 'DYNAMIC',
},
symbolizeAs: {
options: {
value: 'circle',
},
},
},
type: 'VECTOR',
},

View file

@ -193,6 +193,26 @@ exports[`should render 1`] = `
<EuiSpacer
size="m"
/>
<LabelZoomRangeEditor
disabled={true}
disabledBy="labelText"
handlePropertyChange={[Function]}
styleProperty={
LabelZoomRangeProperty {
"_layerMaxZoom": 24,
"_layerMinZoom": 0,
"_options": Object {
"maxZoom": 24,
"minZoom": 0,
"useLayerZoomRange": true,
},
"_styleName": "labelZoomRange",
}
}
/>
<EuiSpacer
size="m"
/>
<VectorStyleColorEditor
defaultDynamicStyleOptions={
Object {
@ -549,6 +569,26 @@ exports[`should render with no style fields 1`] = `
<EuiSpacer
size="m"
/>
<LabelZoomRangeEditor
disabled={true}
disabledBy="labelText"
handlePropertyChange={[Function]}
styleProperty={
LabelZoomRangeProperty {
"_layerMaxZoom": 24,
"_layerMinZoom": 0,
"_options": Object {
"maxZoom": 24,
"minZoom": 0,
"useLayerZoomRange": true,
},
"_styleName": "labelZoomRange",
}
}
/>
<EuiSpacer
size="m"
/>
<VectorStyleColorEditor
defaultDynamicStyleOptions={
Object {

View file

@ -46,6 +46,10 @@ export function getVectorStyleLabel(styleName: VECTOR_STYLES) {
return i18n.translate('xpack.maps.styles.vector.labelLabel', {
defaultMessage: 'Label',
});
case VECTOR_STYLES.LABEL_ZOOM_RANGE:
return i18n.translate('xpack.maps.styles.vector.labelZoomRangeLabel', {
defaultMessage: 'Label visibility',
});
case VECTOR_STYLES.LABEL_COLOR:
return i18n.translate('xpack.maps.styles.vector.labelColorLabel', {
defaultMessage: 'Label color',

View file

@ -0,0 +1,99 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiForm, EuiFormRow, EuiSwitch, EuiSwitchEvent, EuiToolTip } from '@elastic/eui';
import { ValidatedDualRange } from '@kbn/kibana-react-plugin/public';
import { LabelZoomRangeStylePropertyDescriptor } from '../../../../../../common/descriptor_types';
import { VECTOR_STYLES } from '../../../../../../common/constants';
import { getVectorStyleLabel, getDisabledByMessage } from '../get_vector_style_label';
import { LabelZoomRangeProperty } from '../../properties/label_zoom_range_property';
interface Props {
disabled: boolean;
disabledBy: VECTOR_STYLES;
handlePropertyChange: (
propertyName: VECTOR_STYLES,
stylePropertyDescriptor: LabelZoomRangeStylePropertyDescriptor
) => void;
styleProperty: LabelZoomRangeProperty;
}
export function LabelZoomRangeEditor(props: Props) {
const layerZoomRange = props.styleProperty.getLayerZoomRange();
const labelZoomRange = props.styleProperty.getLabelZoomRange();
const onSwitchChange = (event: EuiSwitchEvent) => {
props.handlePropertyChange(props.styleProperty.getStyleName(), {
options: {
...props.styleProperty.getOptions(),
useLayerZoomRange: event.target.checked,
},
});
};
const onZoomChange = (value: [string, string]) => {
props.handlePropertyChange(props.styleProperty.getStyleName(), {
options: {
...props.styleProperty.getOptions(),
minZoom: Math.max(layerZoomRange.minZoom, parseInt(value[0], 10)),
maxZoom: Math.min(layerZoomRange.maxZoom, parseInt(value[1], 10)),
},
});
};
const { useLayerZoomRange } = props.styleProperty.getOptions();
const slider = useLayerZoomRange ? null : (
<EuiFormRow hasEmptyLabelSpace={true}>
<ValidatedDualRange
formRowDisplay="columnCompressed"
min={layerZoomRange.minZoom}
max={layerZoomRange.maxZoom}
value={[labelZoomRange.minZoom, labelZoomRange.maxZoom]}
showInput="inputWithPopover"
showRange
showLabels
onChange={onZoomChange}
allowEmptyRange={false}
compressed
prepend={i18n.translate('xpack.maps.styles.labelZoomRange.visibleZoom', {
defaultMessage: 'Zoom levels',
})}
/>
</EuiFormRow>
);
const form = (
<EuiForm>
<EuiFormRow label={getVectorStyleLabel(props.styleProperty.getStyleName())}>
<EuiSwitch
label={i18n.translate('xpack.maps.styles.labelZoomRange.useLayerZoomLabel', {
defaultMessage: 'Use layer visibility',
})}
checked={useLayerZoomRange}
onChange={onSwitchChange}
compressed
/>
</EuiFormRow>
{slider}
</EuiForm>
);
if (!props.disabled) {
return form;
}
return (
<EuiToolTip
anchorClassName="mapStyleFormDisabledTooltip"
content={getDisabledByMessage(props.disabledBy)}
>
{form}
</EuiToolTip>
);
}

View file

@ -65,7 +65,14 @@ const vectorStyleDescriptor = {
const vectorStyle = new VectorStyle(
vectorStyleDescriptor,
{} as unknown as IVectorSource,
{} as unknown as IVectorLayer,
{
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
} as unknown as IVectorLayer,
[] as CustomIcon[]
);
const styleProperties: StyleProperties = {};

View file

@ -16,6 +16,7 @@ import { VectorStyleSizeEditor } from './size/vector_style_size_editor';
import { VectorStyleSymbolizeAsEditor } from './symbol/vector_style_symbolize_as_editor';
import { VectorStyleIconEditor } from './symbol/vector_style_icon_editor';
import { VectorStyleLabelEditor } from './label/vector_style_label_editor';
import { LabelZoomRangeEditor } from './label/label_zoom_range_editor';
// @ts-expect-error
import { VectorStyleLabelBorderSizeEditor } from './label/vector_style_label_border_size_editor';
// @ts-expect-error
@ -51,6 +52,7 @@ import { LabelBorderSizeProperty } from '../properties/label_border_size_propert
import { StaticTextProperty } from '../properties/static_text_property';
import { DynamicTextProperty } from '../properties/dynamic_text_property';
import { StaticSizeProperty } from '../properties/static_size_property';
import { LabelZoomRangeProperty } from '../properties/label_zoom_range_property';
import { IVectorLayer } from '../../../layers/vector_layer';
import { getHasLabel } from '../style_util';
@ -304,6 +306,16 @@ export class VectorStyleEditor extends Component<Props, State> {
/>
<EuiSpacer size="m" />
<LabelZoomRangeEditor
disabled={!hasLabel}
disabledBy={VECTOR_STYLES.LABEL_TEXT}
handlePropertyChange={this.props.handlePropertyChange}
styleProperty={
this.props.styleProperties[VECTOR_STYLES.LABEL_ZOOM_RANGE] as LabelZoomRangeProperty
}
/>
<EuiSpacer size="m" />
<VectorStyleColorEditor
disabled={!hasLabel}
disabledBy={VECTOR_STYLES.LABEL_TEXT}

View file

@ -0,0 +1,51 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { Map as MbMap } from '@kbn/mapbox-gl';
import { AbstractStyleProperty } from './style_property';
import { LabelZoomRangeStylePropertyDescriptor } from '../../../../../common/descriptor_types';
import { VECTOR_STYLES } from '../../../../../common/constants';
export class LabelZoomRangeProperty extends AbstractStyleProperty<
LabelZoomRangeStylePropertyDescriptor['options']
> {
private readonly _layerMinZoom: number;
private readonly _layerMaxZoom: number;
constructor(
options: LabelZoomRangeStylePropertyDescriptor['options'],
styleName: VECTOR_STYLES,
layerMinZoom: number,
layerMaxZoom: number
) {
super(options, styleName);
this._layerMinZoom = layerMinZoom;
this._layerMaxZoom = layerMaxZoom;
}
syncLabelZoomRange(mbLayerId: string, mbMap: MbMap) {
const { maxZoom, minZoom } = this.getLabelZoomRange();
mbMap.setLayerZoomRange(mbLayerId, minZoom, maxZoom);
}
getLayerZoomRange() {
return {
maxZoom: this._layerMaxZoom,
minZoom: this._layerMinZoom,
};
}
getLabelZoomRange() {
const { useLayerZoomRange, maxZoom, minZoom } = this.getOptions();
return useLayerZoomRange
? this.getLayerZoomRange()
: {
maxZoom: Math.min(this._layerMaxZoom, maxZoom),
minZoom: Math.max(this._layerMinZoom, minZoom),
};
}
}

View file

@ -35,6 +35,12 @@ describe('getDescriptorWithUpdatedStyleProps', () => {
const previousFieldName = 'doIStillExist';
const mapColors = [];
const layer = {
getMaxZoom: () => {
return 24;
},
getMinZoom: () => {
return 0;
},
getSource: () => {
return {
isMvt: () => {

View file

@ -40,6 +40,7 @@ import { StaticOrientationProperty } from './properties/static_orientation_prope
import { DynamicOrientationProperty } from './properties/dynamic_orientation_property';
import { StaticTextProperty } from './properties/static_text_property';
import { DynamicTextProperty } from './properties/dynamic_text_property';
import { LabelZoomRangeProperty } from './properties/label_zoom_range_property';
import { LabelBorderSizeProperty } from './properties/label_border_size_property';
import { extractColorFromStyleProperty } from './components/legend/extract_color_from_style_property';
import { SymbolizeAsProperty } from './properties/symbolize_as_property';
@ -178,6 +179,7 @@ export class VectorStyle implements IVectorStyle {
private readonly _iconSizeStyleProperty: StaticSizeProperty | DynamicSizeProperty;
private readonly _iconOrientationProperty: StaticOrientationProperty | DynamicOrientationProperty;
private readonly _labelStyleProperty: StaticTextProperty | DynamicTextProperty;
private readonly _labelZoomRangeProperty: LabelZoomRangeProperty;
private readonly _labelSizeStyleProperty: StaticSizeProperty | DynamicSizeProperty;
private readonly _labelColorStyleProperty: StaticColorProperty | DynamicColorProperty;
private readonly _labelBorderColorStyleProperty: StaticColorProperty | DynamicColorProperty;
@ -251,6 +253,12 @@ export class VectorStyle implements IVectorStyle {
this._labelStyleProperty = this._makeLabelProperty(
this._descriptor.properties[VECTOR_STYLES.LABEL_TEXT]
);
this._labelZoomRangeProperty = new LabelZoomRangeProperty(
this._descriptor.properties[VECTOR_STYLES.LABEL_ZOOM_RANGE].options,
VECTOR_STYLES.LABEL_ZOOM_RANGE,
layer.getMinZoom(),
layer.getMaxZoom()
);
this._labelSizeStyleProperty = this._makeSizeProperty(
this._descriptor.properties[VECTOR_STYLES.LABEL_SIZE],
VECTOR_STYLES.LABEL_SIZE,
@ -460,6 +468,7 @@ export class VectorStyle implements IVectorStyle {
this._iconSizeStyleProperty,
this._iconOrientationProperty,
this._labelStyleProperty,
this._labelZoomRangeProperty,
this._labelSizeStyleProperty,
this._labelColorStyleProperty,
this._labelBorderColorStyleProperty,
@ -823,6 +832,7 @@ export class VectorStyle implements IVectorStyle {
textLayerId: string;
}) {
this._labelStyleProperty.syncTextFieldWithMb(textLayerId, mbMap);
this._labelZoomRangeProperty.syncLabelZoomRange(textLayerId, mbMap);
this._labelColorStyleProperty.syncLabelColorWithMb(textLayerId, mbMap, alpha);
this._labelSizeStyleProperty.syncLabelSizeWithMb(textLayerId, mbMap);
this._labelBorderSizeStyleProperty.syncLabelBorderSizeWithMb(textLayerId, mbMap);

View file

@ -8,10 +8,13 @@
import {
DEFAULT_ICON,
LABEL_BORDER_SIZES,
MAX_ZOOM,
MIN_ZOOM,
SYMBOLIZE_AS_TYPES,
VECTOR_STYLES,
STYLE_TYPE,
} from '../../../../common/constants';
import {
DEFAULT_FILL_COLORS,
DEFAULT_LINE_COLORS,
@ -115,6 +118,13 @@ export function getDefaultStaticProperties(
size: DEFAULT_LABEL_SIZE,
},
},
[VECTOR_STYLES.LABEL_ZOOM_RANGE]: {
options: {
useLayerZoomRange: true,
minZoom: MIN_ZOOM,
maxZoom: MAX_ZOOM,
},
},
[VECTOR_STYLES.LABEL_BORDER_COLOR]: {
type: STYLE_TYPE.STATIC,
options: {
@ -210,6 +220,13 @@ export function getDefaultDynamicProperties(): VectorStylePropertiesDescriptor {
field: undefined,
},
},
[VECTOR_STYLES.LABEL_ZOOM_RANGE]: {
options: {
useLayerZoomRange: true,
minZoom: MIN_ZOOM,
maxZoom: MAX_ZOOM,
},
},
[VECTOR_STYLES.LABEL_COLOR]: {
type: STYLE_TYPE.DYNAMIC,
options: {

View file

@ -68,6 +68,9 @@ export const mockLayerList = [
labelColor: { type: 'STATIC', options: { color: '#000000' } },
labelSize: { type: 'STATIC', options: { size: 14 } },
labelBorderColor: { type: 'STATIC', options: { color: '#FFFFFF' } },
labelZoomRange: {
options: { maxZoom: 24, minZoom: 0, useLayerZoomRange: true },
},
symbolizeAs: { options: { value: 'circle' } },
labelBorderSize: { options: { size: 'SMALL' } },
},
@ -137,6 +140,9 @@ export const mockLayerList = [
labelColor: { type: 'STATIC', options: { color: '#000000' } },
labelSize: { type: 'STATIC', options: { size: 14 } },
labelBorderColor: { type: 'STATIC', options: { color: '#FFFFFF' } },
labelZoomRange: {
options: { maxZoom: 24, minZoom: 0, useLayerZoomRange: true },
},
symbolizeAs: { options: { value: 'circle' } },
labelBorderSize: { options: { size: 'SMALL' } },
},

View file

@ -120,6 +120,13 @@ export function useLayerList() {
options: { orientation: 0 },
},
labelText: { type: STYLE_TYPE.STATIC, options: { value: '' } },
labelZoomRange: {
options: {
useLayerZoomRange: true,
minZoom: 0,
maxZoom: 24,
},
},
labelColor: {
type: STYLE_TYPE.STATIC,
options: { color: '#000000' },