[Maps] show custom color ramps in legend (#53780)

This commit is contained in:
Thomas Neirynck 2020-01-05 20:05:47 -05:00 committed by GitHub
parent 58da936968
commit c19151d474
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 541 additions and 89 deletions

View file

@ -113,7 +113,7 @@ export const ColorStops = ({ colorStops = [{ stop: 0, color: DEFAULT_COLOR }], o
display="rowCompressed"
>
<div>
<EuiFlexGroup responsive={false} alignItems="center" gutterSize="s">
<EuiFlexGroup responsive={false} alignItems="center" gutterSize="xs">
<EuiFlexItem>{stopInput}</EuiFlexItem>
<EuiFlexItem>{colorInput}</EuiFlexItem>
</EuiFlexGroup>

View file

@ -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 { VectorStyle } from '../../vector_style';
import { getColorRampCenterColor } from '../../../color_utils';
export function extractColorFromStyleProperty(colorStyleProperty, defaultColor) {
if (!colorStyleProperty) {
return defaultColor;
}
if (colorStyleProperty.type === VectorStyle.STYLE_TYPE.STATIC) {
return colorStyleProperty.options.color;
}
// Do not use dynamic color unless configuration is complete
if (!colorStyleProperty.options.field || !colorStyleProperty.options.field.name) {
return defaultColor;
}
// return middle of gradient for dynamic style property
if (colorStyleProperty.options.useCustomColorRamp) {
if (
!colorStyleProperty.options.customColorRamp ||
!colorStyleProperty.options.customColorRamp.length
) {
return defaultColor;
}
// favor the lowest color in even arrays
const middleIndex = Math.floor((colorStyleProperty.options.customColorRamp.length - 1) / 2);
return colorStyleProperty.options.customColorRamp[middleIndex].color;
}
return getColorRampCenterColor(colorStyleProperty.options.color);
}

View file

@ -7,13 +7,11 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { dynamicColorShape, staticColorShape } from '../style_option_shapes';
import { CircleIcon } from './circle_icon';
import { LineIcon } from './line_icon';
import { PolygonIcon } from './polygon_icon';
import { SymbolIcon } from './symbol_icon';
import { VectorStyle } from '../../vector_style';
import { getColorRampCenterColor } from '../../../color_utils';
import { VECTOR_STYLES } from '../../vector_style_defaults';
export class VectorIcon extends Component {
state = {
@ -48,16 +46,16 @@ export class VectorIcon extends Component {
if (this.state.isLinesOnly) {
const style = {
stroke: extractColorFromStyleProperty(this.props.lineColor, 'grey'),
stroke: this.props.getColorForProperty(VECTOR_STYLES.LINE_COLOR, true),
strokeWidth: '4px',
};
return <LineIcon style={style} />;
}
const style = {
stroke: extractColorFromStyleProperty(this.props.lineColor, 'none'),
stroke: this.props.getColorForProperty(VECTOR_STYLES.LINE_COLOR, false),
strokeWidth: '1px',
fill: extractColorFromStyleProperty(this.props.fillColor, 'grey'),
fill: this.props.getColorForProperty(VECTOR_STYLES.FILL_COLOR, false),
};
if (!this.state.isPointsOnly) {
@ -79,45 +77,8 @@ export class VectorIcon extends Component {
}
}
function extractColorFromStyleProperty(colorStyleProperty, defaultColor) {
if (!colorStyleProperty) {
return defaultColor;
}
if (colorStyleProperty.type === VectorStyle.STYLE_TYPE.STATIC) {
return colorStyleProperty.options.color;
}
// Do not use dynamic color unless configuration is complete
if (!colorStyleProperty.options.field || !colorStyleProperty.options.field.name) {
return defaultColor;
}
// return middle of gradient for dynamic style property
if (colorStyleProperty.options.useCustomColorRamp) {
if (
!colorStyleProperty.options.customColorRamp ||
!colorStyleProperty.options.customColorRamp.length
) {
return defaultColor;
}
// favor the lowest color in even arrays
const middleIndex = Math.floor((colorStyleProperty.options.customColorRamp.length - 1) / 2);
return colorStyleProperty.options.customColorRamp[middleIndex].color;
}
return getColorRampCenterColor(colorStyleProperty.options.color);
}
const colorStylePropertyShape = PropTypes.shape({
type: PropTypes.string.isRequired,
options: PropTypes.oneOfType([dynamicColorShape, staticColorShape]).isRequired,
});
VectorIcon.propTypes = {
fillColor: colorStylePropertyShape,
lineColor: colorStylePropertyShape,
getColorForProperty: PropTypes.func.isRequired,
symbolId: PropTypes.string,
loadIsPointsOnly: PropTypes.func.isRequired,
loadIsLinesOnly: PropTypes.func.isRequired,

View file

@ -9,16 +9,12 @@ 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 defaultProps = {
loadIsPointsOnly: () => {
return isPointsOnly;
},
loadIsLinesOnly: () => {
return isLinesOnly;
},
const styles = {
fillColor: {
type: VectorStyle.STYLE_TYPE.STATIC,
options: {
@ -36,6 +32,30 @@ const defaultProps = {
},
};
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;

View file

@ -46,7 +46,15 @@ export class VectorStyleLegend extends Component {
render() {
return this.state.styles.map(style => {
return <Fragment key={style.getStyleName()}>{style.renderLegendDetailRow()}</Fragment>;
return (
<Fragment key={style.getStyleName()}>
{style.renderLegendDetailRow({
loadIsLinesOnly: this.props.loadIsLinesOnly,
loadIsPointsOnly: this.props.loadIsPointsOnly,
symbolId: this.props.symbolId,
})}
</Fragment>
);
});
}
}

View file

@ -111,7 +111,7 @@ export class StaticDynamicStyleRow extends Component {
});
return (
<EuiFlexGroup gutterSize="s">
<EuiFlexGroup gutterSize="xs">
<EuiFlexItem
className={isDynamic ? 'mapStaticDynamicSylingOption__dynamicSizeHack' : undefined}
>

View file

@ -0,0 +1,105 @@
// 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 ranged legend 1`] = `
<RangedStyleLegendRow
fieldLabel="foobar_label"
header={
<ColorGradient
colorRampName="Blues"
/>
}
maxLabel="100_format"
minLabel="0_format"
propertyLabel="Border color"
/>
`;

View file

@ -0,0 +1,56 @@
/*
* 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 _ 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,
};
}
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);
}
}
componentDidUpdate() {
this._loadParams();
}
componentWillUnmount() {
this._isMounted = false;
}
componentDidMount() {
this._isMounted = true;
this._loadParams();
}
render() {
if (this.state.label === EMPTY_VALUE) {
return null;
}
return this.props.style.renderBreakedLegend({
fieldLabel: this.state.label,
isLinesOnly: this.state.isLinesOnly,
isPointsOnly: this.state.isPointsOnly,
symbolId: this.props.symbolId,
});
}
}

View file

@ -7,11 +7,9 @@
import React from 'react';
import _ from 'lodash';
import { RangedStyleLegendRow } from '../../../components/ranged_style_legend_row';
import { getVectorStyleLabel } from '../../components/get_vector_style_label';
const EMPTY_VALUE = '';
export class DynamicLegendRow extends React.Component {
export class OrdinalLegend extends React.Component {
constructor() {
super();
this._isMounted = false;
@ -28,6 +26,13 @@ export class DynamicLegendRow extends React.Component {
}
}
_formatValue(value) {
if (value === EMPTY_VALUE) {
return value;
}
return this.props.style.formatField(value);
}
componentDidUpdate() {
this._loadParams();
}
@ -40,14 +45,6 @@ export class DynamicLegendRow extends React.Component {
this._isMounted = true;
this._loadParams();
}
_formatValue(value) {
if (value === EMPTY_VALUE) {
return value;
}
return this.props.style.formatField(value);
}
render() {
const fieldMeta = this.props.style.getFieldMeta();
@ -70,10 +67,10 @@ export class DynamicLegendRow extends React.Component {
return (
<RangedStyleLegendRow
header={this.props.style.renderLegendHeader()}
header={this.props.style.renderRangeLegendHeader()}
minLabel={minLabel}
maxLabel={maxLabel}
propertyLabel={getVectorStyleLabel(this.props.style.getStyleName())}
propertyLabel={this.props.style.getDisplayStyleName()}
fieldLabel={this.state.label}
/>
);

View file

@ -10,6 +10,9 @@ import { getComputedFieldName } from '../style_util';
import { getColorRampStops } from '../../color_utils';
import { ColorGradient } from '../../components/color_gradient';
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiToolTip } from '@elastic/eui';
import { VectorIcon } from '../components/legend/vector_icon';
import { VECTOR_STYLES } from '../vector_style_defaults';
export class DynamicColorProperty extends DynamicStyleProperty {
syncCircleColorWithMb(mbLayerId, mbMap, alpha) {
@ -64,6 +67,14 @@ export class DynamicColorProperty extends DynamicStyleProperty {
return !this.isCustomColorRamp();
}
isRanged() {
return !this.isCustomColorRamp();
}
hasBreaks() {
return this.isCustomColorRamp();
}
_getMbColor() {
const isDynamicConfigComplete =
_.has(this._options, 'field.name') && _.has(this._options, 'color');
@ -117,11 +128,95 @@ export class DynamicColorProperty extends DynamicStyleProperty {
return getColorRampStops(this._options.color);
}
renderLegendHeader() {
renderRangeLegendHeader() {
if (this._options.color) {
return <ColorGradient colorRampName={this._options.color} />;
} else {
return null;
}
}
_renderStopIcon(color, isLinesOnly, isPointsOnly, symbolId) {
if (this.getStyleName() === VECTOR_STYLES.LABEL_COLOR) {
const style = { color: color };
return (
<EuiText size={'xs'} style={style}>
Tx
</EuiText>
);
}
const loadIsLinesOnly = () => {
return isLinesOnly;
};
const loadIsPointsOnly = () => {
return isPointsOnly;
};
const getColorForProperty = (styleProperty, isLinesOnly) => {
if (isLinesOnly) {
return color;
}
return this.getStyleName() === styleProperty ? color : 'none';
};
return (
<VectorIcon
symbolId={symbolId}
loadIsPointsOnly={loadIsPointsOnly}
loadIsLinesOnly={loadIsLinesOnly}
getColorForProperty={getColorForProperty}
/>
);
}
_renderColorbreaks({ isLinesOnly, isPointsOnly, symbolId }) {
if (!this._options.customColorRamp) {
return null;
}
return this._options.customColorRamp.map((config, index) => {
const value = this.formatField(config.stop);
return (
<EuiFlexItem key={index}>
<EuiFlexGroup direction={'row'} gutterSize={'none'}>
<EuiFlexItem>
<EuiText size={'xs'}>{value}</EuiText>
</EuiFlexItem>
<EuiFlexItem>
{this._renderStopIcon(config.color, isLinesOnly, isPointsOnly, symbolId)}
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
);
});
}
renderBreakedLegend({ fieldLabel, isPointsOnly, isLinesOnly, symbolId }) {
return (
<div>
<EuiSpacer size="s" />
<EuiFlexGroup direction={'column'} gutterSize={'none'}>
{this._renderColorbreaks({
isPointsOnly,
isLinesOnly,
symbolId,
})}
</EuiFlexGroup>
<EuiFlexGroup gutterSize="xs" justifyContent="spaceAround">
<EuiFlexItem grow={false}>
<EuiToolTip position="top" title={this.getDisplayStyleName()} content={fieldLabel}>
<EuiText className="eui-textTruncate" size="xs" style={{ maxWidth: '180px' }}>
<small>
<strong>{fieldLabel}</strong>
</small>
</EuiText>
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
}
}

View file

@ -0,0 +1,103 @@
/*
* 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.
*/
// eslint-disable-next-line no-unused-vars
import React from 'react';
import { shallow } from 'enzyme';
import { VECTOR_STYLES } from '../vector_style_defaults';
import { DynamicColorProperty } from './dynamic_color_property';
const mockField = {
async getLabel() {
return 'foobar_label';
},
getName() {
return 'foobar';
},
supportsFieldMeta() {
return true;
},
};
test('Should render ranged legend', async () => {
const colorStyle = new DynamicColorProperty(
{
color: 'Blues',
},
VECTOR_STYLES.LINE_COLOR,
mockField,
() => {
return { min: 0, max: 100 };
},
() => {
return x => x + '_format';
}
);
const legendRow = colorStyle.renderLegendDetailRow({
loadIsPointsOnly: () => {
return true;
},
loadIsLinesOnly: () => {
return 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 () => {
const colorStyle = new DynamicColorProperty(
{
useCustomColorRamp: true,
customColorRamp: [
{
stop: 0,
color: '#FF0000',
},
{
stop: 10,
color: '#00FF00',
},
],
},
VECTOR_STYLES.LINE_COLOR,
mockField,
() => {
return { min: 0, max: 100 };
},
() => {
return x => x + '_format';
}
);
const legendRow = colorStyle.renderLegendDetailRow({
loadIsPointsOnly: () => {
return true;
},
loadIsLinesOnly: () => {
return 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

@ -146,7 +146,7 @@ export class DynamicSizeProperty extends DynamicStyleProperty {
);
}
renderLegendHeader() {
renderRangeLegendHeader() {
let icons;
if (this.getStyleName() === VECTOR_STYLES.LINE_WIDTH) {
icons = getLineWidthIcons();
@ -157,7 +157,7 @@ export class DynamicSizeProperty extends DynamicStyleProperty {
}
return (
<EuiFlexGroup gutterSize="s" justifyContent="spaceBetween" alignItems="center">
<EuiFlexGroup gutterSize="xs" justifyContent="spaceBetween" alignItems="center">
{icons.map((icon, index) => {
const isLast = index === icons.length - 1;
let spacer;

View file

@ -8,9 +8,10 @@ import _ from 'lodash';
import { AbstractStyleProperty } from './style_property';
import { DEFAULT_SIGMA } from '../vector_style_defaults';
import { STYLE_TYPE } from '../../../../../common/constants';
import { DynamicLegendRow } from './components/dynamic_legend_row';
import { scaleValue } from '../style_util';
import React from 'react';
import { OrdinalLegend } from './components/ordinal_legend';
import { CategoricalLegend } from './components/categorical_legend';
export class DynamicStyleProperty extends AbstractStyleProperty {
static type = STYLE_TYPE.DYNAMIC;
@ -38,6 +39,14 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
return true;
}
hasBreaks() {
return false;
}
isRanged() {
return true;
}
isComplete() {
return !!this._field;
}
@ -75,6 +84,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
}
pluckStyleMetaFromFeatures(features) {
if (!this.isOrdinal()) {
return null;
}
const name = this.getField().getName();
let min = Infinity;
let max = -Infinity;
@ -97,6 +110,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
}
pluckStyleMetaFromFieldMetaData(fieldMetaData) {
if (!this.isOrdinal()) {
return null;
}
const realFieldName = this._field.getESDocFieldName
? this._field.getESDocFieldName()
: this._field.getName();
@ -120,13 +137,13 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
}
formatField(value) {
if (!this.getField()) {
if (this.getField()) {
const fieldName = this.getField().getName();
const fieldFormatter = this._getFieldFormatter(fieldName);
return fieldFormatter ? fieldFormatter(value) : value;
} else {
return value;
}
const fieldName = this.getField().getName();
const fieldFormatter = this._getFieldFormatter(fieldName);
return fieldFormatter ? fieldFormatter(value) : value;
}
getMbValue(value) {
@ -144,7 +161,32 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
return valueAsFloat;
}
renderLegendDetailRow() {
return <DynamicLegendRow style={this} />;
renderBreakedLegend() {
return null;
}
_renderCategoricalLegend({ loadIsPointsOnly, loadIsLinesOnly, symbolId }) {
return (
<CategoricalLegend
style={this}
loadIsLinesOnly={loadIsLinesOnly}
loadIsPointsOnly={loadIsPointsOnly}
symbolId={symbolId}
/>
);
}
_renderRangeLegend() {
return <OrdinalLegend style={this} />;
}
renderLegendDetailRow({ loadIsPointsOnly, loadIsLinesOnly, symbolId }) {
if (this.isRanged()) {
return this._renderRangeLegend();
} else if (this.hasBreaks()) {
return this._renderCategoricalLegend({ loadIsPointsOnly, loadIsLinesOnly, symbolId });
} else {
return null;
}
}
}

View file

@ -32,8 +32,4 @@ export class DynamicTextProperty extends DynamicStyleProperty {
isScaled() {
return false;
}
renderHeader() {
return null;
}
}

View file

@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { getVectorStyleLabel } from '../components/get_vector_style_label';
export class AbstractStyleProperty {
constructor(options, styleName) {
this._options = options;
@ -36,11 +37,15 @@ export class AbstractStyleProperty {
return this._options || {};
}
renderLegendHeader() {
renderRangeLegendHeader() {
return null;
}
renderLegendDetailRow() {
return null;
}
getDisplayStyleName() {
return getVectorStyleLabel(this.getStyleName());
}
}

View file

@ -38,6 +38,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 { extractColorFromStyleProperty } from './components/legend/extract_color_from_style_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];
@ -386,18 +387,37 @@ export class VectorStyle extends AbstractStyle {
return _.get(this._descriptor, '__styleMeta', {});
};
getIcon = () => {
const styles = this.getRawProperties();
const symbolId = this.arePointsSymbolizedAsCircles()
_getSymbolId() {
return this.arePointsSymbolizedAsCircles()
? undefined
: 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();
return (
<VectorIcon
loadIsPointsOnly={this._getIsPointsOnly}
loadIsLinesOnly={this._getIsLinesOnly}
fillColor={styles[VECTOR_STYLES.FILL_COLOR]}
lineColor={styles[VECTOR_STYLES.LINE_COLOR]}
symbolId={symbolId}
getColorForProperty={this._getColorForProperty}
/>
);
};
@ -431,7 +451,12 @@ export class VectorStyle extends AbstractStyle {
renderLegendDetails() {
return (
<VectorStyleLegend getLegendDetailStyleProperties={this._getLegendDetailStyleProperties} />
<VectorStyleLegend
getLegendDetailStyleProperties={this._getLegendDetailStyleProperties}
loadIsPointsOnly={this._getIsPointsOnly}
loadIsLinesOnly={this._getIsLinesOnly}
symbolId={this._getSymbolId()}
/>
);
}