[Maps] refactor isPointsOnly, isLinesOnly, and isPolygonsOnly to make synchronous (#54067)

* [Maps] refactor isPointsOnly, isLinesOnly, and isPolygonsOnly to make synchronous

* fix jest test

* review feedback

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2020-01-13 07:28:39 -05:00 committed by GitHub
parent e7472e2f00
commit 14df4c096c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 198 additions and 572 deletions

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Renders CircleIcon with correct styles when isPointOnly 1`] = `
exports[`Renders CircleIcon 1`] = `
<CircleIcon
style={
Object {
@ -12,7 +12,7 @@ exports[`Renders CircleIcon with correct styles when isPointOnly 1`] = `
/>
`;
exports[`Renders LineIcon with correct styles when isLineOnly 1`] = `
exports[`Renders LineIcon 1`] = `
<LineIcon
style={
Object {
@ -23,7 +23,7 @@ exports[`Renders LineIcon with correct styles when isLineOnly 1`] = `
/>
`;
exports[`Renders PolygonIcon with correct styles when not line only or not point only 1`] = `
exports[`Renders PolygonIcon 1`] = `
<PolygonIcon
style={
Object {
@ -35,7 +35,7 @@ exports[`Renders PolygonIcon with correct styles when not line only or not point
/>
`;
exports[`Renders SymbolIcon with correct styles when isPointOnly and symbolId provided 1`] = `
exports[`Renders SymbolIcon 1`] = `
<SymbolIcon
fill="#ff0000"
stroke="rgb(106,173,213)"

View file

@ -4,82 +4,51 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { CircleIcon } from './circle_icon';
import { LineIcon } from './line_icon';
import { PolygonIcon } from './polygon_icon';
import { SymbolIcon } from './symbol_icon';
import { VECTOR_STYLES } from '../../vector_style_defaults';
export class VectorIcon extends Component {
state = {
isInitialized: false,
export function VectorIcon({ fillColor, isPointsOnly, isLinesOnly, strokeColor, symbolId }) {
if (isLinesOnly) {
const style = {
stroke: strokeColor,
strokeWidth: '4px',
};
return <LineIcon style={style} />;
}
const style = {
stroke: strokeColor,
strokeWidth: '1px',
fill: fillColor,
};
componentDidMount() {
this._isMounted = true;
this._init();
if (!isPointsOnly) {
return <PolygonIcon style={style} />;
}
componentWillUnmount() {
this._isMounted = false;
if (!symbolId) {
return <CircleIcon style={style} />;
}
async _init() {
const isPointsOnly = await this.props.loadIsPointsOnly();
const isLinesOnly = await this.props.loadIsLinesOnly();
if (this._isMounted) {
this.setState({
isInitialized: true,
isPointsOnly,
isLinesOnly,
});
}
}
render() {
if (!this.state.isInitialized) {
return null;
}
if (this.state.isLinesOnly) {
const style = {
stroke: this.props.getColorForProperty(VECTOR_STYLES.LINE_COLOR, true),
strokeWidth: '4px',
};
return <LineIcon style={style} />;
}
const style = {
stroke: this.props.getColorForProperty(VECTOR_STYLES.LINE_COLOR, false),
strokeWidth: '1px',
fill: this.props.getColorForProperty(VECTOR_STYLES.FILL_COLOR, false),
};
if (!this.state.isPointsOnly) {
return <PolygonIcon style={style} />;
}
if (!this.props.symbolId) {
return <CircleIcon style={style} />;
}
return (
<SymbolIcon
symbolId={this.props.symbolId}
fill={style.fill}
stroke={style.stroke}
strokeWidth={style.strokeWidth}
/>
);
}
return (
<SymbolIcon
symbolId={symbolId}
fill={style.fill}
stroke={style.stroke}
strokeWidth={style.strokeWidth}
/>
);
}
VectorIcon.propTypes = {
getColorForProperty: PropTypes.func.isRequired,
fillColor: PropTypes.string,
isPointsOnly: PropTypes.bool.isRequired,
isLinesOnly: PropTypes.bool.isRequired,
strokeColor: PropTypes.string.isRequired,
symbolId: PropTypes.string,
loadIsPointsOnly: PropTypes.func.isRequired,
loadIsLinesOnly: PropTypes.func.isRequired,
};

View file

@ -8,113 +8,51 @@ import React from 'react';
import { shallow } from 'enzyme';
import { VectorIcon } from './vector_icon';
import { VectorStyle } from '../../vector_style';
import { extractColorFromStyleProperty } from './extract_color_from_style_property';
import { VECTOR_STYLES } from '../../vector_style_defaults';
let isPointsOnly = false;
let isLinesOnly = false;
const styles = {
fillColor: {
type: VectorStyle.STYLE_TYPE.STATIC,
options: {
color: '#ff0000',
},
},
lineColor: {
type: VectorStyle.STYLE_TYPE.DYNAMIC,
options: {
color: 'Blues',
field: {
name: 'prop1',
},
},
},
};
const defaultProps = {
getColorForProperty: (styleProperty, isLinesOnly) => {
if (isLinesOnly) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.LINE_COLOR], 'grey');
}
if (styleProperty === VECTOR_STYLES.LINE_COLOR) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.LINE_COLOR], 'none');
} else if (styleProperty === VECTOR_STYLES.FILL_COLOR) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.FILL_COLOR], 'grey');
} else {
//unexpected
console.error('Cannot return color for properties other then line or fill color');
}
},
loadIsPointsOnly: () => {
return isPointsOnly;
},
loadIsLinesOnly: () => {
return isLinesOnly;
},
};
function configureIsLinesOnly() {
isLinesOnly = true;
isPointsOnly = false;
}
function configureIsPointsOnly() {
isLinesOnly = false;
isPointsOnly = true;
}
function configureNotLineOrPointOnly() {
isLinesOnly = false;
isPointsOnly = false;
}
test('Renders PolygonIcon with correct styles when not line only or not point only', async () => {
configureNotLineOrPointOnly();
const component = shallow(<VectorIcon {...defaultProps} />);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
test('Renders PolygonIcon', () => {
const component = shallow(
<VectorIcon
fillColor="#ff0000"
isPointsOnly={false}
isLinesOnly={false}
strokeColor="rgb(106,173,213)"
/>
);
expect(component).toMatchSnapshot();
});
test('Renders LineIcon with correct styles when isLineOnly', async () => {
configureIsLinesOnly();
const component = shallow(<VectorIcon {...defaultProps} />);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
test('Renders LineIcon', () => {
const component = shallow(
<VectorIcon isPointsOnly={false} isLinesOnly={true} strokeColor="rgb(106,173,213)" />
);
expect(component).toMatchSnapshot();
});
test('Renders CircleIcon with correct styles when isPointOnly', async () => {
configureIsPointsOnly();
const component = shallow(<VectorIcon {...defaultProps} />);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
test('Renders CircleIcon', () => {
const component = shallow(
<VectorIcon
fillColor="#ff0000"
isPointsOnly={true}
isLinesOnly={false}
strokeColor="rgb(106,173,213)"
/>
);
expect(component).toMatchSnapshot();
});
test('Renders SymbolIcon with correct styles when isPointOnly and symbolId provided', async () => {
configureIsPointsOnly();
const component = shallow(<VectorIcon {...defaultProps} symbolId="airfield-15" />);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
test('Renders SymbolIcon', () => {
const component = shallow(
<VectorIcon
fillColor="#ff0000"
isPointsOnly={true}
isLinesOnly={false}
strokeColor="rgb(106,173,213)"
symbolId="airfield-15"
/>
);
expect(component).toMatchSnapshot();
});

View file

@ -4,57 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
import _ from 'lodash';
import React, { Component, Fragment } from 'react';
import React, { Fragment } from 'react';
export class VectorStyleLegend extends Component {
state = {
styles: [],
};
componentDidMount() {
this._isMounted = true;
this._prevStyleDescriptors = undefined;
this._loadRows();
}
componentDidUpdate() {
this._loadRows();
}
componentWillUnmount() {
this._isMounted = false;
}
_loadRows = _.debounce(async () => {
const styles = await this.props.getLegendDetailStyleProperties();
const styleDescriptorPromises = styles.map(async style => {
return {
type: style.getStyleName(),
options: style.getOptions(),
fieldMeta: style.getFieldMeta(),
label: await style.getField().getLabel(),
};
});
const styleDescriptors = await Promise.all(styleDescriptorPromises);
if (this._isMounted && !_.isEqual(styleDescriptors, this._prevStyleDescriptors)) {
this._prevStyleDescriptors = styleDescriptors;
this.setState({ styles: styles });
}
}, 100);
render() {
return this.state.styles.map(style => {
return (
<Fragment key={style.getStyleName()}>
{style.renderLegendDetailRow({
loadIsLinesOnly: this.props.loadIsLinesOnly,
loadIsPointsOnly: this.props.loadIsPointsOnly,
symbolId: this.props.symbolId,
})}
</Fragment>
);
});
}
export function VectorStyleLegend({ isLinesOnly, isPointsOnly, styles, symbolId }) {
return styles.map(style => {
return (
<Fragment key={style.getStyleName()}>
{style.renderLegendDetailRow({
isLinesOnly,
isPointsOnly,
symbolId,
})}
</Fragment>
);
});
}

View file

@ -86,25 +86,14 @@ export class VectorStyleEditor extends Component {
async _loadSupportedFeatures() {
const supportedFeatures = await this.props.layer.getSource().getSupportedShapeTypes();
const isPointsOnly = await this.props.loadIsPointsOnly();
const isLinesOnly = await this.props.loadIsLinesOnly();
if (!this._isMounted) {
return;
}
if (
_.isEqual(supportedFeatures, this.state.supportedFeatures) &&
isPointsOnly === this.state.isPointsOnly &&
isLinesOnly === this.state.isLinesOnly
) {
return;
}
let selectedFeature = VECTOR_SHAPE_TYPES.POLYGON;
if (isPointsOnly) {
if (this.props.isPointsOnly) {
selectedFeature = VECTOR_SHAPE_TYPES.POINT;
} else if (isLinesOnly) {
} else if (this.props.isLinesOnly) {
selectedFeature = VECTOR_SHAPE_TYPES.LINE;
}
@ -112,12 +101,7 @@ export class VectorStyleEditor extends Component {
!_.isEqual(supportedFeatures, this.state.supportedFeatures) ||
selectedFeature !== this.state.selectedFeature
) {
this.setState({
supportedFeatures,
selectedFeature,
isPointsOnly,
isLinesOnly,
});
this.setState({ supportedFeatures, selectedFeature });
}
}

View file

@ -1,98 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Should render categorical legend 1`] = `
<div>
<EuiSpacer
size="s"
/>
<EuiFlexGroup
direction="column"
gutterSize="none"
>
<EuiFlexItem
key="0"
>
<EuiFlexGroup
direction="row"
gutterSize="none"
>
<EuiFlexItem>
<EuiText
size="xs"
>
0_format
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<VectorIcon
getColorForProperty={[Function]}
loadIsLinesOnly={[Function]}
loadIsPointsOnly={[Function]}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem
key="1"
>
<EuiFlexGroup
direction="row"
gutterSize="none"
>
<EuiFlexItem>
<EuiText
size="xs"
>
10_format
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<VectorIcon
getColorForProperty={[Function]}
loadIsLinesOnly={[Function]}
loadIsPointsOnly={[Function]}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup
gutterSize="xs"
justifyContent="spaceAround"
>
<EuiFlexItem
grow={false}
>
<EuiToolTip
content="foobar_label"
delay="regular"
position="top"
title="Border color"
>
<EuiText
className="eui-textTruncate"
size="xs"
style={
Object {
"maxWidth": "180px",
}
}
>
<small>
<strong>
foobar_label
</strong>
</small>
</EuiText>
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
</div>
`;
exports[`Should render categorical legend 1`] = `""`;
exports[`Should render ranged legend 1`] = `
<RangedStyleLegendRow
fieldLabel="foobar_label"
fieldLabel=""
header={
<ColorGradient
colorRampName="Blues"

View file

@ -9,24 +9,13 @@ import _ from 'lodash';
const EMPTY_VALUE = '';
export class CategoricalLegend extends React.Component {
constructor() {
super();
this._isMounted = false;
this.state = {
label: EMPTY_VALUE,
isPointsOnly: null,
isLinesOnly: null,
};
}
state = {
label: EMPTY_VALUE,
};
async _loadParams() {
const label = await this.props.style.getField().getLabel();
const isLinesOnly = await this.props.loadIsLinesOnly();
const isPointsOnly = await this.props.loadIsPointsOnly();
const newState = { label, isLinesOnly, isPointsOnly };
if (this._isMounted && !_.isEqual(this.state, newState)) {
this.setState(newState);
}
componentDidMount() {
this._isMounted = true;
this._loadParams();
}
componentDidUpdate() {
@ -37,9 +26,12 @@ export class CategoricalLegend extends React.Component {
this._isMounted = false;
}
componentDidMount() {
this._isMounted = true;
this._loadParams();
async _loadParams() {
const label = await this.props.style.getField().getLabel();
const newState = { label };
if (this._isMounted && !_.isEqual(this.state, newState)) {
this.setState(newState);
}
}
render() {
@ -48,8 +40,8 @@ export class CategoricalLegend extends React.Component {
}
return this.props.style.renderBreakedLegend({
fieldLabel: this.state.label,
isLinesOnly: this.state.isLinesOnly,
isPointsOnly: this.state.isPointsOnly,
isLinesOnly: this.props.isLinesOnly,
isPointsOnly: this.props.isPointsOnly,
symbolId: this.props.symbolId,
});
}

View file

@ -146,28 +146,14 @@ export class DynamicColorProperty extends DynamicStyleProperty {
);
}
const loadIsLinesOnly = () => {
return isLinesOnly;
};
const loadIsPointsOnly = () => {
return isPointsOnly;
};
const getColorForProperty = (styleProperty, isLinesOnly) => {
if (isLinesOnly) {
return color;
}
return this.getStyleName() === styleProperty ? color : 'none';
};
const fillColor = this.getStyleName() === VECTOR_STYLES.FILL_COLOR ? color : 'none';
return (
<VectorIcon
fillColor={fillColor}
isPointsOnly={isPointsOnly}
isLinesOnly={isLinesOnly}
strokeColor={color}
symbolId={symbolId}
loadIsPointsOnly={loadIsPointsOnly}
loadIsLinesOnly={loadIsLinesOnly}
getColorForProperty={getColorForProperty}
/>
);
}

View file

@ -24,7 +24,7 @@ const mockField = {
},
};
test('Should render ranged legend', async () => {
test('Should render ranged legend', () => {
const colorStyle = new DynamicColorProperty(
{
color: 'Blues',
@ -40,25 +40,15 @@ test('Should render ranged legend', async () => {
);
const legendRow = colorStyle.renderLegendDetailRow({
loadIsPointsOnly: () => {
return true;
},
loadIsLinesOnly: () => {
return false;
},
isPointsOnly: true,
isLinesOnly: false,
});
const component = shallow(legendRow);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
expect(component).toMatchSnapshot();
});
test('Should render categorical legend', async () => {
test('Should render categorical legend', () => {
const colorStyle = new DynamicColorProperty(
{
useCustomColorRamp: true,
@ -84,20 +74,10 @@ test('Should render categorical legend', async () => {
);
const legendRow = colorStyle.renderLegendDetailRow({
loadIsPointsOnly: () => {
return true;
},
loadIsLinesOnly: () => {
return false;
},
isPointsOnly: true,
isLinesOnly: false,
});
const component = shallow(legendRow);
// Ensure all promises resolve
await new Promise(resolve => process.nextTick(resolve));
// Ensure the state changes are reflected
component.update();
expect(component).toMatchSnapshot();
});

View file

@ -165,12 +165,12 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
return null;
}
_renderCategoricalLegend({ loadIsPointsOnly, loadIsLinesOnly, symbolId }) {
_renderCategoricalLegend({ isPointsOnly, isLinesOnly, symbolId }) {
return (
<CategoricalLegend
style={this}
loadIsLinesOnly={loadIsLinesOnly}
loadIsPointsOnly={loadIsPointsOnly}
isPointsOnly={isPointsOnly}
isLinesOnly={isLinesOnly}
symbolId={symbolId}
/>
);
@ -180,11 +180,11 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
return <OrdinalLegend style={this} />;
}
renderLegendDetailRow({ loadIsPointsOnly, loadIsLinesOnly, symbolId }) {
renderLegendDetailRow({ isPointsOnly, isLinesOnly, symbolId }) {
if (this.isRanged()) {
return this._renderRangeLegend();
} else if (this.hasBreaks()) {
return this._renderCategoricalLegend({ loadIsPointsOnly, loadIsLinesOnly, symbolId });
return this._renderCategoricalLegend({ isPointsOnly, isLinesOnly, symbolId });
} else {
return null;
}

View file

@ -17,10 +17,6 @@ export function isOnlySingleFeatureType(featureType, supportedFeatures, hasFeatu
return supportedFeatures[0] === featureType;
}
if (!hasFeatureType) {
return false;
}
const featureTypes = Object.keys(hasFeatureType);
return featureTypes.reduce((isOnlyTargetFeatureType, featureTypeKey) => {
const hasFeature = hasFeatureType[featureTypeKey];

View file

@ -143,8 +143,8 @@ export class VectorStyle extends AbstractStyle {
styleProperties={styleProperties}
symbolDescriptor={this._descriptor.properties[VECTOR_STYLES.SYMBOL]}
layer={layer}
loadIsPointsOnly={this._getIsPointsOnly}
loadIsLinesOnly={this._getIsLinesOnly}
isPointsOnly={this._getIsPointsOnly()}
isLinesOnly={this._getIsLinesOnly()}
onIsTimeAwareChange={onIsTimeAwareChange}
isTimeAware={this.isTimeAware()}
showIsTimeAware={propertiesWithFieldMeta.length > 0}
@ -218,43 +218,57 @@ export class VectorStyle extends AbstractStyle {
async pluckStyleMetaFromSourceDataRequest(sourceDataRequest) {
const features = _.get(sourceDataRequest.getData(), 'features', []);
if (features.length === 0) {
return {};
}
const dynamicProperties = this.getDynamicPropertiesArray();
const supportedFeatures = await this._source.getSupportedShapeTypes();
const isSingleFeatureType = supportedFeatures.length === 1;
if (dynamicProperties.length === 0 && isSingleFeatureType) {
// no meta data to pull from source data request.
return {};
}
let hasPoints = false;
let hasLines = false;
let hasPolygons = false;
for (let i = 0; i < features.length; i++) {
const feature = features[i];
if (!hasPoints && POINTS.includes(feature.geometry.type)) {
hasPoints = true;
}
if (!hasLines && LINES.includes(feature.geometry.type)) {
hasLines = true;
}
if (!hasPolygons && POLYGONS.includes(feature.geometry.type)) {
hasPolygons = true;
const hasFeatureType = {
[VECTOR_SHAPE_TYPES.POINT]: false,
[VECTOR_SHAPE_TYPES.LINE]: false,
[VECTOR_SHAPE_TYPES.POLYGON]: false,
};
if (supportedFeatures.length > 1) {
for (let i = 0; i < features.length; i++) {
const feature = features[i];
if (!hasFeatureType[VECTOR_SHAPE_TYPES.POINT] && POINTS.includes(feature.geometry.type)) {
hasFeatureType[VECTOR_SHAPE_TYPES.POINT] = true;
}
if (!hasFeatureType[VECTOR_SHAPE_TYPES.LINE] && LINES.includes(feature.geometry.type)) {
hasFeatureType[VECTOR_SHAPE_TYPES.LINE] = true;
}
if (
!hasFeatureType[VECTOR_SHAPE_TYPES.POLYGON] &&
POLYGONS.includes(feature.geometry.type)
) {
hasFeatureType[VECTOR_SHAPE_TYPES.POLYGON] = true;
}
}
}
const featuresMeta = {
hasFeatureType: {
[VECTOR_SHAPE_TYPES.POINT]: hasPoints,
[VECTOR_SHAPE_TYPES.LINE]: hasLines,
[VECTOR_SHAPE_TYPES.POLYGON]: hasPolygons,
geometryTypes: {
isPointsOnly: isOnlySingleFeatureType(
VECTOR_SHAPE_TYPES.POINT,
supportedFeatures,
hasFeatureType
),
isLinesOnly: isOnlySingleFeatureType(
VECTOR_SHAPE_TYPES.LINE,
supportedFeatures,
hasFeatureType
),
isPolygonsOnly: isOnlySingleFeatureType(
VECTOR_SHAPE_TYPES.POLYGON,
supportedFeatures,
hasFeatureType
),
},
};
const dynamicProperties = this.getDynamicPropertiesArray();
if (dynamicProperties.length === 0 || features.length === 0) {
// no additional meta data to pull from source data request.
return featuresMeta;
}
dynamicProperties.forEach(dynamicProperty => {
const styleMeta = dynamicProperty.pluckStyleMetaFromFeatures(features);
if (styleMeta) {
@ -291,24 +305,16 @@ export class VectorStyle extends AbstractStyle {
);
}
_isOnlySingleFeatureType = async featureType => {
return isOnlySingleFeatureType(
featureType,
await this._source.getSupportedShapeTypes(),
this._getStyleMeta().hasFeatureType
);
_getIsPointsOnly = () => {
return _.get(this._getStyleMeta(), 'geometryTypes.isPointsOnly', false);
};
_getIsPointsOnly = async () => {
return this._isOnlySingleFeatureType(VECTOR_SHAPE_TYPES.POINT);
_getIsLinesOnly = () => {
return _.get(this._getStyleMeta(), 'geometryTypes.isLinesOnly', false);
};
_getIsLinesOnly = async () => {
return this._isOnlySingleFeatureType(VECTOR_SHAPE_TYPES.LINE);
};
_getIsPolygonsOnly = async () => {
return this._isOnlySingleFeatureType(VECTOR_SHAPE_TYPES.POLYGON);
_getIsPolygonsOnly = () => {
return _.get(this._getStyleMeta(), 'geometryTypes.isPolygonsOnly', false);
};
_getDynamicPropertyByFieldName(fieldName) {
@ -393,50 +399,44 @@ export class VectorStyle extends AbstractStyle {
: this._descriptor.properties.symbol.options.symbolId;
}
_getColorForProperty = (styleProperty, isLinesOnly) => {
const styles = this.getRawProperties();
if (isLinesOnly) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.LINE_COLOR], 'grey');
}
if (styleProperty === VECTOR_STYLES.LINE_COLOR) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.LINE_COLOR], 'none');
} else if (styleProperty === VECTOR_STYLES.FILL_COLOR) {
return extractColorFromStyleProperty(styles[VECTOR_STYLES.FILL_COLOR], 'grey');
} else {
//unexpected
console.error('Cannot return color for properties other then line or fill color');
}
};
getIcon = () => {
const symbolId = this._getSymbolId();
const isLinesOnly = this._getIsLinesOnly();
const strokeColor = isLinesOnly
? extractColorFromStyleProperty(this._descriptor.properties[VECTOR_STYLES.LINE_COLOR], 'grey')
: extractColorFromStyleProperty(
this._descriptor.properties[VECTOR_STYLES.LINE_COLOR],
'none'
);
const fillColor = isLinesOnly
? null
: extractColorFromStyleProperty(
this._descriptor.properties[VECTOR_STYLES.FILL_COLOR],
'grey'
);
return (
<VectorIcon
loadIsPointsOnly={this._getIsPointsOnly}
loadIsLinesOnly={this._getIsLinesOnly}
symbolId={symbolId}
getColorForProperty={this._getColorForProperty}
isPointsOnly={this._getIsPointsOnly()}
isLinesOnly={isLinesOnly}
symbolId={this._getSymbolId()}
strokeColor={strokeColor}
fillColor={fillColor}
/>
);
};
_getLegendDetailStyleProperties = async () => {
const isLinesOnly = await this._getIsLinesOnly();
const isPolygonsOnly = await this._getIsPolygonsOnly();
_getLegendDetailStyleProperties = () => {
return this.getDynamicPropertiesArray().filter(styleProperty => {
const styleName = styleProperty.getStyleName();
if ([VECTOR_STYLES.ICON_ORIENTATION, VECTOR_STYLES.LABEL_TEXT].includes(styleName)) {
return false;
}
if (isLinesOnly) {
if (this._getIsLinesOnly()) {
return LINE_STYLES.includes(styleName);
}
if (isPolygonsOnly) {
if (this._getIsPolygonsOnly()) {
return POLYGON_STYLES.includes(styleName);
}
@ -445,16 +445,15 @@ export class VectorStyle extends AbstractStyle {
};
async hasLegendDetails() {
const styles = await this._getLegendDetailStyleProperties();
return styles.length > 0;
return this._getLegendDetailStyleProperties().length > 0;
}
renderLegendDetails() {
return (
<VectorStyleLegend
getLegendDetailStyleProperties={this._getLegendDetailStyleProperties}
loadIsPointsOnly={this._getIsPointsOnly}
loadIsLinesOnly={this._getIsLinesOnly}
styles={this._getLegendDetailStyleProperties()}
isPointsOnly={this._getIsPointsOnly()}
isLinesOnly={this._getIsLinesOnly()}
symbolId={this._getSymbolId()}
/>
);

View file

@ -159,11 +159,9 @@ describe('pluckStyleMetaFromSourceDataRequest', () => {
const vectorStyle = new VectorStyle({}, new MockSource());
const featuresMeta = await vectorStyle.pluckStyleMetaFromSourceDataRequest(sourceDataRequest);
expect(featuresMeta.hasFeatureType).toEqual({
LINE: false,
POINT: true,
POLYGON: false,
});
expect(featuresMeta.geometryTypes.isPointsOnly).toBe(true);
expect(featuresMeta.geometryTypes.isLinesOnly).toBe(false);
expect(featuresMeta.geometryTypes.isPolygonsOnly).toBe(false);
});
it('Should identify when feature collection only contains lines', async () => {
@ -189,11 +187,9 @@ describe('pluckStyleMetaFromSourceDataRequest', () => {
const vectorStyle = new VectorStyle({}, new MockSource());
const featuresMeta = await vectorStyle.pluckStyleMetaFromSourceDataRequest(sourceDataRequest);
expect(featuresMeta.hasFeatureType).toEqual({
LINE: true,
POINT: false,
POLYGON: false,
});
expect(featuresMeta.geometryTypes.isPointsOnly).toBe(false);
expect(featuresMeta.geometryTypes.isLinesOnly).toBe(true);
expect(featuresMeta.geometryTypes.isPolygonsOnly).toBe(false);
});
});
@ -241,11 +237,9 @@ describe('pluckStyleMetaFromSourceDataRequest', () => {
);
const featuresMeta = await vectorStyle.pluckStyleMetaFromSourceDataRequest(sourceDataRequest);
expect(featuresMeta.hasFeatureType).toEqual({
LINE: false,
POINT: true,
POLYGON: false,
});
expect(featuresMeta.geometryTypes.isPointsOnly).toBe(true);
expect(featuresMeta.geometryTypes.isLinesOnly).toBe(false);
expect(featuresMeta.geometryTypes.isPolygonsOnly).toBe(false);
});
it('Should extract scaled field range', async () => {
@ -275,88 +269,3 @@ describe('pluckStyleMetaFromSourceDataRequest', () => {
});
});
});
describe('checkIfOnlyFeatureType', () => {
describe('source supports single feature type', () => {
it('isPointsOnly should be true when source feature type only supports points', async () => {
const vectorStyle = new VectorStyle(
{},
new MockSource({
supportedShapeTypes: [VECTOR_SHAPE_TYPES.POINT],
})
);
const isPointsOnly = await vectorStyle._getIsPointsOnly();
expect(isPointsOnly).toBe(true);
});
it('isLineOnly should be false when source feature type only supports points', async () => {
const vectorStyle = new VectorStyle(
{},
new MockSource({
supportedShapeTypes: [VECTOR_SHAPE_TYPES.POINT],
})
);
const isLineOnly = await vectorStyle._getIsLinesOnly();
expect(isLineOnly).toBe(false);
});
});
describe('source supports multiple feature types', () => {
it('isPointsOnly should be true when data contains just points', async () => {
const vectorStyle = new VectorStyle(
{
__styleMeta: {
hasFeatureType: {
POINT: true,
LINE: false,
POLYGON: false,
},
},
},
new MockSource({
supportedShapeTypes: Object.values(VECTOR_SHAPE_TYPES),
})
);
const isPointsOnly = await vectorStyle._getIsPointsOnly();
expect(isPointsOnly).toBe(true);
});
it('isPointsOnly should be false when data contains just lines', async () => {
const vectorStyle = new VectorStyle(
{
__styleMeta: {
hasFeatureType: {
POINT: false,
LINE: true,
POLYGON: false,
},
},
},
new MockSource({
supportedShapeTypes: Object.values(VECTOR_SHAPE_TYPES),
})
);
const isPointsOnly = await vectorStyle._getIsPointsOnly();
expect(isPointsOnly).toBe(false);
});
it('isPointsOnly should be false when data contains points, lines, and polygons', async () => {
const vectorStyle = new VectorStyle(
{
__styleMeta: {
hasFeatureType: {
POINT: true,
LINE: true,
POLYGON: true,
},
},
},
new MockSource({
supportedShapeTypes: Object.values(VECTOR_SHAPE_TYPES),
})
);
const isPointsOnly = await vectorStyle._getIsPointsOnly();
expect(isPointsOnly).toBe(false);
});
});
});