Skip to content

Commit 40f0b6c

Browse files
committed
better looking country sankey
1 parent 8734fa6 commit 40f0b6c

2 files changed

Lines changed: 96 additions & 15 deletions

File tree

website/js/delegations.js

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,13 @@
601601
const topSports = getTopSports(medalRows, 10);
602602
const filteredRows = medalRows.filter(d => topSports.has(d.sport));
603603

604+
const readableRows =
605+
mode === "country"
606+
? groupSmallCountries(filteredRows, 20)
607+
: filteredRows;
608+
604609
const sourceToMedal = d3.rollups(
605-
filteredRows,
610+
readableRows,
606611
values => d3.sum(values, d => d.value),
607612
d => d.source,
608613
d => d.medal
@@ -614,18 +619,22 @@
614619
each medal-sport flow comes from.
615620
*/
616621
const medalToSport = d3.rollups(
617-
filteredRows,
622+
readableRows,
618623
values => {
619624
const total = d3.sum(values, d => d.value);
620625

621626
const breakdown = d3.rollups(
622627
values,
623-
v => d3.sum(v, d => d.value),
628+
v => ({
629+
value: d3.sum(v, d => d.value),
630+
countries: Array.from(new Set(v.map(d => d.originalSource || d.source))).sort(d3.ascending)
631+
}),
624632
d => d.source
625633
)
626-
.map(([source, value]) => ({
634+
.map(([source, info]) => ({
627635
source,
628-
value
636+
value: info.value,
637+
countries: info.countries
629638
}))
630639
.sort((a, b) => d3.descending(a.value, b.value));
631640

@@ -642,15 +651,19 @@
642651
const medalNames = new Set();
643652
const sportNames = new Set();
644653

645-
filteredRows.forEach(row => {
654+
readableRows.forEach(row => {
646655
sourceNames.add(row.source);
647656
medalNames.add(row.medal);
648657
sportNames.add(row.sport);
649658
});
650659

651660
const orderedSources = mode === "continent"
652661
? continentOrder.filter(source => sourceNames.has(source))
653-
: Array.from(sourceNames).sort(d3.ascending);
662+
: Array.from(sourceNames).sort((a, b) => {
663+
if (a === "Other countries") return 1;
664+
if (b === "Other countries") return -1;
665+
return d3.ascending(a, b);
666+
});
654667

655668
const orderedMedals = medalOrder.filter(medal => medalNames.has(medal));
656669
const orderedSports = Array.from(sportNames).sort(d3.ascending);
@@ -725,6 +738,25 @@
725738
);
726739
}
727740

741+
function groupSmallCountries(rows, limit = 20) {
742+
const topCountries = new Set(
743+
d3.rollups(
744+
rows,
745+
values => d3.sum(values, d => d.value),
746+
d => d.source
747+
)
748+
.sort((a, b) => d3.descending(a[1], b[1]))
749+
.slice(0, limit)
750+
.map(([country]) => country)
751+
);
752+
753+
return rows.map(row => ({
754+
...row,
755+
originalSource: row.source,
756+
source: topCountries.has(row.source) ? row.source : "Other countries"
757+
}));
758+
}
759+
728760
function normalizeMedal(value) {
729761
const text = String(value || "").trim();
730762

@@ -811,7 +843,11 @@
811843
.attr("fill", "rgba(255,255,255,0.75)")
812844
.attr("font-family", "'Elms Sans', sans-serif")
813845
.attr("font-size", 14)
814-
.text(`Flows show ${graph.mode}s → medal type → top 10 sports · ${graph.medalCount} medals shown`);
846+
.text(
847+
graph.mode === "country"
848+
? `Flows show top medal-winning countries + other countries → medal type → top 10 sports · ${graph.medalCount} medals shown`
849+
: `Flows show continents → medal type → top 10 sports · ${graph.medalCount} medals shown`
850+
);
815851

816852
if (!graph.links.length) {
817853
svg.append("text")
@@ -933,7 +969,12 @@
933969

934970
return `
935971
<div style="display:flex; justify-content:space-between; gap:18px;">
936-
<span>${d.source}</span>
972+
<span>
973+
${d.source}
974+
${d.source === "Other countries" && d.countries
975+
? `<br><small>${d.countries.slice(0, 12).join(", ")}${d.countries.length > 12 ? "…" : ""}</small>`
976+
: ""}
977+
</span>
937978
<strong>${d.value} (${pct}%)</strong>
938979
</div>
939980
`;
@@ -1036,6 +1077,7 @@
10361077
source: nodeIndex.get(d.source),
10371078
target: nodeIndex.get(detail.sport),
10381079
value: d.value,
1080+
countries: d.countries || [],
10391081
label: `${d.source}${detail.sport}: ${d.value} ${detail.medal} medals`
10401082
}));
10411083

@@ -1090,12 +1132,29 @@
10901132

10911133
const pct = total ? Math.round((d.value / total) * 100) : 0;
10921134

1093-
tooltip
1094-
.html(`
1095-
<strong>${d.label}</strong><br>
1096-
Share of this ${detail.medal.toLowerCase()}-${detail.sport} flow:
1097-
<strong>${pct}%</strong>
1098-
`)
1135+
tooltip.html(`
1136+
<strong>${d.label}</strong><br>
1137+
1138+
Share of this ${detail.medal.toLowerCase()}-${detail.sport} flow:
1139+
<strong>${pct}%</strong>
1140+
1141+
${
1142+
d.source.name === "Other countries" && d.countries.length
1143+
? `
1144+
<div style="
1145+
margin-top:10px;
1146+
color:#ffd166;
1147+
max-width:300px;
1148+
line-height:1.4;
1149+
font-size:12px;
1150+
">
1151+
<strong>Countries included:</strong><br>
1152+
${d.countries.join(", ")}
1153+
</div>
1154+
`
1155+
: ""
1156+
}
1157+
`)
10991158
.style("left", `${event.pageX + 14}px`)
11001159
.style("top", `${event.pageY + 14}px`)
11011160
.style("opacity", 1);
@@ -1158,6 +1217,10 @@
11581217
return index === -1 ? 999 : index;
11591218
}
11601219

1220+
if (node.name === "Other countries") {
1221+
return 999;
1222+
}
1223+
11611224
return 100;
11621225
}
11631226

website/styles.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,24 @@ p {
12481248
z-index: 2;
12491249
}
12501250

1251+
.medal-tooltip {
1252+
z-index: 100001 !important;
1253+
background: rgba(0, 0, 0, 0.96) !important;
1254+
color: white !important;
1255+
border: 1px solid rgba(255, 209, 102, 0.7) !important;
1256+
box-shadow: 0 8px 28px rgba(0,0,0,0.85) !important;
1257+
opacity: 1;
1258+
}
1259+
1260+
.medal-tooltip small {
1261+
display: block;
1262+
margin-top: 4px;
1263+
color: #ffd166 !important;
1264+
font-size: 12px;
1265+
line-height: 1.35;
1266+
max-width: 360px;
1267+
}
1268+
12511269
/* =============================================
12521270
Footer
12531271
=========================================== */

0 commit comments

Comments
 (0)