Skip to content

Commit 7721787

Browse files
committed
Refactor Map component to follow compnent structure
1 parent f352154 commit 7721787

File tree

1 file changed

+94
-109
lines changed
  • assets/js/Ioda/components/map

1 file changed

+94
-109
lines changed
Lines changed: 94 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { Component } from "react";
1+
import React, {useEffect} from "react";
2+
import { useState } from "react";
23
import { Map, TileLayer, GeoJSON } from "react-leaflet";
34
import { humanizeNumber } from "../../utils";
45
import {
@@ -10,160 +11,144 @@ import {
1011
import MapLegend from "./MapLegend";
1112

1213
const mapAccessToken =
13-
"pk.eyJ1Ijoid2ViZXIwMjUiLCJhIjoiY2tmNXp5bG0wMDAzaTMxbWQzcXQ1Y3k2eCJ9.NMu5bfrybATuYQ7HdYvq-g";
14+
"pk.eyJ1Ijoid2ViZXIwMjUiLCJhIjoiY2tmNXp5bG0wMDAzaTMxbWQzcXQ1Y3k2eCJ9.NMu5bfrybATuYQ7HdYvq-g";
1415

1516
const DEFAULT_NONE = "#f2f2f0";
1617

17-
class TopoMap extends Component {
18-
constructor(props) {
19-
super(props);
20-
this.state = {
21-
hoverName: "",
22-
hoverScore: 0,
23-
hoverTooltipDisplay: false,
24-
screenWidthBelow680: false,
25-
};
26-
}
18+
const TopoMap = ({ handleEntityShapeClick, hideLegend, propBounds, topoData, scores, entityType }) => {
19+
const [hoverName, setHoverName] = useState("");
20+
const [hoverScore, setHoverScore] = useState(0);
21+
const [hoverTooltipDisplay, setHoverTooltipDisplay] = useState(false);
22+
const [screenWidthBelow680, setScreenWidthBelow680] = useState(false);
2723

28-
componentDidMount() {
29-
window.addEventListener("resize", this.resize.bind(this), {
30-
passive: true,
31-
});
32-
}
24+
useEffect(() => {
25+
window.addEventListener('resize', resize, { passive: true });
3326

34-
resize() {
27+
// Cleanup function
28+
return () => {
29+
window.removeEventListener('resize', resize);
30+
};
31+
}, []);
32+
33+
const resize = () => {
3534
let screenWidthBelow680 = window.innerWidth <= 680;
36-
if (screenWidthBelow680 !== this.state.screenWidthBelow680) {
37-
this.setState({
38-
screenWidthBelow680: screenWidthBelow680,
39-
});
35+
if (screenWidthBelow680 !== screenWidthBelow680) {
36+
setScreenWidthBelow680(screenWidthBelow680)
4037
}
4138
}
4239

43-
onEachFeature = (feature, layer) => {
40+
const onEachFeature = (feature, layer) => {
4441
layer.on({
45-
mouseover: (e) => this.mouseOverFeature(e, feature),
46-
mouseout: (e) => this.mouseOutFeature(e),
47-
click: () => this.clickFeature(feature),
42+
mouseover: (e) => mouseOverFeature(e, feature),
43+
mouseout: (e) => mouseOutFeature(e),
44+
click: () => clickFeature(feature),
4845
});
4946
};
5047

51-
mouseOverFeature = (e, feature) => {
52-
this.setState(
53-
{
54-
hoverName: feature.properties.name,
55-
hoverScore: feature.properties.score
56-
? humanizeNumber(feature.properties.score)
57-
: 0,
58-
hoverTooltipDisplay: true,
59-
},
60-
() => {
61-
let hoverColor =
62-
e.target.options && e.target.options.fillColor
48+
const mouseOverFeature = (e, feature) => {
49+
50+
setHoverName(feature.properties.name);
51+
setHoverScore(feature.properties.score ? humanizeNumber(feature.properties.score) : 0);
52+
setHoverTooltipDisplay(true);
53+
let hoverColor =
54+
e.target.options && e.target.options.fillColor
6355
? shadeColor(e.target.options.fillColor, -10)
6456
: shadeColor(DEFAULT_NONE, -10);
65-
e.target.setStyle({
66-
fillColor: hoverColor,
67-
color: "#fff",
68-
opacity: 1,
69-
fillOpacity: 0.4,
70-
weight: 3,
71-
dashArray: "2",
72-
});
73-
}
74-
);
57+
e.target.setStyle({
58+
fillColor: hoverColor,
59+
color: "#fff",
60+
opacity: 1,
61+
fillOpacity: 0.4,
62+
weight: 3,
63+
dashArray: "2",
64+
});
7565
};
7666

77-
mouseOutFeature = (e) => {
67+
const mouseOutFeature = (e) => {
7868
e.target.setStyle({
7969
weight: 2,
8070
fillOpacity: 0.7,
8171
});
8272

83-
this.setState({
84-
hoverName: "",
85-
hoverScore: 0,
86-
hoverTooltipDisplay: false,
87-
});
73+
setHoverName("");
74+
setHoverScore(0);
75+
setHoverTooltipDisplay(false);
8876
};
8977

90-
clickFeature = (feature) => {
91-
this.props.handleEntityShapeClick(feature);
78+
const clickFeature = (feature) => {
79+
handleEntityShapeClick(feature);
9280
};
9381

94-
render() {
95-
let { scores } = this.props;
96-
let position = [20, 0];
97-
let zoom = this.state.screenWidthBelow680 ? 1 : 2;
9882

99-
const entityType = this.props.entityType;
83+
let position = [20, 0];
84+
let zoom = screenWidthBelow680 ? 1 : 2;
10085

101-
let bounds = {};
102-
if (entityType === "country") {
103-
bounds = getThresholdBoundsForCountry();
104-
} else if (entityType === "region") {
105-
bounds = getThresholdBoundsForRegion();
106-
}
86+
let bounds = {};
87+
if (entityType === "country") {
88+
bounds = getThresholdBoundsForCountry();
89+
} else if (entityType === "region") {
90+
bounds = getThresholdBoundsForRegion();
91+
}
10792

108-
return (
93+
return (
10994
<div
110-
className="topo-map"
111-
style={{ position: "relative", height: "inherit", width: "100%" }}
95+
className="topo-map"
96+
style={{ position: "relative", height: "inherit", width: "100%" }}
11297
>
11398
<div
114-
className={
115-
this.state.hoverTooltipDisplay
116-
? "topo-map__tooltip topo-map__tooltip-visible"
117-
: "topo-map__tooltip"
118-
}
99+
className={
100+
hoverTooltipDisplay
101+
? "topo-map__tooltip topo-map__tooltip-visible"
102+
: "topo-map__tooltip"
103+
}
119104
>
120105
<p>
121-
{this.state.hoverName}
122-
{this.state.hoverScore !== 0 ? ` - ${this.state.hoverScore}` : null}
106+
{hoverName}
107+
{hoverScore !== 0 ? ` - ${hoverScore}` : null}
123108
</p>
124109
</div>
125110

126-
{!this.props.hideLegend && (
127-
<MapLegend
128-
style={{ position: "absolute", bottom: "1rem", left: "1rem" }}
129-
highThreshold={bounds.high ?? 0}
130-
lowThreshold={bounds.low ?? 0}
131-
/>
111+
{!hideLegend && (
112+
<MapLegend
113+
style={{ position: "absolute", bottom: "1rem", left: "1rem" }}
114+
highThreshold={bounds.high ?? 0}
115+
lowThreshold={bounds.low ?? 0}
116+
/>
132117
)}
133118

134119
<Map
135-
center={this.props.bounds ? null : position}
136-
zoom={this.props.bounds ? null : zoom}
137-
bounds={this.props.bounds ? this.props.bounds : null}
138-
minZoom={1}
139-
scrollWheelZoom={false}
140-
touchZoom={true}
141-
dragging={!this.state.screenWidthBelow680}
142-
style={{ width: "inherit", height: "inherit", overflow: "hidden" }}
120+
center={propBounds ? null : position}
121+
zoom={propBounds ? null : zoom}
122+
bounds={propBounds ? propBounds : null}
123+
minZoom={1}
124+
scrollWheelZoom={false}
125+
touchZoom={true}
126+
dragging={!screenWidthBelow680}
127+
style={{ width: "inherit", height: "inherit", overflow: "hidden" }}
143128
>
144129
<TileLayer
145-
id="mapbox/light-v10"
146-
url={`https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=${mapAccessToken}`}
130+
id="mapbox/light-v10"
131+
url={`https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=${mapAccessToken}`}
147132
/>
148133
<GeoJSON
149-
data={this.props.topoData}
150-
onEachFeature={this.onEachFeature}
151-
style={(feature) => ({
152-
color: "transparent",
153-
weight: 2,
154-
fillColor: !scores
155-
? DEFAULT_NONE
156-
: !feature.properties.score
157-
? DEFAULT_NONE
158-
: getEntityScaleColor(feature.properties.score, entityType),
159-
fillOpacity: !feature.properties.score ? 0.2 : 0.5,
160-
dashArray: "2",
161-
})}
134+
data={topoData}
135+
onEachFeature={onEachFeature}
136+
style={(feature) => ({
137+
color: "transparent",
138+
weight: 2,
139+
fillColor: !scores
140+
? DEFAULT_NONE
141+
: !feature.properties.score
142+
? DEFAULT_NONE
143+
: getEntityScaleColor(feature.properties.score, entityType),
144+
fillOpacity: !feature.properties.score ? 0.2 : 0.5,
145+
dashArray: "2",
146+
})}
162147
/>
163148
</Map>
164149
</div>
165-
);
166-
}
150+
);
151+
167152
}
168153

169-
export default TopoMap;
154+
export default TopoMap;

0 commit comments

Comments
 (0)