-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathchoropleth.jsx
86 lines (70 loc) · 2.58 KB
/
choropleth.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { GeoJSON, FeatureGroup } from 'react-leaflet'
import chroma from 'chroma-js'
import React, { Component, cloneElement, Children } from 'react'
import assign from './assign'
export default class Choropleth extends Component {
isFunction (prop) {
return typeof prop === 'function'
}
getColors() {
const { data, valueProperty, mode, steps, scale, colors: cl } = this.props
const colors = {}
const features = Array.isArray(data) ? data : data.features
const values = features.map(item => this.isFunction(valueProperty)
? valueProperty(item)
: item.properties[valueProperty])
colors.limits = chroma.limits(values, mode, steps - 1)
colors.colors = cl || chroma.scale(scale).colors(steps)
return colors
}
getStyle ({ limits, colors }, feature) {
const { valueProperty, visible = (() => true), style: userStyle } = this.props
if( !(( this.isFunction(visible) && visible(feature) ) || feature.properties[visible]) ) return userStyle
const featureValue = this.isFunction(valueProperty)
? valueProperty(feature)
: feature.properties[valueProperty]
const idx = (!isNaN(featureValue))
? limits.findIndex(lim => featureValue <= lim)
: -1
if(colors[idx]){
const style = {
fillColor: colors[idx]
}
switch (typeof userStyle) {
case 'function':
return assign(userStyle(feature), style)
case 'object':
return assign({}, userStyle, style)
default:
return style
}
} else {
return userStyle
}
}
cloneChildrenWithFeature(props, feature){
const newProps = assign({}, props, { feature })
return Children.map(props.children, child => {
return child ? cloneElement(child, newProps) : null
})
}
render(){
const features = Array.isArray(this.props.data) ? this.props.data : this.props.data.features
const chroms = this.getColors()
const { layerContainer, identity, ...options } = this.props //remove
return (
<FeatureGroup map={this.props.map} layerContainer={layerContainer} ref={ (layer) => layer ? this.leafletElement = layer.leafletElement : null } >
{features.map( (feature, idx) =>
(<GeoJSON
key={(identity) ? identity(feature) : idx}
{...options}
style={this.getStyle(chroms, feature)}
{...this.getStyle(chroms, feature)}
data={feature}
children={this.props.children ? this.cloneChildrenWithFeature(this.props, feature) : this.props.children}
/>)
) }
</FeatureGroup>
)
}
}