Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Maps] show custom color ramps in legend #53780

Merged
merged 21 commits into from
Jan 6, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class StaticDynamicStyleRow extends Component {
});

return (
<EuiFlexGroup gutterSize="s">
<EuiFlexGroup gutterSize="xs">
<EuiFlexItem
className={isDynamic ? 'mapStaticDynamicSylingOption__dynamicSizeHack' : undefined}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
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 {
Expand All @@ -17,12 +15,16 @@ export class DynamicLegendRow extends React.Component {
this._isMounted = false;
this.state = {
label: EMPTY_VALUE,
isPointsOnly: null,
isLinesOnly: null,
};
}

async _loadParams() {
const label = await this.props.style.getField().getLabel();
const newState = { label };
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);
}
Expand All @@ -48,7 +50,7 @@ export class DynamicLegendRow extends React.Component {
return this.props.style.formatField(value);
}

render() {
_renderRangeLegend() {
const fieldMeta = this.props.style.getFieldMeta();

let minLabel = EMPTY_VALUE;
Expand All @@ -70,12 +72,31 @@ 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}
/>
);
}

_renderBreakedLegend() {
return this.props.style.renderBreakedLegend({
fieldLabel: this.state.label,
isLinesOnly: this.state.isLinesOnly,
isPointsOnly: this.state.isPointsOnly,
symbolId: this.props.symbolId,
});
}

render() {
if (this.props.style.isRanged()) {
thomasneirynck marked this conversation as resolved.
Show resolved Hide resolved
thomasneirynck marked this conversation as resolved.
Show resolved Hide resolved
return this._renderRangeLegend();
} else if (this.props.style.hasBreaks()) {
return this._renderBreakedLegend();
} else {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ 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 { LineIcon } from '../components/legend/line_icon';
import { PolygonIcon } from '../components/legend/polygon_icon';
import { CircleIcon } from '../components/legend/circle_icon';
import { SymbolIcon } from '../components/legend/symbol_icon';
import { VECTOR_STYLES } from '../vector_style_defaults';

export class DynamicColorProperty extends DynamicStyleProperty {
syncCircleColorWithMb(mbLayerId, mbMap, alpha) {
Expand Down Expand Up @@ -64,6 +70,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');
Expand Down Expand Up @@ -117,11 +131,105 @@ 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>
);
}

if (isLinesOnly && this.getStyleName() === VECTOR_STYLES.LINE_COLOR) {
thomasneirynck marked this conversation as resolved.
Show resolved Hide resolved
const style = {
stroke: color,
strokeWidth: '4px',
};
return <LineIcon style={style} />;
}

const style = {};

if (this.getStyleName() === VECTOR_STYLES.FILL_COLOR) {
style.fill = color;
style.strokeWidth = '0px';
} else if (this.getStyleName() === VECTOR_STYLES.LINE_COLOR) {
style.fill = 'rgba(255,255,255,0)';
style.stroke = color;
style.strokeWidth = '1px';
}

if (!isPointsOnly) {
return <PolygonIcon style={style} />;
}

if (!symbolId) {
return <CircleIcon style={style} />;
}

const fillColor =
this.getStyleName() === VECTOR_STYLES.FILL_COLOR ? color : 'rgba(255,255,255,0)';
const strokeColor =
this.getStyleName() === VECTOR_STYLES.LINE_COLOR ? color : 'rgba(255,255,255,0)';
return (
<SymbolIcon symbolId={symbolId} fill={fillColor} stroke={strokeColor} strokeWidth={'1px'} />
);
}

_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>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class DynamicSizeProperty extends DynamicStyleProperty {
);
}

renderLegendHeader() {
renderRangeLegendHeader() {
let icons;
if (this.getStyleName() === VECTOR_STYLES.LINE_WIDTH) {
icons = getLineWidthIcons();
Expand All @@ -142,7 +142,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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
return true;
}

hasBreaks() {
return false;
}

isRanged() {
return true;
}

isComplete() {
return !!this._field;
}
Expand Down Expand Up @@ -74,48 +82,56 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
}

pluckStyleMetaFromFeatures(features) {
const name = this.getField().getName();
let min = Infinity;
let max = -Infinity;
for (let i = 0; i < features.length; i++) {
const feature = features[i];
const newValue = parseFloat(feature.properties[name]);
if (!isNaN(newValue)) {
min = Math.min(min, newValue);
max = Math.max(max, newValue);
if (this.isOrdinal()) {
thomasneirynck marked this conversation as resolved.
Show resolved Hide resolved
const name = this.getField().getName();
let min = Infinity;
let max = -Infinity;
for (let i = 0; i < features.length; i++) {
const feature = features[i];
const newValue = parseFloat(feature.properties[name]);
if (!isNaN(newValue)) {
min = Math.min(min, newValue);
max = Math.max(max, newValue);
}
}
}

return min === Infinity || max === -Infinity
? null
: {
min: min,
max: max,
delta: max - min,
};
return min === Infinity || max === -Infinity
? null
: {
min: min,
max: max,
delta: max - min,
};
} else {
return null;
}
}

pluckStyleMetaFromFieldMetaData(fieldMetaData) {
const realFieldName = this._field.getESDocFieldName
? this._field.getESDocFieldName()
: this._field.getName();
const stats = fieldMetaData[realFieldName];
if (!stats) {
if (this.isOrdinal()) {
thomasneirynck marked this conversation as resolved.
Show resolved Hide resolved
const realFieldName = this._field.getESDocFieldName
? this._field.getESDocFieldName()
: this._field.getName();
const stats = fieldMetaData[realFieldName];
if (!stats) {
return null;
}

const sigma = _.get(this.getFieldMetaOptions(), 'sigma', DEFAULT_SIGMA);
const stdLowerBounds = stats.avg - stats.std_deviation * sigma;
const stdUpperBounds = stats.avg + stats.std_deviation * sigma;
const min = Math.max(stats.min, stdLowerBounds);
const max = Math.min(stats.max, stdUpperBounds);
return {
min,
max,
delta: max - min,
isMinOutsideStdRange: stats.min < stdLowerBounds,
isMaxOutsideStdRange: stats.max > stdUpperBounds,
};
} else {
return null;
}

const sigma = _.get(this.getFieldMetaOptions(), 'sigma', DEFAULT_SIGMA);
const stdLowerBounds = stats.avg - stats.std_deviation * sigma;
const stdUpperBounds = stats.avg + stats.std_deviation * sigma;
const min = Math.max(stats.min, stdLowerBounds);
const max = Math.min(stats.max, stdUpperBounds);
return {
min,
max,
delta: max - min,
isMinOutsideStdRange: stats.min < stdLowerBounds,
isMaxOutsideStdRange: stats.max > stdUpperBounds,
};
}

formatField(value) {
Expand All @@ -128,7 +144,14 @@ export class DynamicStyleProperty extends AbstractStyleProperty {
}
}

renderLegendDetailRow() {
return <DynamicLegendRow style={this} />;
renderLegendDetailRow({ loadIsPointsOnly, loadIsLinesOnly, symbolId }) {
return (
<DynamicLegendRow
style={this}
loadIsPointsOnly={loadIsPointsOnly}
loadIsLinesOnly={loadIsLinesOnly}
symbolId={symbolId}
/>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,4 @@ export class DynamicTextProperty extends DynamicStyleProperty {
isScaled() {
return false;
}

renderHeader() {
return null;
}
}
Loading