Skip to content

Commit 7510616

Browse files
committed
fix: dominican republic issue, add speed to bar, fix cartogram
1 parent 2af20b9 commit 7510616

8 files changed

Lines changed: 405 additions & 61 deletions

File tree

data/data_date_nat.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
def find_match(nationality, country_names):
3737
nationality_lower = nationality.lower().strip()
38+
country_names.sort(key = len, reverse = True)
3839
for name in country_names:
3940
if nationality_lower in name.lower() or name.lower() in nationality_lower:
4041
return name
@@ -64,7 +65,6 @@ def find_match(nationality, country_names):
6465
lambda n: find_match(n, all_names)
6566
)
6667

67-
# Merge country metadata (without population columns — those are in pop_long)
6868
country_meta = all_countries[["name", "country-code", "alpha-2"]].copy()
6969
merged = pd.merge(
7070
grouped,
@@ -75,11 +75,16 @@ def find_match(nationality, country_names):
7575
)
7676
merged = merged.rename(columns={"country-code": "ID", "alpha-2":"alpha2"})
7777

78+
def exceptions(series):
79+
if series.iloc[0] == "Scotland":
80+
return "United Kingdom"
81+
return series.iloc[0]
82+
7883
merged_agg = (
7984
merged
8085
.groupby(["ID", "alpha2", "year"], dropna=False)
8186
.agg(
82-
nationality=("nationality", "first"),
87+
nationality=("nationality", exceptions),
8388
counts=("counts", "sum"),
8489
)
8590
.reset_index()

data/data_nationality.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ def find_match(nationality, country_names):
2828
return aliases[nationality]
2929
return None
3030

31-
# TODO: figure out how to map scotland
3231
nationalities["nationality"] = nationalities["nationality"].apply(lambda n: re.findall(r"[\w'\s]+", str(n))).explode("nationality")
3332
nationalities["nationality"] = nationalities["nationality"].str.lstrip()
3433
nationalities = nationalities.groupby(['nationality']).size().reset_index(name='counts')

data/datasets/population.csv

Lines changed: 267 additions & 0 deletions
Large diffs are not rendered by default.

website/config/_default/params.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fingerprintAlgorithm = "sha256"
3636
recentLimit = 5
3737

3838
[article]
39-
showDate = true
39+
showDate = false
4040
showDateUpdated = false
4141
showAuthor = true
4242
showBreadcrumbs = true
@@ -47,8 +47,8 @@ fingerprintAlgorithm = "sha256"
4747
showHeadingAnchors = true
4848
showPagination = true
4949
invertPagination = false
50-
showReadingTime = true
51-
showTableOfContents = true
50+
showReadingTime = false
51+
showTableOfContents = false
5252
showTaxonomies = false
5353
showWordCount = false
5454
showComments = false

website/content/festivities.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

website/content/visualizations/bar-race/index.md

Lines changed: 107 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,16 @@ description: "Bar race representing books published by each author nationality o
55
tags: ["d3", "visualization"]
66
layout: "simple"
77
---
8-
Toggle the button to see the race with data scaled by inhabitants. Please wait for the race to end to scale the data :)
8+
This vizualisation represents the amount of authors from a country over time. There is also the possibility to scale it per million of inhabitants. The data spans from 2013 to 2022, that is because these are the ranges available in the international bestsellers dataset.
9+
We have chosen to only show the first 10 countries.
10+
11+
This allows us to see that even though the United States publish more books, they do not have the biggest ratio of authors per million of inhabitants. Using the scaled view allows us to see tha Iceland has about 32 authors per million inhabitants in 2022, which by far the country with the most authors overall.
12+
It is good to see the top 3 of countries change, when scaled it is Iceland, Norway and Spain otherwise it is the United States, France and Spain. Spain seems to have a high enough amount of authors that even when scaled it remains in the top 3.
13+
14+
15+
16+
17+
*Toggle the button to see the race with data scaled by inhabitants. Please note that the toggle is disabled while the race is running :)*
918
<!-- prettier-ignore-start -->
1019
{{< d3 >}}
1120
const n = 10;
@@ -15,17 +24,21 @@ const margin = { top: 20, right: 6, bottom: 6, left: 50 };
1524
const width = container.clientWidth - margin.left - margin.right;
1625
const height = margin.top + barSize * n + margin.bottom;
1726

27+
1828
const svg = d3.select(container).append("svg")
1929
.attr("width", width + margin.left + margin.right)
2030
.attr("height", height + margin.top + margin.bottom)
2131
.append("g")
2232
.attr("transform", `translate(${margin.left},${margin.top})`);
2333

34+
d3.select(container).style("position", "relative");
35+
2436
const isDark = document.documentElement.classList.contains("dark");
2537
const labelColor = isDark ? congoColors.neutral100 : congoColors.neutral700;
2638

2739
// --- Toggle ---
2840
let useScaled = false;
41+
let animDuration = 250;
2942

3043
const toggleWrapper = d3.select(container).insert("div", "svg")
3144
.style("margin-bottom", "10px")
@@ -74,6 +87,43 @@ toggleWrapper.append("span")
7487
.style("font-size", "15px")
7588
.style("color", congoColors.neutral700);
7689

90+
toggleWrapper.append("span")
91+
.text("Speed:")
92+
.style("font-size", "15px")
93+
.style("color", congoColors.neutral700)
94+
.style("margin-left", "20px");
95+
96+
97+
const speedSlider = toggleWrapper.append("input")
98+
.attr("type", "range")
99+
.attr("min", 50)
100+
.attr("max", 1000)
101+
.attr("value", 250)
102+
.attr("step", 50)
103+
.style("accent-color", congoColors.primary300)
104+
.style("cursor", "pointer");
105+
106+
107+
const speedLabel = toggleWrapper.append("span")
108+
.text("1x")
109+
.style("font-size", "15px")
110+
.style("min-width", "35px")
111+
.style("color", congoColors.neutral700);
112+
113+
114+
// --- Toggle ---
115+
const tooltip = d3.select(container).append("div")
116+
.style("position", "absolute")
117+
.style("background", isDark ? "#333" : "#fff")
118+
.style("color", isDark ? "#fff" : "#333")
119+
.style("border", "1px solid #ccc")
120+
.style("border-radius", "6px")
121+
.style("padding", "4px 10px")
122+
.style("font-size", "13px")
123+
.style("pointer-events", "none")
124+
.style("opacity", 0)
125+
.style("transition", "opacity 0.15s");
126+
77127
function toFlag(alpha2) {
78128
if (!alpha2 || alpha2.length !== 2) return "🏳";
79129
return String.fromCodePoint(
@@ -111,6 +161,16 @@ d3.csv("{{< asset-url "data/nat_date.csv" >}}").then(data => {
111161
.rangeRound([margin.top, margin.top + barSize * (n + 1 + 0.1)])
112162
.padding(0.1);
113163

164+
speedSlider.on("input", function(event) {
165+
animDuration = 1050 - +event.target.value;
166+
// Invert so higher slider = faster, display as multiplier
167+
const mult = (250 / animDuration).toFixed(1);
168+
speedLabel.text(`${mult}x`);
169+
170+
svg.selectAll("*").interrupt();
171+
run(keyframes);
172+
});
173+
114174
function rank(valueFn) {
115175
const arr = Array.from(nationalities, nationality => ({
116176
nationality,
@@ -170,7 +230,17 @@ d3.csv("{{< asset-url "data/nat_date.csv" >}}").then(data => {
170230
.attr("height", y.bandwidth())
171231
.attr("x", x(0))
172232
.attr("y", d => y((prev.get(d) || d).rank))
173-
.attr("width", d => Math.max(0, x((prev.get(d) || d).counts) - x(0))),
233+
.attr("width", d => Math.max(0, x((prev.get(d) || d).counts) - x(0)))
234+
.on("mouseover", (event, d) => {
235+
tooltip.style("opacity", 1).text(d.nationality);
236+
})
237+
.on("mousemove", (event) => {
238+
const [x, y] = d3.pointer(event, container);
239+
tooltip
240+
.style("left", `${x + 12}px`)
241+
.style("top", `${y - 28}px`);
242+
})
243+
.on("mouseout", () => tooltip.style("opacity", 0)),
174244
update => update,
175245
exit => exit.transition(transition).remove()
176246
.attr("y", d => y((next.get(d) || d).rank))
@@ -195,11 +265,21 @@ d3.csv("{{< asset-url "data/nat_date.csv" >}}").then(data => {
195265
.attr("dy", "0.35em")
196266
.attr("text-anchor", "end")
197267
.attr("opacity", 0)
198-
.text(d => natToFlag.get(d.nationality) ?? "🏳"),
199-
update => update,
200-
exit => exit.transition(transition).remove()
201-
.attr("y", d => y((next.get(d) || d).rank) + y.bandwidth() / 2)
202-
.attr("opacity", 0)
268+
.text(d => natToFlag.get(d.nationality) ?? "🏳")
269+
.on("mouseover", (event, d) => {
270+
tooltip.style("opacity", 1).text(d.nationality);
271+
})
272+
.on("mousemove", (event) => {
273+
const rect = container.getBoundingClientRect();
274+
tooltip
275+
.style("left", (event.clientX - rect.left + 12) + "px")
276+
.style("top", (event.clientY - rect.top - 28) + "px");
277+
})
278+
.on("mouseout", () => tooltip.style("opacity", 0)),
279+
update => update,
280+
exit => exit.transition(transition).remove()
281+
.attr("y", d => y((next.get(d) || d).rank) + y.bandwidth() / 2)
282+
.attr("opacity", 0)
203283
)
204284
.call(flag => flag.transition(transition)
205285
.attr("y", d => y(d.rank) + y.bandwidth() / 2)
@@ -278,23 +358,23 @@ d3.csv("{{< asset-url "data/nat_date.csv" >}}").then(data => {
278358
};
279359
}
280360

281-
let running = false;
361+
let runId = 0;
362+
363+
async function run(kf) {
364+
const myId = ++runId; // claim a unique ID for this run
282365

283-
async function run(kf) {
284-
if (running) return;
285-
running = true;
286-
checkbox.attr("disabled", true).style("opacity", "0.4");
287-
toggleWrapper.style("opacity", "0.4").style("pointer-events", "none");
288-
svg.selectAll("*").remove();
366+
svg.selectAll("*").remove();
289367

290-
const updateBars = bars(svg);
291-
const updateFlags = flags(svg);
292-
const updateValueTags = valueTags(svg);
293-
const updateAxis = axis(svg);
294-
const updateTicker = ticker(svg);
368+
const updateBars = bars(svg);
369+
const updateFlags = flags(svg);
370+
const updateValueTags = valueTags(svg);
371+
const updateAxis = axis(svg);
372+
const updateTicker = ticker(svg);
295373

374+
try {
296375
for (const keyframe of kf) {
297-
const transition = svg.transition().duration(250).ease(d3.easeLinear);
376+
if (runId !== myId) break;
377+
const transition = svg.transition().duration(animDuration).ease(d3.easeLinear);
298378
x.domain([0, d3.max(keyframe[1], d => d.counts)]);
299379
updateAxis(keyframe, transition);
300380
updateBars(keyframe, transition);
@@ -303,21 +383,22 @@ d3.csv("{{< asset-url "data/nat_date.csv" >}}").then(data => {
303383
updateTicker(keyframe, transition);
304384
await transition.end();
305385
}
306-
running = false;
307-
checkbox.attr("disabled", null).style("opacity", "1");
308-
toggleWrapper.style("opacity", "1").style("pointer-events", "auto");
386+
} catch {
309387
}
388+
}
310389

311-
run(keyframes);
390+
run(keyframes)
312391

313-
checkbox.on("change", function() {
314-
useScaled = this.checked;
392+
checkbox.on("change", function(event) {
393+
useScaled = event.target.checked;
315394
knob.style("background-color", useScaled ? congoColors.primary500 : congoColors.primary300);
316395
knob.select(".knob-inner").style("transform", useScaled ? "translateX(22px)" : "translateX(0)");
317396

318397
formatNumber = useScaled ? formatScaled : formatRaw;
319398
keyframes = buildKeyframes(useScaled ? "counts" : "counts_raw");
320399
({ prev, next } = getPrevNext(keyframes));
400+
401+
svg.selectAll("*").interrupt();
321402
run(keyframes);
322403
});
323404
});

website/content/visualizations/cartogram/index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ description: "Map that scales countries by the number of books published by auth
55
tags: ["d3", "visualization"]
66
layout: "simple"
77
---
8-
Toggle the button to discover the scaled map !
8+
This map explores the voices amplified by the publishing industry, by scaling the countries on the map by the number of the authors from these countries. This deformed map, called a cartogram, shows us that as expected most published authors come from European and North America. The United States, Italy and France are some of the countries with the most published authors from our dataset. It should be mentionned that this vizualisation was made with the international bestsellers dataset. This means that it might be skewed towards books published by bigger countries with more reach. We tried finding other datasets with author origin but this one was the best we found. Sadly, our dataset covered few African, Central American and Central Asian authors.
9+
10+
*Toggle the button to discover the scaled map !*
911
<!-- prettier-ignore-start -->
1012
<script src="https://unpkg.com/topojson@3/dist/topojson.min.js"></script>
1113
<script src="{{< asset-url "js/cartogram.js" >}}"></script>
@@ -172,12 +174,12 @@ Promise.all([
172174
.on("mousemove", onMousemove)
173175
.on("mouseout", onMouseout);
174176

175-
// Draw cartogram countries
177+
// Draw normal map first
176178
const paths = svg.selectAll(".carto-country")
177179
.data(cartoFeatures)
178180
.enter().append("path")
179181
.attr("class", "carto-country")
180-
.attr("d", carto.path)
182+
.attr("d", (d, i) => staticPath(normalFeatures[i])) // ← use staticPath initially
181183
.attr("fill", color)
182184
.attr("stroke", congoColors.neutral100)
183185
.attr("stroke-width", 0.5)

website/static/data/nat_date.csv

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ ID,alpha2,year,nationality,counts,counts_raw
117117
208,DK,2019,Denmark,0.344,2
118118
208,DK,2021,Denmark,0.8537,5
119119
208,DK,2022,Denmark,0.1694,1
120-
212,DM,2018,Dominican Republic,14.6683,1
121-
212,DM,2019,Dominican Republic,58.9275,4
120+
214,DO,2018,Dominican Republic,0.0927,1
121+
214,DO,2019,Dominican Republic,0.3672,4
122122
233,EE,2020,Estonia,0.7522,1
123123
246,FI,2014,Finland,0.1831,1
124124
246,FI,2015,Finland,0.73,4
@@ -180,15 +180,6 @@ ID,alpha2,year,nationality,counts,counts_raw
180180
364,IR,2016,Iran,0.0119,1
181181
364,IR,2021,Iran,0.0113,1
182182
368,IQ,2016,Iraq,0.026,1
183-
372,IE,2014,Ireland,1.9323,9
184-
372,IE,2015,Ireland,1.2761,6
185-
372,IE,2016,Ireland,1.0498,5
186-
372,IE,2017,Ireland,0.4143,2
187-
372,IE,2018,Ireland,0.6125,3
188-
372,IE,2019,Ireland,0.4019,2
189-
372,IE,2020,Ireland,1.1905,6
190-
372,IE,2021,Ireland,0.9784,5
191-
372,IE,2022,Ireland,1.151,6
192183
376,IL,2014,Israel,0.4869,4
193184
376,IL,2015,Israel,0.4773,4
194185
376,IL,2016,Israel,0.117,1
@@ -251,9 +242,6 @@ ID,alpha2,year,nationality,counts,counts_raw
251242
508,MZ,2015,Mozambique,0.0377,1
252243
508,MZ,2016,Mozambique,0.0366,1
253244
508,MZ,2017,Mozambique,0.0355,1
254-
512,OM,2020,Romania,0.2211,1
255-
512,OM,2021,Romania,0.6666,3
256-
512,OM,2022,Romania,0.2114,1
257245
528,NL,2013,Netherlands,0.2975,5
258246
528,NL,2015,Netherlands,0.2361,4
259247
528,NL,2016,Netherlands,0.2349,4
@@ -267,8 +255,8 @@ ID,alpha2,year,nationality,counts,counts_raw
267255
554,NZ,2020,New Zealand,0.3943,2
268256
554,NZ,2021,New Zealand,0.1967,1
269257
554,NZ,2022,New Zealand,0.1968,1
270-
562,NE,2015,Nigeria,0.0502,1
271-
562,NE,2018,Nigeria,0.1803,4
258+
566,NG,2015,Nigeria,0.0052,1
259+
566,NG,2018,Nigeria,0.0195,4
272260
578,NO,2013,Norway,1.3781,7
273261
578,NO,2014,Norway,1.1679,6
274262
578,NO,2015,Norway,0.9636,5
@@ -301,6 +289,9 @@ ID,alpha2,year,nationality,counts,counts_raw
301289
620,PT,2020,Portugal,0.0971,1
302290
620,PT,2021,Portugal,0.0965,1
303291
620,PT,2022,Portugal,0.0958,1
292+
642,RO,2020,Romania,0.0519,1
293+
642,RO,2021,Romania,0.1569,3
294+
642,RO,2022,Romania,0.0525,1
304295
643,RU,2013,Russia,0.0626,9
305296
643,RU,2014,Russia,0.0416,6
306297
643,RU,2018,Russia,0.0275,4
@@ -379,15 +370,15 @@ ID,alpha2,year,nationality,counts,counts_raw
379370
818,EG,2020,Egypt,0.0091,1
380371
818,EG,2022,Egypt,0.0444,5
381372
826,GB,2013,United Kingdom,0.3118,20
382-
826,GB,2014,United Kingdom,0.6964,45
383-
826,GB,2015,Scotland,0.5685,37
384-
826,GB,2016,Scotland,0.5182,34
385-
826,GB,2017,United Kingdom,0.5761,38
386-
826,GB,2018,United Kingdom,0.4073,27
387-
826,GB,2019,United Kingdom,0.5853,39
388-
826,GB,2020,United Kingdom,0.5544,37
389-
826,GB,2021,United Kingdom,0.4628,31
390-
826,GB,2022,United Kingdom,0.429,29
373+
826,GB,2014,Ireland,0.8357,54
374+
826,GB,2015,Ireland,0.6606,43
375+
826,GB,2016,Ireland,0.5944,39
376+
826,GB,2017,Ireland,0.6064,40
377+
826,GB,2018,Ireland,0.4526,30
378+
826,GB,2019,Ireland,0.6153,41
379+
826,GB,2020,Ireland,0.6443,43
380+
826,GB,2021,Ireland,0.5374,36
381+
826,GB,2022,Ireland,0.5177,35
391382
834,TZ,2021,Tanzania,0.0159,1
392383
840,US,2013,United States,0.2684,85
393384
840,US,2014,United States,0.4385,140

0 commit comments

Comments
 (0)