Skip to content

Commit 9343d07

Browse files
committed
Fix map bugs
1 parent bc015a9 commit 9343d07

File tree

2 files changed

+82
-43
lines changed

2 files changed

+82
-43
lines changed

src/App.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* {
2+
font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
3+
}

src/App.tsx

Lines changed: 79 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,49 @@ function formatLargeMoney(value: number) {
3434
return `$${valueTo100ths} ${specifier}`;
3535
}
3636

37-
type AmChartsData = ({ id: Valid2DigitCountryCodesWithoutUSA, approxValueFormatted?: string } & Partial<Pick<FlattenedTariffDataEntry, Exclude<keyof FlattenedTariffDataEntry, "id" | "date" | "type">>>) & IComponentDataItem;
37+
interface AmChartsData extends IComponentDataItem, Partial<Pick<FlattenedTariffDataEntry, Exclude<keyof FlattenedTariffDataEntry, "id" | "date" | "type" | "color">>> {
38+
id: Valid2DigitCountryCodesWithoutUSA;
39+
approxValueFormatted?: string;
40+
}
3841

3942
function AmChartsMap() {
40-
const [field, setField] = useState<Exclude<keyof FlattenedTariffDataEntry, "id" | "date" | "type">>("percentValue");
43+
const [field, setField] = useState<Exclude<keyof FlattenedTariffDataEntry, "id" | "date" | "type" | "color">>("percentValue");
4144
const [type, setType] = useState<TariffType>("announced");
4245
const [dateIndex, setDateIndex] = useState<number>(-1);
4346
const [polygonSeries, setPolygonSeries] = useState<am5map.MapPolygonSeries | null>(null);
47+
const [heatLegend, setHeatLegend] = useState<HeatLegend | null>(null);
4448
const dateIndexRef = useRef(dateIndex); // Need to pass this value into a callback in the use effect
4549
const oldData = useRef<AmChartsData[]>([]);
50+
const fieldRef = useRef(field);
51+
52+
useEffect(() => {
53+
if (polygonSeries) {
54+
polygonSeries.set("valueField", field);
55+
polygonSeries.mapPolygons.template.set("tooltipText", field === "percentValue" ? `{name}: {${field}}%` : `{name}: {approxValueFormatted}`);
56+
const originalHeatRule = polygonSeries.get("heatRules")![0];
57+
const newHeatRule = {
58+
...originalHeatRule,
59+
maxValue: field === "percentValue" ? 150 : undefined,
60+
};
61+
polygonSeries.set("heatRules", [newHeatRule]);
62+
}
63+
if (heatLegend) {
64+
heatLegend.setAll({
65+
endValue: field === "percentValue" ? 150 : undefined,
66+
startText: field === "percentValue" ? "0% Tariff" : "$0 Tariffed",
67+
stepCount: field === "percentValue" ? 15 : 100,
68+
})
69+
if (field === "percentValue") {
70+
heatLegend.set("endText", "150% Tariff");
71+
}
72+
}
73+
}, [field]);
4674

4775
useEffect(() => {
76+
let maxValue = 0;
4877
if (polygonSeries) {
4978
const mappedData: AmChartsData[] = dateIndex === -1 ? [] : FLATTENED_TARIFF_DATA.get(dates[dateIndex])!.filter((d) => d.type === type).map(d => {
79+
maxValue = Math.max(maxValue, d[field]);
5080
return {
5181
id: d.id,
5282
[field]: d[field],
@@ -62,10 +92,23 @@ function AmChartsMap() {
6292
const isDifferent = oldItem[field] !== d[field];
6393
return isDifferent;
6494
}).map(d => d.id);
95+
console.log({
96+
mappedData, diffItems,
97+
filtered: mappedData.filter(d => diffItems.includes(d.id)),
98+
});
6599
oldData.current = mappedData;
66100
polygonSeries.mapPolygons.values
67101
.filter(polygon => polygon.dataItem && diffItems.includes((polygon.dataItem as DataItem<AmChartsData>).get("id")))
68-
.forEach(polygon => polygon.appear(1000));
102+
.forEach((polygon) => {
103+
polygon.appear(1000);
104+
});
105+
if (field !== "percentValue") {
106+
const endValue = Math.max(maxValue, 1_000_000);
107+
heatLegend!.setAll({
108+
endValue,
109+
endText: `${formatLargeMoney(endValue)} Tariffed`,
110+
});
111+
}
69112
}
70113
}, [polygonSeries, dateIndex, field, type]);
71114

@@ -79,6 +122,10 @@ function AmChartsMap() {
79122
dateIndexRef.current = dateIndex;
80123
}, [dateIndex]);
81124

125+
useEffect(() => {
126+
fieldRef.current = field;
127+
}, [field]);
128+
82129
useEffect(() => {
83130
// Create root
84131
const root = Root.new("chartdiv", {});
@@ -93,7 +140,6 @@ function AmChartsMap() {
93140
panX: "rotateX",
94141
panY: "none",
95142
projection: am5map.geoMercator(),
96-
// projection: am5map.geoAlbersUsa(),
97143
layout: root.horizontalLayout,
98144
}));
99145

@@ -102,27 +148,25 @@ function AmChartsMap() {
102148
// geoJSON: am5geodataUSALow,
103149
geoJSON: am5geodataWorldLow,
104150
valueField: field,
105-
calculateAggregates: true
151+
calculateAggregates: true,
152+
exclude: ["AQ"], // Hide Antarctica
106153
}));
154+
// chart.seriesContainer.set("paddingBottom", 50);
107155

108156
setPolygonSeries(polygonSeries);
109157

110-
// Hide antartica
111-
polygonSeries.set("exclude", ["AQ"]);
112-
polygonSeries.mapPolygons.template.setAll({
113-
tooltipText: field === "percentValue" ? `{name}: {${field}}%` : `{name}: {approxValueFormatted}`
114-
});
115-
116158
polygonSeries.set("heatRules", [{
117159
target: polygonSeries.mapPolygons.template,
118160
dataField: "value",
119161
min: am5color(0xd3a29f), // Green
120-
max: am5color(0x6f0600), // Red
162+
max: am5color(0x330000), // Red
121163
key: "fill",
122164
minValue: 0,
123-
maxValue: field === "percentValue" ? 50 : undefined,
165+
maxValue: field === "percentValue" ? 150 : undefined,
124166
}]);
125167

168+
polygonSeries.mapPolygons.template.set("tooltipText", field === "percentValue" ? `{name}: {${field}}%` : `{name}: {approxValueFormatted}`);
169+
126170
const heatLegendContainer = chart.children.push(Container.new(root, {
127171
layout: root.horizontalLayout,
128172
// Make this container be on the top of the page (y=0)
@@ -137,15 +181,17 @@ function AmChartsMap() {
137181
orientation: "horizontal",
138182
startColor: am5color(0xd3a29f),
139183
startValue: 0,
140-
endValue: field === "percentValue" ? 50 : undefined,
141-
endColor: am5color(0x6f0600),
142-
startText: "No Tariff",
143-
endText: field === "percentValue" ? "50% Tariff" : "Most Tariffed",
144-
stepCount: field === "percentValue" ? 5 : 100,
184+
endValue: field === "percentValue" ? 150 : undefined,
185+
endColor: am5color(0x330000),
186+
startText: field === "percentValue" ? "0% Tariff" : "$0 Tariffed",
187+
endText: field === "percentValue" ? "150% Tariff" : "Most Tariffed",
188+
stepCount: field === "percentValue" ? 15 : 100,
145189
}));
146190

191+
setHeatLegend(heatLegend);
192+
147193
polygonSeries.mapPolygons.template.events.on("pointerover", function (ev) {
148-
heatLegend.showValue(Number((ev.target.dataItem as DataItem<AmChartsData>).get(field)));
194+
heatLegend.showValue(Number((ev.target.dataItem as DataItem<AmChartsData>).get(fieldRef.current)));
149195
});
150196

151197
heatLegend.startLabel.setAll({
@@ -158,22 +204,6 @@ function AmChartsMap() {
158204
fill: heatLegend.get("endColor")
159205
});
160206

161-
// change this to template when possible
162-
polygonSeries.events.on("datavalidated", function () {
163-
// console.log({ low: polygonSeries.getPrivate("valueLow"), high: polygonSeries.getPrivate("valueHigh") });
164-
// const low = polygonSeries.getPrivate("valueLow")!;
165-
const high = polygonSeries.getPrivate("valueHigh") ?? 0;
166-
// heatLegend.set("startValue", polygonSeries.getPrivate("valueLow"));
167-
// heatLegend.set("endValue", Math.max(polygonSeries.getPrivate("valueHigh") ?? 0, 100));
168-
if (field !== "percentValue") {
169-
const endValue = Math.max(high, 1_000_000);
170-
heatLegend.setAll({
171-
endValue,
172-
endText: formatLargeMoney(endValue),
173-
});
174-
}
175-
})
176-
177207
// Set clicking on "water" to zoom out
178208
chart.chartContainer.get("background")!.events.on("click", function () {
179209
chart.goHome();
@@ -184,12 +214,12 @@ function AmChartsMap() {
184214

185215
const container = chart.children.push(Container.new(root, {
186216
y: am5p100,
187-
centerX: am5p50,
217+
centerX: am5percent(55),
188218
centerY: am5p100,
189-
x: am5percent(50),
219+
x: am5percent(55),
190220
width: am5percent(135),
191221
layout: root.horizontalLayout,
192-
paddingBottom: 10
222+
dy: -10,
193223
}));
194224

195225
const playButton = container.children.push(Button.new(root, {
@@ -204,7 +234,7 @@ function AmChartsMap() {
204234
const slider = container.children.push(Slider.new(root, {
205235
orientation: "horizontal",
206236
start: 0,
207-
centerY: am5p50
237+
centerY: am5p50,
208238
}));
209239

210240
playButton.events.on("click", function () {
@@ -285,7 +315,7 @@ function AmChartsMap() {
285315

286316
const fieldContainer = chart.children.push(Container.new(root, {
287317
layout: root.horizontalLayout,
288-
x: am5percent(15),
318+
x: am5percent(25),
289319
centerX: am5p100,
290320
y: am5percent(100),
291321
dy: -40
@@ -324,15 +354,21 @@ function AmChartsMap() {
324354
return () => {
325355
root.dispose();
326356
}
327-
}, [field]);
357+
}, []);
328358

329-
return <div style={{ width: "100%", height: "95vh" }} id="chartdiv" />
359+
return <div style={{ width: "100%", height: "75vh" }} id="chartdiv" />
330360
}
331361

332362

333363
function App() {
334364
return (
335-
<AmChartsMap />
365+
<div>
366+
<div style={{ textAlign: "center", fontSize: "2rem", marginBottom: "1rem", width: "75%", marginLeft: "auto", marginRight: "auto" }}>
367+
<h1>The Effect of Trump Tariffs</h1>
368+
<p>In under 3 months, Trump has announced and implemented radical tariffs that affect the entire rest of the world. The map shows the approximate value of the tariffs, and attempts to put the insane numbers to scale.</p>
369+
</div>
370+
<AmChartsMap />
371+
</div>
336372
)
337373
}
338374

0 commit comments

Comments
 (0)