Skip to content

Commit 25bf7e8

Browse files
author
Michiel Leyman
authored
Add clickable provinces (#100)
* Update geojson data to include Brussels * Don't enforce lines between class members * Get demographic data * Extend province model * Add provinces to store * Disable bugged rule See issue jsx-eslint/eslint-plugin-react#1875 * Make provinces individually selectable
1 parent 9cd5816 commit 25bf7e8

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed

frontend/.eslintrc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"ImportDeclaration": "never",
1818
"ExportDeclaration": { "multiline": true, "minProperties": 5 }
1919
}],
20-
"react/prop-types": ["error", { "ignore": ["store"] }]
20+
"react/prop-types": ["error", { "ignore": ["store"] }],
21+
"lines-between-class-members": 0,
22+
"react/destructuring-assignment": 0
2123
}
2224
}

frontend/src/api/BaseAPI.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ export default class BaseAPI {
1010
getHospitals() {
1111
return fetch(`${this.BASE_URL}/hospitals`, { headers: this.headers }).then(r => r.json());
1212
}
13+
14+
getDemographics() {
15+
return fetch(`${this.BASE_URL}/population`, { headers: this.headers }).then(r => r.json());
16+
}
1317
}

frontend/src/assets/data/be-provinces.geo.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

frontend/src/components/Explorer/Map.jsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,45 @@ import provincesGeoJSON from '../../assets/data/be-provinces.geo.json';
66

77
import 'leaflet/dist/leaflet.css';
88
import '../../assets/css/explorer/map.css';
9-
import Province from '../../models/Province';
109

1110
const MapLeaflet = ({ store }) => {
12-
const provinces = [];
13-
const { hospitals } = store;
11+
store.addProvince(...provincesGeoJSON.features);
12+
13+
const getProvinceById = id => store.provinces.find(province => province.id === id);
1414

15-
const getColor = feature => ((feature.properties.TX_PROV_DESCR_EN === 'Antwerp') ? 'red' : 'yellow');
16-
const styleMap = feature => ({
17-
fillColor: getColor(feature),
18-
weight: 3,
19-
opacity: 0.65
20-
});
15+
const getColor = (province) => {
16+
if (province.selected) return 'yellow';
17+
return '';
18+
};
19+
20+
const toggleProvinceSelection = (province) => {
21+
province.toggleSelection();
22+
province.layer.setStyle({
23+
fillColor: getColor(province)
24+
});
25+
};
2126

2227
const onEachProvince = (feature, layer) => {
23-
const province = feature.properties.TX_PROV_DESCR_EN;
24-
provinces.push(new Province(feature.properties, layer));
28+
const province = getProvinceById(feature.properties.ID);
2529
layer.on({
26-
click: () => { console.log(province); }
30+
click: () => { toggleProvinceSelection(province); }
2731
});
32+
province.setLayer(layer);
2833
};
2934

35+
const { hospitals } = store;
3036
return (
3137
<Map className="leaflet-container" center={[50.52, 4.3517]} zoom={8} dragging={false} zoomControl={false} scrollWheelZoom={false}>
3238
<TileLayer
3339
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
3440
/>
3541
<GeoJSON
3642
data={provincesGeoJSON}
37-
style={styleMap}
43+
style={{
44+
fillColor: 'yellow',
45+
weight: 3,
46+
opacity: 0.65
47+
}}
3848
onEachFeature={onEachProvince}
3949
/>
4050
{

frontend/src/models/Province.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
import uuid from 'uuid';
1+
import { observable, action } from 'mobx';
22

33
export default class Province {
4-
constructor(province, layer) {
4+
@observable selected = true;
5+
6+
constructor(province) {
57
Object.keys(province).forEach((prop) => {
68
this[prop] = province[prop];
79
});
8-
this.mapLayer = layer;
9-
this.id = uuid();
10+
this.id = this.ID;
11+
}
12+
13+
@action setLayer = (layer) => {
14+
this.layer = layer;
15+
}
16+
17+
@action toggleSelection = () => {
18+
this.selected = !this.selected;
1019
}
1120
}

frontend/src/store/index.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@ import { observable, configure } from 'mobx';
22

33
import API from '../api/BaseAPI';
44
import Hospital from '../models/Hospital';
5+
import Province from '../models/Province';
56

67
configure({ enforceActions: true });
78

89
class Store {
10+
demographics = [];
11+
hospitals = [];
12+
@observable provinces = [];
13+
914
static init = async () => {
1015
const api = new API();
1116
const initialState = {};
17+
initialState.demographics = await api.getDemographics();
1218
initialState.hospitals = await api.getHospitals();
1319
return new Store(initialState);
1420
};
1521

16-
@observable hospitals = [];
17-
18-
constructor({ hospitals }) {
22+
constructor({ demographics, hospitals }) {
1923
this.api = new API();
24+
this.demographics = [...demographics];
2025
this._addHospital(...hospitals);
2126
}
2227

@@ -25,6 +30,12 @@ class Store {
2530
this.hospitals.push(new Hospital(hospital));
2631
});
2732
}
33+
34+
addProvince = (...provinces) => {
35+
provinces.forEach((province) => {
36+
this.provinces.push(new Province(province.properties));
37+
});
38+
}
2839
}
2940

3041
export default Store;

0 commit comments

Comments
 (0)