Merge pull request #444 from orangemug/feature/issue-433

Added color swatch to <FeatureLayerPopup/>
This commit is contained in:
Orange Mug 2019-05-18 19:15:27 +01:00 committed by GitHub
commit da456b08fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 17 deletions

View file

@ -1,6 +1,7 @@
import React from 'react' import React from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import LayerIcon from '../icons/LayerIcon' import LayerIcon from '../icons/LayerIcon'
import {latest, expression, function as styleFunction} from '@mapbox/mapbox-gl-style-spec'
function groupFeaturesBySourceLayer(features) { function groupFeaturesBySourceLayer(features) {
const sources = {} const sources = {}
@ -28,7 +29,59 @@ function groupFeaturesBySourceLayer(features) {
class FeatureLayerPopup extends React.Component { class FeatureLayerPopup extends React.Component {
static propTypes = { static propTypes = {
onLayerSelect: PropTypes.func.isRequired, onLayerSelect: PropTypes.func.isRequired,
features: PropTypes.array features: PropTypes.array,
zoom: PropTypes.number,
}
_getFeatureColor(feature, zoom) {
try {
const paintProps = feature.layer.paint;
let propName;
if(paintProps.hasOwnProperty("text-color") && paintProps["text-color"]) {
propName = "text-color";
}
else if (paintProps.hasOwnProperty("fill-color") && paintProps["fill-color"]) {
propName = "fill-color";
}
else if (paintProps.hasOwnProperty("line-color") && paintProps["line-color"]) {
propName = "line-color";
}
else if (paintProps.hasOwnProperty("fill-extrusion-color") && paintProps["fill-extrusion-color"]) {
propName = "fill-extrusion-color";
}
if(propName) {
const propertySpec = latest["paint_"+feature.layer.type][propName];
let color = feature.layer.paint[propName];
if(typeof(color) === "object") {
if(color.stops) {
color = styleFunction.convertFunction(color, propertySpec);
}
const exprResult = expression.createExpression(color, propertySpec);
const val = exprResult.value.evaluate({
zoom: zoom
}, feature);
return val.toString();
}
else {
return color;
}
}
else {
// Default color
return "black";
}
}
// This is quite complex, just incase there's an edgecase we're missing
// always return black if we get an unexpected error.
catch (err) {
console.error("Unable to get feature color, error:", err);
return "black";
}
} }
render() { render() {
@ -36,9 +89,18 @@ class FeatureLayerPopup extends React.Component {
const items = Object.keys(sources).map(vectorLayerId => { const items = Object.keys(sources).map(vectorLayerId => {
const layers = sources[vectorLayerId].map((feature, idx) => { const layers = sources[vectorLayerId].map((feature, idx) => {
return <label const featureColor = this._getFeatureColor(feature, this.props.zoom);
return <div
key={idx} key={idx}
className="maputnik-popup-layer" className="maputnik-popup-layer"
>
<div
className="maputnik-popup-layer__swatch"
style={{background: featureColor}}
></div>
<label
className="maputnik-popup-layer__label"
onClick={() => { onClick={() => {
this.props.onLayerSelect(feature.layer.id) this.props.onLayerSelect(feature.layer.id)
}} }}
@ -51,6 +113,7 @@ class FeatureLayerPopup extends React.Component {
{feature.layer.id} {feature.layer.id}
{feature.counter && <span> × {feature.counter}</span>} {feature.counter && <span> × {feature.counter}</span>}
</label> </label>
</div>
}) })
return <div key={vectorLayerId}> return <div key={vectorLayerId}>
<div className="maputnik-popup-layer-id">{vectorLayerId}</div> <div className="maputnik-popup-layer-id">{vectorLayerId}</div>

View file

@ -166,14 +166,18 @@ export default class MapboxGlMap extends React.Component {
if(this.props.inspectModeEnabled) { if(this.props.inspectModeEnabled) {
return renderPopup(<FeaturePropertyPopup features={features} />, tmpNode); return renderPopup(<FeaturePropertyPopup features={features} />, tmpNode);
} else { } else {
return renderPopup(<FeatureLayerPopup features={features} onLayerSelect={this.props.onLayerSelect} />, tmpNode); return renderPopup(<FeatureLayerPopup features={features} onLayerSelect={this.props.onLayerSelect} zoom={this.state.zoom} />, tmpNode);
} }
} }
}) })
map.addControl(inspect) map.addControl(inspect)
map.on("style.load", () => { map.on("style.load", () => {
this.setState({ map, inspect }); this.setState({
map,
inspect,
zoom: map.getZoom()
});
if(this.props.inspectModeEnabled) { if(this.props.inspectModeEnabled) {
inspect.toggleInspector(); inspect.toggleInspector();
} }
@ -185,6 +189,12 @@ export default class MapboxGlMap extends React.Component {
map: this.state.map map: this.state.map
}) })
}) })
map.on("zoom", e => {
this.setState({
zoom: map.getZoom()
});
})
} }
render() { render() {

View file

@ -1,4 +1,15 @@
.maputnik-popup-layer { .maputnik-popup-layer {
display: flex;
flex-direction: row;
}
.maputnik-popup-layer__swatch {
display: inline-block;
width: 5px;
align-content: stretch;
}
.maputnik-popup-layer__label {
display: block; display: block;
color: $color-lowgray; color: $color-lowgray;
cursor: pointer; cursor: pointer;