mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* text styling * label style editor UI * wire up styles to mb * allow string values * remove console.log * default getFields to provide ordinal fields for vector source * fix vector_style jest test * add label styles to docs * fix prettier errors * use index-pattern field formatter to format label * rename LABEL to LABEL_TEXT * review feedback * fix problem with icons not displaying with labels * fix functional tests * fix canno read name of null error * update jest expect * fix eslint errors * do not display label text in legend * always show all label styling properties in editor * review feedback
This commit is contained in:
parent
c620d11d72
commit
2055347fc7
28 changed files with 554 additions and 105 deletions
|
@ -8,32 +8,52 @@ Point, polygon, and line features support different styling properties.
|
|||
[[point-style-properties]]
|
||||
==== Point style properties
|
||||
|
||||
You can add text labels to your Point features by configuring label style properties.
|
||||
|
||||
[cols="2*"]
|
||||
|===
|
||||
|*Label*
|
||||
|Specifies label content.
|
||||
|*Label color*
|
||||
|The text color.
|
||||
|*Label size*
|
||||
|The size of the text font, in pixels.
|
||||
|===
|
||||
|
||||
You can symbolize Point features as *Circle markers* or *Icons*.
|
||||
|
||||
Use *Circle marker* to symbolize Points as circles.
|
||||
|
||||
*Fill color*:: The fill color of the point features.
|
||||
|
||||
*Border color*:: The border color of the point features.
|
||||
|
||||
*Border width*:: The border width of the point features.
|
||||
|
||||
*Symbol size*:: The radius of the symbol size, in pixels.
|
||||
[cols="2*"]
|
||||
|===
|
||||
|*Border color*
|
||||
|The border color of the point features.
|
||||
|*Border width*
|
||||
|The border width of the point features.
|
||||
|*Fill color*
|
||||
|The fill color of the point features.
|
||||
|*Symbol size*
|
||||
|The radius of the symbol size, in pixels.
|
||||
|===
|
||||
|
||||
Use *Icon* to symbolize Points as icons.
|
||||
|
||||
*Fill color*:: The fill color of the point features.
|
||||
[cols="2*"]
|
||||
|===
|
||||
|*Border color*
|
||||
|The border color of the point features.
|
||||
|*Border width*
|
||||
|The border width of the point features.
|
||||
|*Fill color*
|
||||
|The fill color of the point features.
|
||||
|*Symbol orientation*
|
||||
|The symbol orientation rotating the icon clockwise.
|
||||
|*Symbol size*
|
||||
|The radius of the symbol size, in pixels.
|
||||
|===
|
||||
|
||||
*Border color*:: The border color of the point features.
|
||||
|
||||
*Border width*:: The border width of the point features.
|
||||
|
||||
*Symbol orientation*:: The symbol orientation rotating the icon clockwise.
|
||||
|
||||
*Symbol size*:: The radius of the symbol size, in pixels.
|
||||
+
|
||||
Available icons
|
||||
+
|
||||
|
||||
[role="screenshot"]
|
||||
image::maps/images/maki-icons.png[]
|
||||
|
||||
|
@ -42,17 +62,25 @@ image::maps/images/maki-icons.png[]
|
|||
[[polygon-style-properties]]
|
||||
==== Polygon style properties
|
||||
|
||||
*Fill color*:: The fill color of the polygon features.
|
||||
|
||||
*Border color*:: The border color of the polygon features.
|
||||
|
||||
*Border width*:: The border width of the polygon features.
|
||||
[cols="2*"]
|
||||
|===
|
||||
|*Border color*
|
||||
|The border color of the polygon features.
|
||||
|*Border width*
|
||||
|The border width of the polygon features.
|
||||
|*Fill color*
|
||||
|The fill color of the polygon features.
|
||||
|===
|
||||
|
||||
|
||||
[float]
|
||||
[[line-style-properties]]
|
||||
==== Line style properties
|
||||
|
||||
*Border color*:: The color of the line features.
|
||||
|
||||
*Border width*:: The width of the line features.
|
||||
[cols="2*"]
|
||||
|===
|
||||
|*Border color*
|
||||
|The color of the line features.
|
||||
|*Border width*
|
||||
|The width of the line features.
|
||||
|===
|
||||
|
|
|
@ -344,6 +344,10 @@ export class AbstractLayer {
|
|||
return [];
|
||||
}
|
||||
|
||||
async getFields() {
|
||||
return [];
|
||||
}
|
||||
|
||||
syncVisibilityWithMb(mbMap, mbLayerId) {
|
||||
mbMap.setLayoutProperty(mbLayerId, 'visibility', this.isVisible() ? 'visible' : 'none');
|
||||
}
|
||||
|
|
|
@ -124,6 +124,24 @@ export class ESSearchSource extends AbstractESSource {
|
|||
}
|
||||
}
|
||||
|
||||
async getFields() {
|
||||
try {
|
||||
const indexPattern = await this.getIndexPattern();
|
||||
return indexPattern.fields
|
||||
.filter(field => {
|
||||
// Ensure fielddata is enabled for field.
|
||||
// Search does not request _source
|
||||
return field.aggregatable;
|
||||
})
|
||||
.map(field => {
|
||||
return this.createField({ fieldName: field.name });
|
||||
});
|
||||
} catch (error) {
|
||||
// failed index-pattern retrieval will show up as error-message in the layer-toc-entry
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
getFieldNames() {
|
||||
return [this._descriptor.geoField];
|
||||
}
|
||||
|
|
|
@ -103,6 +103,10 @@ export class AbstractVectorSource extends AbstractSource {
|
|||
return [];
|
||||
}
|
||||
|
||||
async getFields() {
|
||||
return [...(await this.getDateFields()), ...(await this.getNumberFields())];
|
||||
}
|
||||
|
||||
async getLeftJoinFields() {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { FieldSelect, fieldShape } from '../field_select';
|
|||
import { ColorRampSelect } from './color_ramp_select';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
|
||||
export function DynamicColorSelection({ ordinalFields, onChange, styleOptions }) {
|
||||
export function DynamicColorSelection({ fields, onChange, styleOptions }) {
|
||||
const onFieldChange = ({ field }) => {
|
||||
onChange({ ...styleOptions, field });
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ export function DynamicColorSelection({ ordinalFields, onChange, styleOptions })
|
|||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<FieldSelect
|
||||
fields={ordinalFields}
|
||||
fields={fields}
|
||||
selectedFieldName={_.get(styleOptions, 'field.name')}
|
||||
onChange={onFieldChange}
|
||||
compressed
|
||||
|
@ -42,7 +42,7 @@ export function DynamicColorSelection({ ordinalFields, onChange, styleOptions })
|
|||
}
|
||||
|
||||
DynamicColorSelection.propTypes = {
|
||||
ordinalFields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
fields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
styleOptions: dynamicColorShape.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ import { StaticColorSelection } from './static_color_selection';
|
|||
export function VectorStyleColorEditor(props) {
|
||||
return (
|
||||
<StaticDynamicStyleRow
|
||||
ordinalFields={props.ordinalFields}
|
||||
fields={props.fields}
|
||||
styleProperty={props.styleProperty}
|
||||
handlePropertyChange={props.handlePropertyChange}
|
||||
swatches={props.swatches}
|
||||
|
|
|
@ -30,6 +30,18 @@ export function getVectorStyleLabel(styleName) {
|
|||
return i18n.translate('xpack.maps.styles.vector.orientationLabel', {
|
||||
defaultMessage: 'Symbol orientation',
|
||||
});
|
||||
case VECTOR_STYLES.LABEL_TEXT:
|
||||
return i18n.translate('xpack.maps.styles.vector.labelLabel', {
|
||||
defaultMessage: 'Label',
|
||||
});
|
||||
case VECTOR_STYLES.LABEL_COLOR:
|
||||
return i18n.translate('xpack.maps.styles.vector.labelColorLabel', {
|
||||
defaultMessage: 'Label color',
|
||||
});
|
||||
case VECTOR_STYLES.LABEL_SIZE:
|
||||
return i18n.translate('xpack.maps.styles.vector.labelSizeLabel', {
|
||||
defaultMessage: 'Label size',
|
||||
});
|
||||
default:
|
||||
return styleName;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 _ from 'lodash';
|
||||
import React from 'react';
|
||||
import { FieldSelect } from '../field_select';
|
||||
|
||||
export function DynamicLabelSelector({ fields, styleOptions, onChange }) {
|
||||
const onFieldChange = ({ field }) => {
|
||||
onChange({ ...styleOptions, field });
|
||||
};
|
||||
|
||||
return (
|
||||
<FieldSelect
|
||||
fields={fields}
|
||||
selectedFieldName={_.get(styleOptions, 'field.name')}
|
||||
onChange={onFieldChange}
|
||||
compressed
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiFieldText } from '@elastic/eui';
|
||||
|
||||
export function StaticLabelSelector({ onChange, styleOptions }) {
|
||||
const onValueChange = event => {
|
||||
onChange({ value: event.target.value });
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFieldText
|
||||
placeholder={i18n.translate('xpack.maps.styles.staticLabel.valuePlaceholder', {
|
||||
defaultMessage: 'symbol label',
|
||||
})}
|
||||
value={styleOptions.value}
|
||||
onChange={onValueChange}
|
||||
aria-label={i18n.translate('xpack.maps.styles.staticLabel.valueAriaLabel', {
|
||||
defaultMessage: 'symbol label',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
|
||||
import { StaticDynamicStyleRow } from '../static_dynamic_style_row';
|
||||
import { DynamicLabelSelector } from './dynamic_label_selector';
|
||||
import { StaticLabelSelector } from './static_label_selector';
|
||||
|
||||
export function VectorStyleLabelEditor(props) {
|
||||
return (
|
||||
<StaticDynamicStyleRow
|
||||
{...props}
|
||||
DynamicSelector={DynamicLabelSelector}
|
||||
StaticSelector={StaticLabelSelector}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -10,14 +10,14 @@ import PropTypes from 'prop-types';
|
|||
import { dynamicOrientationShape } from '../style_option_shapes';
|
||||
import { FieldSelect, fieldShape } from '../field_select';
|
||||
|
||||
export function DynamicOrientationSelection({ ordinalFields, styleOptions, onChange }) {
|
||||
export function DynamicOrientationSelection({ fields, styleOptions, onChange }) {
|
||||
const onFieldChange = ({ field }) => {
|
||||
onChange({ ...styleOptions, field });
|
||||
};
|
||||
|
||||
return (
|
||||
<FieldSelect
|
||||
fields={ordinalFields}
|
||||
fields={fields}
|
||||
selectedFieldName={_.get(styleOptions, 'field.name')}
|
||||
onChange={onFieldChange}
|
||||
compressed
|
||||
|
@ -26,7 +26,7 @@ export function DynamicOrientationSelection({ ordinalFields, styleOptions, onCha
|
|||
}
|
||||
|
||||
DynamicOrientationSelection.propTypes = {
|
||||
ordinalFields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
fields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
styleOptions: dynamicOrientationShape.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ import { StaticOrientationSelection } from './static_orientation_selection';
|
|||
export function OrientationEditor(props) {
|
||||
return (
|
||||
<StaticDynamicStyleRow
|
||||
ordinalFields={props.ordinalFields}
|
||||
fields={props.fields}
|
||||
styleProperty={props.styleProperty}
|
||||
handlePropertyChange={props.handlePropertyChange}
|
||||
DynamicSelector={DynamicOrientationSelection}
|
||||
|
|
|
@ -12,7 +12,7 @@ import { FieldSelect, fieldShape } from '../field_select';
|
|||
import { SizeRangeSelector } from './size_range_selector';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
|
||||
export function DynamicSizeSelection({ ordinalFields, styleOptions, onChange }) {
|
||||
export function DynamicSizeSelection({ fields, styleOptions, onChange }) {
|
||||
const onFieldChange = ({ field }) => {
|
||||
onChange({ ...styleOptions, field });
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ export function DynamicSizeSelection({ ordinalFields, styleOptions, onChange })
|
|||
/>
|
||||
<EuiSpacer size="s" />
|
||||
<FieldSelect
|
||||
fields={ordinalFields}
|
||||
fields={fields}
|
||||
selectedFieldName={_.get(styleOptions, 'field.name')}
|
||||
onChange={onFieldChange}
|
||||
compressed
|
||||
|
@ -42,7 +42,7 @@ export function DynamicSizeSelection({ ordinalFields, styleOptions, onChange })
|
|||
}
|
||||
|
||||
DynamicSizeSelection.propTypes = {
|
||||
ordinalFields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
fields: PropTypes.arrayOf(fieldShape).isRequired,
|
||||
styleOptions: dynamicSizeShape.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ import { StaticSizeSelection } from './static_size_selection';
|
|||
export function VectorStyleSizeEditor(props) {
|
||||
return (
|
||||
<StaticDynamicStyleRow
|
||||
ordinalFields={props.ordinalFields}
|
||||
fields={props.fields}
|
||||
styleProperty={props.styleProperty}
|
||||
handlePropertyChange={props.handlePropertyChange}
|
||||
DynamicSelector={DynamicSizeSelection}
|
||||
|
|
|
@ -19,7 +19,7 @@ export class StaticDynamicStyleRow extends Component {
|
|||
prevDynamicStyleOptions = this.props.defaultDynamicStyleOptions;
|
||||
|
||||
_canBeDynamic() {
|
||||
return this.props.ordinalFields.length > 0;
|
||||
return this.props.fields.length > 0;
|
||||
}
|
||||
|
||||
_isDynamic() {
|
||||
|
@ -78,7 +78,7 @@ export class StaticDynamicStyleRow extends Component {
|
|||
return (
|
||||
<Fragment>
|
||||
<DynamicSelector
|
||||
ordinalFields={this.props.ordinalFields}
|
||||
fields={this.props.fields}
|
||||
onChange={this._onDynamicStyleChange}
|
||||
styleOptions={this._getStyleOptions()}
|
||||
/>
|
||||
|
|
|
@ -11,6 +11,7 @@ import chrome from 'ui/chrome';
|
|||
import { VectorStyleColorEditor } from './color/vector_style_color_editor';
|
||||
import { VectorStyleSizeEditor } from './size/vector_style_size_editor';
|
||||
import { VectorStyleSymbolEditor } from './vector_style_symbol_editor';
|
||||
import { VectorStyleLabelEditor } from './label/vector_style_label_editor';
|
||||
import { OrientationEditor } from './orientation/orientation_editor';
|
||||
import { getDefaultDynamicProperties, getDefaultStaticProperties } from '../vector_style_defaults';
|
||||
import { DEFAULT_FILL_COLORS, DEFAULT_LINE_COLORS } from '../../color_utils';
|
||||
|
@ -25,6 +26,7 @@ export class VectorStyleEditor extends Component {
|
|||
state = {
|
||||
dateFields: [],
|
||||
numberFields: [],
|
||||
fields: [],
|
||||
defaultDynamicProperties: getDefaultDynamicProperties(),
|
||||
defaultStaticProperties: getDefaultStaticProperties(),
|
||||
supportedFeatures: undefined,
|
||||
|
@ -37,16 +39,16 @@ export class VectorStyleEditor extends Component {
|
|||
|
||||
componentDidMount() {
|
||||
this._isMounted = true;
|
||||
this._loadOrdinalFields();
|
||||
this._loadFields();
|
||||
this._loadSupportedFeatures();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this._loadOrdinalFields();
|
||||
this._loadFields();
|
||||
this._loadSupportedFeatures();
|
||||
}
|
||||
|
||||
async _loadOrdinalFields() {
|
||||
async _loadFields() {
|
||||
const getFieldMeta = async field => {
|
||||
return {
|
||||
label: await field.getLabel(),
|
||||
|
@ -54,21 +56,27 @@ export class VectorStyleEditor extends Component {
|
|||
origin: field.getOrigin(),
|
||||
};
|
||||
};
|
||||
|
||||
const dateFields = await this.props.layer.getDateFields();
|
||||
const dateFieldPromises = dateFields.map(getFieldMeta);
|
||||
const dateFieldsArray = await Promise.all(dateFieldPromises);
|
||||
|
||||
if (this._isMounted && !_.isEqual(dateFieldsArray, this.state.dateFields)) {
|
||||
this.setState({ dateFields: dateFieldsArray });
|
||||
}
|
||||
|
||||
const numberFields = await this.props.layer.getNumberFields();
|
||||
const numberFieldPromises = numberFields.map(getFieldMeta);
|
||||
|
||||
const numberFieldsArray = await Promise.all(numberFieldPromises);
|
||||
if (this._isMounted && !_.isEqual(numberFieldsArray, this.state.numberFields)) {
|
||||
this.setState({ numberFields: numberFieldsArray });
|
||||
}
|
||||
|
||||
const fields = await this.props.layer.getFields();
|
||||
const fieldPromises = fields.map(getFieldMeta);
|
||||
const fieldsArray = await Promise.all(fieldPromises);
|
||||
if (this._isMounted && !_.isEqual(fieldsArray, this.state.fields)) {
|
||||
this.setState({ fields: fieldsArray });
|
||||
}
|
||||
}
|
||||
|
||||
async _loadSupportedFeatures() {
|
||||
|
@ -126,7 +134,7 @@ export class VectorStyleEditor extends Component {
|
|||
swatches={DEFAULT_FILL_COLORS}
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.fillColor}
|
||||
ordinalFields={this._getOrdinalFields()}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.fillColor.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.fillColor.options}
|
||||
/>
|
||||
|
@ -139,7 +147,7 @@ export class VectorStyleEditor extends Component {
|
|||
swatches={DEFAULT_LINE_COLORS}
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.lineColor}
|
||||
ordinalFields={this._getOrdinalFields()}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.lineColor.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.lineColor.options}
|
||||
/>
|
||||
|
@ -151,7 +159,7 @@ export class VectorStyleEditor extends Component {
|
|||
<VectorStyleSizeEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.lineWidth}
|
||||
ordinalFields={this._getOrdinalFields()}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.lineWidth.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.lineWidth.options}
|
||||
/>
|
||||
|
@ -163,27 +171,58 @@ export class VectorStyleEditor extends Component {
|
|||
<VectorStyleSizeEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.iconSize}
|
||||
ordinalFields={this._getOrdinalFields()}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.iconSize.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.iconSize.options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_renderLabelProperties() {
|
||||
return (
|
||||
<Fragment>
|
||||
<VectorStyleLabelEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.labelText}
|
||||
fields={this.state.fields}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.labelText.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.labelText.options}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<VectorStyleColorEditor
|
||||
swatches={DEFAULT_LINE_COLORS}
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.labelColor}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.labelColor.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.labelColor.options}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
<VectorStyleSizeEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.labelSize}
|
||||
fields={this._getOrdinalFields()}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.labelSize.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.labelSize.options}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
_renderPointProperties() {
|
||||
let iconOrientation;
|
||||
if (this.props.symbolDescriptor.options.symbolizeAs === SYMBOLIZE_AS_ICON) {
|
||||
iconOrientation = (
|
||||
<Fragment>
|
||||
<OrientationEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.iconOrientation}
|
||||
ordinalFields={this.state.numberFields}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.iconOrientation.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.iconOrientation.options}
|
||||
/>
|
||||
<EuiSpacer size="m" />
|
||||
</Fragment>
|
||||
<OrientationEditor
|
||||
handlePropertyChange={this.props.handlePropertyChange}
|
||||
styleProperty={this.props.styleProperties.iconOrientation}
|
||||
fields={this.state.numberFields}
|
||||
defaultStaticStyleOptions={this.state.defaultStaticProperties.iconOrientation.options}
|
||||
defaultDynamicStyleOptions={this.state.defaultDynamicProperties.iconOrientation.options}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -207,8 +246,12 @@ export class VectorStyleEditor extends Component {
|
|||
<EuiSpacer size="m" />
|
||||
|
||||
{iconOrientation}
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
{this._renderSymbolSize()}
|
||||
<EuiSpacer size="m" />
|
||||
|
||||
{this._renderLabelProperties()}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,12 @@ export class DynamicColorProperty extends DynamicStyleProperty {
|
|||
mbMap.setPaintProperty(mbLayerId, 'line-opacity', alpha);
|
||||
}
|
||||
|
||||
syncLabelColorWithMb(mbLayerId, mbMap, alpha) {
|
||||
const color = this._getMbColor();
|
||||
mbMap.setPaintProperty(mbLayerId, 'text-color', color);
|
||||
mbMap.setPaintProperty(mbLayerId, 'text-opacity', alpha);
|
||||
}
|
||||
|
||||
isCustomColorRamp() {
|
||||
return this._options.useCustomColorRamp;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,10 @@ function getSymbolSizeIcons() {
|
|||
}
|
||||
|
||||
export class DynamicSizeProperty extends DynamicStyleProperty {
|
||||
supportsFeatureState() {
|
||||
return this.getStyleName() !== VECTOR_STYLES.LABEL_SIZE;
|
||||
}
|
||||
|
||||
syncHaloWidthWithMb(mbLayerId, mbMap) {
|
||||
const haloWidth = this._getMbSize();
|
||||
mbMap.setPaintProperty(mbLayerId, 'icon-halo-width', haloWidth);
|
||||
|
@ -89,6 +93,11 @@ export class DynamicSizeProperty extends DynamicStyleProperty {
|
|||
mbMap.setPaintProperty(mbLayerId, 'line-width', lineWidth);
|
||||
}
|
||||
|
||||
syncLabelSizeWithMb(mbLayerId, mbMap) {
|
||||
const lineWidth = this._getMbSize();
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-size', lineWidth);
|
||||
}
|
||||
|
||||
_getMbSize() {
|
||||
if (this._isSizeDynamicConfigComplete(this._options)) {
|
||||
return this._getMbDataDrivenSize({
|
||||
|
@ -101,10 +110,11 @@ export class DynamicSizeProperty extends DynamicStyleProperty {
|
|||
}
|
||||
|
||||
_getMbDataDrivenSize({ targetName, minSize, maxSize }) {
|
||||
const lookup = this.supportsFeatureState() ? 'feature-state' : 'get';
|
||||
return [
|
||||
'interpolate',
|
||||
['linear'],
|
||||
['coalesce', ['feature-state', targetName], 0],
|
||||
['coalesce', [lookup, targetName], 0],
|
||||
0,
|
||||
minSize,
|
||||
1,
|
||||
|
|
|
@ -33,6 +33,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
|
|||
return true;
|
||||
}
|
||||
|
||||
isOrdinal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
isComplete() {
|
||||
return !!this._field;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 { DynamicStyleProperty } from './dynamic_style_property';
|
||||
import { getComputedFieldName } from '../style_util';
|
||||
|
||||
export class DynamicTextProperty extends DynamicStyleProperty {
|
||||
syncTextFieldWithMb(mbLayerId, mbMap) {
|
||||
if (this._field && this._field.isValid()) {
|
||||
const targetName = getComputedFieldName(this._styleName, this._options.field.name);
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-field', ['coalesce', ['get', targetName], '']);
|
||||
} else {
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-field', null);
|
||||
}
|
||||
}
|
||||
|
||||
isOrdinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
supportsFieldMeta() {
|
||||
return false;
|
||||
}
|
||||
|
||||
supportsFeatureState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
isScaled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -30,8 +30,13 @@ export class StaticColorProperty extends StaticStyleProperty {
|
|||
mbMap.setPaintProperty(mbLayerId, 'line-opacity', alpha);
|
||||
}
|
||||
|
||||
syncCircleStrokeWithMb(pointLayerId, mbMap, alpha) {
|
||||
mbMap.setPaintProperty(pointLayerId, 'circle-stroke-color', this._options.color);
|
||||
mbMap.setPaintProperty(pointLayerId, 'circle-stroke-opacity', alpha);
|
||||
syncCircleStrokeWithMb(mbLayerId, mbMap, alpha) {
|
||||
mbMap.setPaintProperty(mbLayerId, 'circle-stroke-color', this._options.color);
|
||||
mbMap.setPaintProperty(mbLayerId, 'circle-stroke-opacity', alpha);
|
||||
}
|
||||
|
||||
syncLabelColorWithMb(mbLayerId, mbMap, alpha) {
|
||||
mbMap.setPaintProperty(mbLayerId, 'text-color', this._options.color);
|
||||
mbMap.setPaintProperty(mbLayerId, 'text-opacity', alpha);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,4 +43,8 @@ export class StaticSizeProperty extends StaticStyleProperty {
|
|||
syncLineWidthWithMb(mbLayerId, mbMap) {
|
||||
mbMap.setPaintProperty(mbLayerId, 'line-width', this._options.size);
|
||||
}
|
||||
|
||||
syncLabelSizeWithMb(mbLayerId, mbMap) {
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-size', this._options.size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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 { StaticStyleProperty } from './static_style_property';
|
||||
|
||||
export class StaticTextProperty extends StaticStyleProperty {
|
||||
isComplete() {
|
||||
return this.getOptions().value.length > 0;
|
||||
}
|
||||
|
||||
syncTextFieldWithMb(mbLayerId, mbMap) {
|
||||
if (this.getOptions().value.length) {
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-field', this.getOptions().value);
|
||||
} else {
|
||||
mbMap.setLayoutProperty(mbLayerId, 'text-field', null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ import { StaticColorProperty } from './properties/static_color_property';
|
|||
import { DynamicColorProperty } from './properties/dynamic_color_property';
|
||||
import { StaticOrientationProperty } from './properties/static_orientation_property';
|
||||
import { DynamicOrientationProperty } from './properties/dynamic_orientation_property';
|
||||
import { StaticTextProperty } from './properties/static_text_property';
|
||||
import { DynamicTextProperty } from './properties/dynamic_text_property';
|
||||
|
||||
const POINTS = [GEO_JSON_TYPE.POINT, GEO_JSON_TYPE.MULTI_POINT];
|
||||
const LINES = [GEO_JSON_TYPE.LINE_STRING, GEO_JSON_TYPE.MULTI_LINE_STRING];
|
||||
|
@ -85,6 +87,17 @@ export class VectorStyle extends AbstractStyle {
|
|||
this._descriptor.properties[VECTOR_STYLES.ICON_ORIENTATION],
|
||||
VECTOR_STYLES.ICON_ORIENTATION
|
||||
);
|
||||
this._labelStyleProperty = this._makeLabelProperty(
|
||||
this._descriptor.properties[VECTOR_STYLES.LABEL_TEXT]
|
||||
);
|
||||
this._labelSizeStyleProperty = this._makeSizeProperty(
|
||||
this._descriptor.properties[VECTOR_STYLES.LABEL_SIZE],
|
||||
VECTOR_STYLES.LABEL_SIZE
|
||||
);
|
||||
this._labelColorStyleProperty = this._makeColorProperty(
|
||||
this._descriptor.properties[VECTOR_STYLES.LABEL_COLOR],
|
||||
VECTOR_STYLES.LABEL_COLOR
|
||||
);
|
||||
}
|
||||
|
||||
_getAllStyleProperties() {
|
||||
|
@ -94,6 +107,9 @@ export class VectorStyle extends AbstractStyle {
|
|||
this._lineWidthStyleProperty,
|
||||
this._iconSizeStyleProperty,
|
||||
this._iconOrientationProperty,
|
||||
this._labelStyleProperty,
|
||||
this._labelSizeStyleProperty,
|
||||
this._labelColorStyleProperty,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -114,16 +130,15 @@ export class VectorStyle extends AbstractStyle {
|
|||
return dynamicStyleProp.isFieldMetaEnabled();
|
||||
});
|
||||
|
||||
const styleProperties = {};
|
||||
this._getAllStyleProperties().forEach(styleProperty => {
|
||||
styleProperties[styleProperty.getStyleName()] = styleProperty;
|
||||
});
|
||||
|
||||
return (
|
||||
<VectorStyleEditor
|
||||
handlePropertyChange={handlePropertyChange}
|
||||
styleProperties={{
|
||||
lineColor: this._lineColorStyleProperty,
|
||||
fillColor: this._fillColorStyleProperty,
|
||||
lineWidth: this._lineWidthStyleProperty,
|
||||
iconSize: this._iconSizeStyleProperty,
|
||||
iconOrientation: this._iconOrientationProperty,
|
||||
}}
|
||||
styleProperties={styleProperties}
|
||||
symbolDescriptor={this._descriptor.properties[VECTOR_STYLES.SYMBOL]}
|
||||
layer={layer}
|
||||
loadIsPointsOnly={this._getIsPointsOnly}
|
||||
|
@ -391,12 +406,17 @@ export class VectorStyle extends AbstractStyle {
|
|||
const isPolygonsOnly = await this._getIsPolygonsOnly();
|
||||
|
||||
return this.getDynamicPropertiesArray().filter(styleProperty => {
|
||||
const styleName = styleProperty.getStyleName();
|
||||
if ([VECTOR_STYLES.ICON_ORIENTATION, VECTOR_STYLES.LABEL_TEXT].includes(styleName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLinesOnly) {
|
||||
return LINE_STYLES.includes(styleProperty.getStyleName());
|
||||
return LINE_STYLES.includes(styleName);
|
||||
}
|
||||
|
||||
if (isPolygonsOnly) {
|
||||
return POLYGON_STYLES.includes(styleProperty.getStyleName());
|
||||
return POLYGON_STYLES.includes(styleName);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -420,6 +440,7 @@ export class VectorStyle extends AbstractStyle {
|
|||
// To work around this limitation, some styling values must fall back to geojson property values.
|
||||
let supportsFeatureState;
|
||||
let isScaled;
|
||||
// TODO move first check into DynamicSizeProperty.supportsFeatureState
|
||||
if (
|
||||
styleProperty.getStyleName() === VECTOR_STYLES.ICON_SIZE &&
|
||||
this._descriptor.properties.symbol.options.symbolizeAs === SYMBOLIZE_AS_ICON
|
||||
|
@ -435,8 +456,10 @@ export class VectorStyle extends AbstractStyle {
|
|||
return {
|
||||
supportsFeatureState,
|
||||
isScaled,
|
||||
isOrdinal: styleProperty.isOrdinal(),
|
||||
name: field.getName(),
|
||||
meta: this._getFieldMeta(field.getName()),
|
||||
formatter: this._getFieldFormatter(field.getName()),
|
||||
computedName: getComputedFieldName(styleProperty.getStyleName(), field.getName()),
|
||||
};
|
||||
});
|
||||
|
@ -455,6 +478,20 @@ export class VectorStyle extends AbstractStyle {
|
|||
}
|
||||
}
|
||||
|
||||
_getOrdinalValue(value, isScaled, range) {
|
||||
const valueAsFloat = parseFloat(value);
|
||||
|
||||
if (isScaled) {
|
||||
return scaleValue(valueAsFloat, range);
|
||||
}
|
||||
|
||||
if (isNaN(valueAsFloat)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return valueAsFloat;
|
||||
}
|
||||
|
||||
setFeatureStateAndStyleProps(featureCollection, mbMap, mbSourceId) {
|
||||
if (!featureCollection) {
|
||||
return;
|
||||
|
@ -479,20 +516,20 @@ export class VectorStyle extends AbstractStyle {
|
|||
const {
|
||||
supportsFeatureState,
|
||||
isScaled,
|
||||
isOrdinal,
|
||||
name,
|
||||
meta: range,
|
||||
formatter,
|
||||
computedName,
|
||||
} = featureStateParams[j];
|
||||
const value = parseFloat(feature.properties[name]);
|
||||
|
||||
let styleValue;
|
||||
if (isScaled) {
|
||||
styleValue = scaleValue(value, range);
|
||||
if (isOrdinal) {
|
||||
styleValue = this._getOrdinalValue(feature.properties[name], isScaled, range);
|
||||
} else if (formatter) {
|
||||
styleValue = formatter(feature.properties[name]);
|
||||
} else {
|
||||
if (isNaN(value)) {
|
||||
styleValue = 0;
|
||||
} else {
|
||||
styleValue = value;
|
||||
}
|
||||
styleValue = feature.properties[name];
|
||||
}
|
||||
|
||||
if (supportsFeatureState) {
|
||||
|
@ -530,6 +567,14 @@ export class VectorStyle extends AbstractStyle {
|
|||
this._iconSizeStyleProperty.syncCircleRadiusWithMb(pointLayerId, mbMap);
|
||||
}
|
||||
|
||||
setMBPropertiesForLabelText({ alpha, mbMap, textLayerId }) {
|
||||
mbMap.setLayoutProperty(textLayerId, 'icon-allow-overlap', true);
|
||||
mbMap.setLayoutProperty(textLayerId, 'text-allow-overlap', true);
|
||||
this._labelStyleProperty.syncTextFieldWithMb(textLayerId, mbMap);
|
||||
this._labelColorStyleProperty.syncLabelColorWithMb(textLayerId, mbMap, alpha);
|
||||
this._labelSizeStyleProperty.syncLabelSizeWithMb(textLayerId, mbMap);
|
||||
}
|
||||
|
||||
setMBSymbolPropertiesForPoints({ mbMap, symbolLayerId, alpha }) {
|
||||
const symbolId = this._descriptor.properties.symbol.options.symbolId;
|
||||
mbMap.setLayoutProperty(symbolLayerId, 'icon-ignore-placement', true);
|
||||
|
@ -619,4 +664,17 @@ export class VectorStyle extends AbstractStyle {
|
|||
throw new Error(`${descriptor} not implemented`);
|
||||
}
|
||||
}
|
||||
|
||||
_makeLabelProperty(descriptor) {
|
||||
if (!descriptor || !descriptor.options) {
|
||||
return new StaticTextProperty({ value: '' }, VECTOR_STYLES.LABEL_TEXT);
|
||||
} else if (descriptor.type === StaticStyleProperty.type) {
|
||||
return new StaticTextProperty(descriptor.options, VECTOR_STYLES.LABEL_TEXT);
|
||||
} else if (descriptor.type === DynamicStyleProperty.type) {
|
||||
const field = this._makeField(descriptor.options.field);
|
||||
return new DynamicTextProperty(descriptor.options, VECTOR_STYLES.LABEL_TEXT, field);
|
||||
} else {
|
||||
throw new Error(`${descriptor} not implemented`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,24 @@ describe('getDescriptorWithMissingStylePropsRemoved', () => {
|
|||
},
|
||||
type: 'DYNAMIC',
|
||||
},
|
||||
labelText: {
|
||||
options: {
|
||||
value: '',
|
||||
},
|
||||
type: 'STATIC',
|
||||
},
|
||||
labelColor: {
|
||||
options: {
|
||||
color: '#000000',
|
||||
},
|
||||
type: 'STATIC',
|
||||
},
|
||||
labelSize: {
|
||||
options: {
|
||||
size: 14,
|
||||
},
|
||||
type: 'STATIC',
|
||||
},
|
||||
lineColor: {
|
||||
options: {},
|
||||
type: 'DYNAMIC',
|
||||
|
|
|
@ -7,11 +7,14 @@
|
|||
import { VectorStyle } from './vector_style';
|
||||
import { SYMBOLIZE_AS_CIRCLE, DEFAULT_ICON_SIZE } from './vector_constants';
|
||||
import { COLOR_GRADIENTS, DEFAULT_FILL_COLORS, DEFAULT_LINE_COLORS } from '../color_utils';
|
||||
import chrome from 'ui/chrome';
|
||||
|
||||
const DEFAULT_ICON = 'airfield';
|
||||
|
||||
export const MIN_SIZE = 1;
|
||||
export const MAX_SIZE = 64;
|
||||
export const DEFAULT_MIN_SIZE = 4;
|
||||
export const DEFAULT_MAX_SIZE = 32;
|
||||
export const DEFAULT_SIGMA = 3;
|
||||
|
||||
export const VECTOR_STYLES = {
|
||||
|
@ -21,6 +24,9 @@ export const VECTOR_STYLES = {
|
|||
LINE_WIDTH: 'lineWidth',
|
||||
ICON_SIZE: 'iconSize',
|
||||
ICON_ORIENTATION: 'iconOrientation',
|
||||
LABEL_TEXT: 'labelText',
|
||||
LABEL_COLOR: 'labelColor',
|
||||
LABEL_SIZE: 'labelSize',
|
||||
};
|
||||
|
||||
export const LINE_STYLES = [VECTOR_STYLES.LINE_COLOR, VECTOR_STYLES.LINE_WIDTH];
|
||||
|
@ -49,6 +55,8 @@ export function getDefaultStaticProperties(mapColors = []) {
|
|||
const nextFillColor = DEFAULT_FILL_COLORS[nextColorIndex];
|
||||
const nextLineColor = DEFAULT_LINE_COLORS[nextColorIndex];
|
||||
|
||||
const isDarkMode = chrome.getUiSettingsClient().get('theme:darkMode', false);
|
||||
|
||||
return {
|
||||
[VECTOR_STYLES.FILL_COLOR]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
|
@ -80,6 +88,24 @@ export function getDefaultStaticProperties(mapColors = []) {
|
|||
orientation: 0,
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_TEXT]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_COLOR]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
color: isDarkMode ? '#FFFFFF' : '#000000',
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_SIZE]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
size: 14,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -122,8 +148,8 @@ export function getDefaultDynamicProperties() {
|
|||
[VECTOR_STYLES.ICON_SIZE]: {
|
||||
type: VectorStyle.STYLE_TYPE.DYNAMIC,
|
||||
options: {
|
||||
minSize: 4,
|
||||
maxSize: 32,
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
maxSize: DEFAULT_MAX_SIZE,
|
||||
field: undefined,
|
||||
fieldMetaOptions: {
|
||||
isEnabled: true,
|
||||
|
@ -141,5 +167,34 @@ export function getDefaultDynamicProperties() {
|
|||
},
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_TEXT]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
field: undefined,
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_COLOR]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
color: COLOR_GRADIENTS[0].value,
|
||||
field: undefined,
|
||||
fieldMetaOptions: {
|
||||
isEnabled: true,
|
||||
sigma: DEFAULT_SIGMA,
|
||||
},
|
||||
},
|
||||
},
|
||||
[VECTOR_STYLES.LABEL_SIZE]: {
|
||||
type: VectorStyle.STYLE_TYPE.STATIC,
|
||||
options: {
|
||||
minSize: DEFAULT_MIN_SIZE,
|
||||
maxSize: DEFAULT_MAX_SIZE,
|
||||
field: undefined,
|
||||
fieldMetaOptions: {
|
||||
isEnabled: true,
|
||||
sigma: DEFAULT_SIGMA,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -191,24 +191,33 @@ export class VectorLayer extends AbstractLayer {
|
|||
return this._source.getDisplayName();
|
||||
}
|
||||
|
||||
_getJoinFields() {
|
||||
const joinFields = [];
|
||||
this.getValidJoins().forEach(join => {
|
||||
const fields = join.getJoinFields();
|
||||
joinFields.push(...fields);
|
||||
});
|
||||
return joinFields;
|
||||
}
|
||||
|
||||
async getDateFields() {
|
||||
return await this._source.getDateFields();
|
||||
}
|
||||
|
||||
async getNumberFields() {
|
||||
const numberFieldOptions = await this._source.getNumberFields();
|
||||
const joinFields = [];
|
||||
this.getValidJoins().forEach(join => {
|
||||
const fields = join.getJoinFields();
|
||||
joinFields.push(...fields);
|
||||
});
|
||||
return [...numberFieldOptions, ...joinFields];
|
||||
return [...numberFieldOptions, ...this._getJoinFields()];
|
||||
}
|
||||
|
||||
async getOrdinalFields() {
|
||||
return [...(await this.getDateFields()), ...(await this.getNumberFields())];
|
||||
}
|
||||
|
||||
async getFields() {
|
||||
const sourceFields = await this._source.getFields();
|
||||
return [...sourceFields, ...this._getJoinFields()];
|
||||
}
|
||||
|
||||
getIndexPatternIds() {
|
||||
const indexPatternIds = this._source.getIndexPatternIds();
|
||||
this.getValidJoins().forEach(join => {
|
||||
|
@ -621,30 +630,40 @@ export class VectorLayer extends AbstractLayer {
|
|||
const pointLayer = mbMap.getLayer(pointLayerId);
|
||||
const symbolLayer = mbMap.getLayer(symbolLayerId);
|
||||
|
||||
let mbLayerId;
|
||||
// Point layers symbolized as circles require 2 mapbox layers because
|
||||
// "circle" layers do not support "text" style properties
|
||||
// Point layers symbolized as icons only contain a single mapbox layer.
|
||||
let markerLayerId;
|
||||
let textLayerId;
|
||||
if (this._style.arePointsSymbolizedAsCircles()) {
|
||||
mbLayerId = pointLayerId;
|
||||
markerLayerId = pointLayerId;
|
||||
textLayerId = this._getMbTextLayerId();
|
||||
if (symbolLayer) {
|
||||
mbMap.setLayoutProperty(symbolLayerId, 'visibility', 'none');
|
||||
}
|
||||
this._setMbCircleProperties(mbMap);
|
||||
} else {
|
||||
mbLayerId = symbolLayerId;
|
||||
markerLayerId = symbolLayerId;
|
||||
textLayerId = symbolLayerId;
|
||||
if (pointLayer) {
|
||||
mbMap.setLayoutProperty(pointLayerId, 'visibility', 'none');
|
||||
mbMap.setLayoutProperty(this._getMbTextLayerId(), 'visibility', 'none');
|
||||
}
|
||||
this._setMbSymbolProperties(mbMap);
|
||||
}
|
||||
|
||||
this.syncVisibilityWithMb(mbMap, mbLayerId);
|
||||
mbMap.setLayerZoomRange(mbLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
|
||||
this.syncVisibilityWithMb(mbMap, markerLayerId);
|
||||
mbMap.setLayerZoomRange(markerLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
|
||||
if (markerLayerId !== textLayerId) {
|
||||
this.syncVisibilityWithMb(mbMap, textLayerId);
|
||||
mbMap.setLayerZoomRange(textLayerId, this._descriptor.minZoom, this._descriptor.maxZoom);
|
||||
}
|
||||
}
|
||||
|
||||
_setMbCircleProperties(mbMap) {
|
||||
const sourceId = this.getId();
|
||||
const pointLayerId = this._getMbPointLayerId();
|
||||
const pointLayer = mbMap.getLayer(pointLayerId);
|
||||
|
||||
if (!pointLayer) {
|
||||
mbMap.addLayer({
|
||||
id: pointLayerId,
|
||||
|
@ -654,15 +673,32 @@ export class VectorLayer extends AbstractLayer {
|
|||
});
|
||||
}
|
||||
|
||||
const textLayerId = this._getMbTextLayerId();
|
||||
const textLayer = mbMap.getLayer(textLayerId);
|
||||
if (!textLayer) {
|
||||
mbMap.addLayer({
|
||||
id: textLayerId,
|
||||
type: 'symbol',
|
||||
source: sourceId,
|
||||
});
|
||||
}
|
||||
|
||||
const filterExpr = getPointFilterExpression(this._hasJoins());
|
||||
if (filterExpr !== mbMap.getFilter(pointLayerId)) {
|
||||
mbMap.setFilter(pointLayerId, filterExpr);
|
||||
mbMap.setFilter(textLayerId, filterExpr);
|
||||
}
|
||||
|
||||
this._style.setMBPaintPropertiesForPoints({
|
||||
alpha: this.getAlpha(),
|
||||
mbMap,
|
||||
pointLayerId: pointLayerId,
|
||||
pointLayerId,
|
||||
});
|
||||
|
||||
this._style.setMBPropertiesForLabelText({
|
||||
alpha: this.getAlpha(),
|
||||
mbMap,
|
||||
textLayerId,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -687,7 +723,13 @@ export class VectorLayer extends AbstractLayer {
|
|||
this._style.setMBSymbolPropertiesForPoints({
|
||||
alpha: this.getAlpha(),
|
||||
mbMap,
|
||||
symbolLayerId: symbolLayerId,
|
||||
symbolLayerId,
|
||||
});
|
||||
|
||||
this._style.setMBPropertiesForLabelText({
|
||||
alpha: this.getAlpha(),
|
||||
mbMap,
|
||||
textLayerId: symbolLayerId,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -759,6 +801,10 @@ export class VectorLayer extends AbstractLayer {
|
|||
return this.makeMbLayerId('circle');
|
||||
}
|
||||
|
||||
_getMbTextLayerId() {
|
||||
return this.makeMbLayerId('text');
|
||||
}
|
||||
|
||||
_getMbSymbolLayerId() {
|
||||
return this.makeMbLayerId('symbol');
|
||||
}
|
||||
|
@ -774,6 +820,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
getMbLayerIds() {
|
||||
return [
|
||||
this._getMbPointLayerId(),
|
||||
this._getMbTextLayerId(),
|
||||
this._getMbSymbolLayerId(),
|
||||
this._getMbLineLayerId(),
|
||||
this._getMbPolygonLayerId(),
|
||||
|
@ -781,12 +828,7 @@ export class VectorLayer extends AbstractLayer {
|
|||
}
|
||||
|
||||
ownsMbLayerId(mbLayerId) {
|
||||
return (
|
||||
this._getMbPointLayerId() === mbLayerId ||
|
||||
this._getMbLineLayerId() === mbLayerId ||
|
||||
this._getMbPolygonLayerId() === mbLayerId ||
|
||||
this._getMbSymbolLayerId() === mbLayerId
|
||||
);
|
||||
return this.getMbLayerIds().includes(mbLayerId);
|
||||
}
|
||||
|
||||
ownsMbSourceId(mbSourceId) {
|
||||
|
|
|
@ -18,6 +18,9 @@ const EXPECTED_JOIN_VALUES = {
|
|||
};
|
||||
|
||||
const VECTOR_SOURCE_ID = 'n1t6f';
|
||||
const CIRCLE_STYLE_LAYER_INDEX = 0;
|
||||
const FILL_STYLE_LAYER_INDEX = 2;
|
||||
const LINE_STYLE_LAYER_INDEX = 3;
|
||||
|
||||
export default function({ getPageObjects, getService }) {
|
||||
const PageObjects = getPageObjects(['maps']);
|
||||
|
@ -82,19 +85,21 @@ export default function({ getPageObjects, getService }) {
|
|||
const layersForVectorSource = mapboxStyle.layers.filter(mbLayer => {
|
||||
return mbLayer.id.startsWith(VECTOR_SOURCE_ID);
|
||||
});
|
||||
|
||||
// Color is dynamically obtained from eui source lib
|
||||
const dynamicColor = layersForVectorSource[0].paint['circle-stroke-color'];
|
||||
const dynamicColor =
|
||||
layersForVectorSource[CIRCLE_STYLE_LAYER_INDEX].paint['circle-stroke-color'];
|
||||
|
||||
//circle layer for points
|
||||
expect(layersForVectorSource[0]).to.eql(
|
||||
expect(layersForVectorSource[CIRCLE_STYLE_LAYER_INDEX]).to.eql(
|
||||
_.set(MAPBOX_STYLES.POINT_LAYER, 'paint.circle-stroke-color', dynamicColor)
|
||||
);
|
||||
|
||||
//fill layer
|
||||
expect(layersForVectorSource[1]).to.eql(MAPBOX_STYLES.FILL_LAYER);
|
||||
expect(layersForVectorSource[FILL_STYLE_LAYER_INDEX]).to.eql(MAPBOX_STYLES.FILL_LAYER);
|
||||
|
||||
//line layer for borders
|
||||
expect(layersForVectorSource[2]).to.eql(
|
||||
expect(layersForVectorSource[LINE_STYLE_LAYER_INDEX]).to.eql(
|
||||
_.set(MAPBOX_STYLES.LINE_LAYER, 'paint.line-color', dynamicColor)
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue