Skip to content

Commit f891cb5

Browse files
committed
fix: remove cartogram
1 parent cd86492 commit f891cb5

3 files changed

Lines changed: 127 additions & 167 deletions

File tree

website/config/_default/params.toml

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
@@ -67,16 +67,3 @@ fingerprintAlgorithm = "sha256"
6767

6868
[taxonomy]
6969
showTermCount = true
70-
71-
[fathomAnalytics]
72-
# site = "ABC12345"
73-
74-
#[umamiAnalytics]
75-
# site = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
76-
# region = "eu" # Can be either "eu" or "us"
77-
78-
[verification]
79-
# google = ""
80-
# bing = ""
81-
# pinterest = ""
82-
# yandex = ""

website/content/_index.md

Lines changed: 125 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -19,154 +19,128 @@ A powerful, lightweight visualization for COM-480 built with Hugo, Tailwind CSS.
1919
- [Languages](visualizations/languages/): see the distribution of books by language as a waffle chart.
2020
- [Publishers](visualizations/publishers/): compare gender representation across major publishers.
2121
- [Library](visualizations/library/): browse and filter books on an interactive shelf.
22-
23-
### Scale countries by amount of books published by author's from these countries
24-
25-
26-
## Cartogram
27-
28-
<!-- prettier-ignore-start -->
29-
<script src="https://unpkg.com/topojson@3/dist/topojson.min.js"></script>
30-
<script src="{{< asset-url "js/cartogram.js" >}}"></script>
31-
32-
{{< d3 >}}
33-
const width = container.clientWidth;
34-
const height = 500;
35-
const svg = d3.select(container).append("svg")
36-
.attr("width", width)
37-
.attr("height", height);
38-
39-
const genderLabels = {
40-
"m": "Male",
41-
"w": "Female",
42-
"w;m": "Female & Male",
43-
"m;m": "Male & Male",
44-
"m;m;m": "Male & Male & Male",
45-
"w;w": "Female & Female"
46-
};
47-
const genders = Object.keys(genderLabels);
48-
const isDark = document.documentElement.classList.contains("dark");
49-
const labelColor = isDark ? congoColors.neutral100 : "#000000";
50-
51-
const selector = d3.select(container).insert("div", "svg")
52-
.style("margin-bottom", "10px");
53-
selector.append("label")
54-
.text("Select gender: ")
55-
.style("color", labelColor);
56-
const select = selector.append("select")
57-
.style("margin-bottom", "8px")
58-
.style("padding", "6px 12px")
59-
.style("background", congoColors.primary400)
60-
.style("color", congoColors.neutral100)
61-
.style("border", "none")
62-
.style("border-radius", "4px")
63-
.style("cursor", "pointer");
64-
65-
Promise.all([
66-
d3.json("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"),
67-
d3.csv("{{< asset-url "data/nationalities.csv" >}}")
68-
]).then(([topology, data]) => {
69-
const dataById = new Map(
70-
data
71-
.filter(d => d["ID"] && d["ID"] !== "nan")
72-
.map(d => [+d["ID"], { counts: +d["counts"], name: d["nationality"] }])
73-
);
74-
const nameById = new Map(
75-
topology.objects.countries.geometries.map(d => [+d.id, d.properties?.name ?? "Unknown"])
76-
);
77-
78-
79-
// Split geometries
80-
const problematicIDs = [10, 643, 242]; // Antarctica, Russia
81-
const cartoGeometries = topology.objects.countries.geometries
82-
.filter(d => !problematicIDs.includes(+d.id));
83-
84-
const staticGeometries = topology.objects.countries.geometries
85-
.filter(d => problematicIDs.includes(+d.id)); // Russia yes, Antarctica no
86-
87-
88-
const values = cartoGeometries.map(d => dataById.get(+d.id)?.counts ?? 0);
89-
90-
const lo = d3.min(values), hi = d3.max(values);
91-
92-
const scale = d3.scaleLinear().domain([lo, hi]).range([1, 20]);
93-
const colorScale = d3.scaleSequentialLog(d3.interpolate(
94-
congoColors.neutral100,
95-
congoColors.primary500
96-
)).domain([1, hi]);
97-
98-
const color = d => {
99-
const counts = dataById.get(+d.id)?.counts ?? 0;
100-
return counts === 0 ? congoColors.neutral100 : colorScale(counts);
101-
};
102-
103-
// Tooltip handlers
104-
const onMouseover = (event, d) => {
105-
const id = +d.id;
106-
const entry = dataById.get(id);
107-
const name = entry?.name ?? nameById.get(id) ?? "Unknown";
108-
const counts = entry?.counts ?? 0;
109-
tooltip.style("opacity", 1)
110-
.html(`<strong>${name}</strong><br/>${counts} book${counts !== 1 ? "s" : ""}`);
111-
};
112-
113-
const onMousemove = (event) => {
114-
const [x, y] = d3.pointer(event, container);
115-
tooltip
116-
.style("left", `${x + 12}px`)
117-
.style("top", `${y - 28}px`);
118-
};
119-
120-
const onMouseout = () => tooltip.style("opacity", 0);
121-
122-
carto
123-
.properties(d => ({ id: d.ID }))
124-
.value(d => scale(dataById.get(+d.id)?.counts ?? 0));
125-
126-
const features = carto(topology, cartoGeometries).features;
127-
const cartoFeatures = carto(topology, cartoGeometries).features;
128-
const normalFeatures = cartoGeometries.map(d => topojson.feature(topology, d));
129-
130-
// Draw exluded countries because of anti-meridian as static layer first
131-
svg.selectAll(".static-country")
132-
.data(staticGeometries.map(d => topojson.feature(topology, d)))
133-
.enter().append("path")
134-
.attr("class", "static-country")
135-
.attr("d", staticPath)
136-
.attr("fill", color)
137-
.attr("stroke", congoColors.neutral100)
138-
.attr("stroke-width", 0.5)
139-
.on("mouseover", onMouseover)
140-
.on("mousemove", onMousemove)
141-
.on("mouseout", onMouseout);
142-
143-
// Draw cartogram countries
144-
const paths = svg.selectAll(".carto-country")
145-
.data(cartoFeatures)
146-
.enter().append("path")
147-
.attr("class", "carto-country")
148-
.attr("d", carto.path)
149-
.attr("fill", color)
150-
.attr("stroke", congoColors.neutral100)
151-
.attr("stroke-width", 0.5)
152-
.on("mouseover", onMouseover)
153-
.on("mousemove", onMousemove)
154-
.on("mouseout", onMouseout);
155-
156-
// Toggle between distorted and normal
157-
button.on("click", () => {
158-
distorted = !distorted;
159-
button.text(distorted ? "Show Normal Map" : "Show Cartogram");
160-
161-
paths.transition().duration(750)
162-
.attr("d", (d, i) => distorted
163-
? carto.path(d)
164-
: staticPath(normalFeatures[i])
165-
);
166-
});
167-
168-
}).catch(err => {
169-
console.error("Error loading data:", err);
170-
});
171-
{{< /d3 >}}
172-
<!-- prettier-ignore-end -->
22+
## Scale countries by amount of books published by author's from these countries
23+
# Cartogram
24+
!-- prettier-ignore-start -->
25+
script src="https://unpkg.com/topojson@3/dist/topojson.min.js"></script>
26+
script src="{{< asset-url "js/cartogram.js" >}}"></script>
27+
{< d3 >}}
28+
onst width = container.clientWidth;
29+
onst height = 500;
30+
onst svg = d3.select(container).append("svg")
31+
.attr("width", width)
32+
.attr("height", height);
33+
onst genderLabels = {
34+
"m": "Male",
35+
"w": "Female",
36+
"w;m": "Female & Male",
37+
"m;m": "Male & Male",
38+
"m;m;m": "Male & Male & Male",
39+
"w;w": "Female & Female"
40+
;
41+
onst genders = Object.keys(genderLabels);
42+
onst isDark = document.documentElement.classList.contains("dark");
43+
onst labelColor = isDark ? congoColors.neutral100 : "#000000";
44+
onst selector = d3.select(container).insert("div", "svg")
45+
.style("margin-bottom", "10px");
46+
elector.append("label")
47+
.text("Select gender: ")
48+
.style("color", labelColor);
49+
onst select = selector.append("select")
50+
.style("margin-bottom", "8px")
51+
.style("padding", "6px 12px")
52+
.style("background", congoColors.primary400)
53+
.style("color", congoColors.neutral100)
54+
.style("border", "none")
55+
.style("border-radius", "4px")
56+
.style("cursor", "pointer");
57+
romise.all([
58+
d3.json("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"),
59+
d3.csv("{{< asset-url "data/nationalities.csv" >}}")
60+
).then(([topology, data]) => {
61+
const dataById = new Map(
62+
data
63+
.filter(d => d["ID"] && d["ID"] !== "nan")
64+
.map(d => [+d["ID"], { counts: +d["counts"], name: d["nationality"] }])
65+
);
66+
const nameById = new Map(
67+
topology.objects.countries.geometries.map(d => [+d.id, d.properties?.name ?? "Unknown"])
68+
);
69+
// Split geometries
70+
const problematicIDs = [10, 643, 242]; // Antarctica, Russia
71+
const cartoGeometries = topology.objects.countries.geometries
72+
.filter(d => !problematicIDs.includes(+d.id));
73+
const staticGeometries = topology.objects.countries.geometries
74+
.filter(d => problematicIDs.includes(+d.id)); // Russia yes, Antarctica no
75+
const values = cartoGeometries.map(d => dataById.get(+d.id)?.counts ?? 0);
76+
const lo = d3.min(values), hi = d3.max(values);
77+
const scale = d3.scaleLinear().domain([lo, hi]).range([1, 20]);
78+
const colorScale = d3.scaleSequentialLog(d3.interpolate(
79+
congoColors.neutral100,
80+
congoColors.primary500
81+
)).domain([1, hi]);
82+
const color = d => {
83+
const counts = dataById.get(+d.id)?.counts ?? 0;
84+
return counts === 0 ? congoColors.neutral100 : colorScale(counts);
85+
};
86+
// Tooltip handlers
87+
const onMouseover = (event, d) => {
88+
const id = +d.id;
89+
const entry = dataById.get(id);
90+
const name = entry?.name ?? nameById.get(id) ?? "Unknown";
91+
const counts = entry?.counts ?? 0;
92+
tooltip.style("opacity", 1)
93+
.html(`<strong>${name}</strong><br/>${counts} book${counts !== 1 ? "s" : ""}`);
94+
};
95+
const onMousemove = (event) => {
96+
const [x, y] = d3.pointer(event, container);
97+
tooltip
98+
.style("left", `${x + 12}px`)
99+
.style("top", `${y - 28}px`);
100+
};
101+
const onMouseout = () => tooltip.style("opacity", 0);
102+
carto
103+
.properties(d => ({ id: d.ID }))
104+
.value(d => scale(dataById.get(+d.id)?.counts ?? 0));
105+
const features = carto(topology, cartoGeometries).features;
106+
const cartoFeatures = carto(topology, cartoGeometries).features;
107+
const normalFeatures = cartoGeometries.map(d => topojson.feature(topology, d));
108+
// Draw exluded countries because of anti-meridian as static layer first
109+
svg.selectAll(".static-country")
110+
.data(staticGeometries.map(d => topojson.feature(topology, d)))
111+
.enter().append("path")
112+
.attr("class", "static-country")
113+
.attr("d", staticPath)
114+
.attr("fill", color)
115+
.attr("stroke", congoColors.neutral100)
116+
.attr("stroke-width", 0.5)
117+
.on("mouseover", onMouseover)
118+
.on("mousemove", onMousemove)
119+
.on("mouseout", onMouseout);
120+
// Draw cartogram countries
121+
const paths = svg.selectAll(".carto-country")
122+
.data(cartoFeatures)
123+
.enter().append("path")
124+
.attr("class", "carto-country")
125+
.attr("d", carto.path)
126+
.attr("fill", color)
127+
.attr("stroke", congoColors.neutral100)
128+
.attr("stroke-width", 0.5)
129+
.on("mouseover", onMouseover)
130+
.on("mousemove", onMousemove)
131+
.on("mouseout", onMouseout);
132+
// Toggle between distorted and normal
133+
button.on("click", () => {
134+
distorted = !distorted;
135+
button.text(distorted ? "Show Normal Map" : "Show Cartogram");
136+
paths.transition().duration(750)
137+
.attr("d", (d, i) => distorted
138+
? carto.path(d)
139+
: staticPath(normalFeatures[i])
140+
);
141+
});
142+
).catch(err => {
143+
console.error("Error loading data:", err);
144+
);
145+
{< /d3 >}}
146+
!-- prettier-ignore-end -->

website/content/festivities.svg

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

0 commit comments

Comments
 (0)