Skip to content

Commit b468da7

Browse files
committed
fix: region-only tooltip, Asia step, per-region radar highlight, label overlap detection
- geo-map: tooltip shows region name only, not country - geo-map: each step highlights one region (Europe/NA/ME/Asia) - geo-map: removed currentStep guard so clicks always re-trigger - index.html: added Asia step card (4th) - bubbles: collision detection hides overlapping labels
1 parent a40e0b2 commit b468da7

3 files changed

Lines changed: 34 additions & 17 deletions

File tree

docs/index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,10 @@ <h2 class="section-title">The Geography of Scent</h2>
234234
<p><strong>North America</strong> overlaps heavily with Europe but leans slightly more fruity. American fragrance culture favors accessible, fresh compositions.</p>
235235
</div>
236236
<div class="step" data-step="3">
237-
<p>The <strong>Middle East</strong> stands apart: more woody, spicy, and musky. Oud-based compositions and resinous bases reflect a centuries-old olfactory tradition fundamentally different from the Western floral canon.</p>
237+
<p>The <strong>Middle East</strong> stands apart: more woody, spicy, and musky. Oud-based compositions and resinous bases reflect a centuries-old olfactory tradition.</p>
238+
</div>
239+
<div class="step" data-step="4">
240+
<p><strong>Asia</strong> balances citrus brightness with woody depth. Japanese perfumery favors lighter, cleaner profiles — less floral than Europe, less sweet than America.</p>
238241
</div>
239242
</div>
240243
</div>

docs/js/visualizations/bubbles.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,26 @@
241241
.attr('r', function (d) { return rScale(d.total); });
242242
}
243243

244-
// ── Labels for largest bubbles ──
245244
function drawLabels() {
246245
var labeled = bubbleData.slice(0, LABEL_COUNT);
246+
var placed = [];
247+
248+
var visible = labeled.filter(function (d) {
249+
var x = xScale(d.frequency);
250+
var y = yScale(d.avgRating) - rScale(d.total) - 4;
251+
var w = d.note.length * 5;
252+
var collides = placed.some(function (p) {
253+
return Math.abs(x - p.x) < (w + p.w) / 2 && Math.abs(y - p.y) < 12;
254+
});
255+
if (!collides) {
256+
placed.push({ x: x, y: y, w: w });
257+
return true;
258+
}
259+
return false;
260+
});
247261

248262
labelsSelection = g.selectAll('.bubble-label')
249-
.data(labeled, function (d) { return d.note; })
263+
.data(visible, function (d) { return d.note; })
250264
.join('text')
251265
.attr('class', 'bubble-label')
252266
.attr('x', function (d) { return xScale(d.frequency); })

docs/js/visualizations/geo-map.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,10 @@
141141
}
142142
}
143143

144-
function buildTooltipHtml(countryName, regionName, perfumeCount) {
144+
function buildTooltipHtml(regionName, perfumeCount) {
145145
var color = getRegionColor(regionName);
146146
var html = '<div class="tooltip-title" style="color:' + color + '">' +
147-
window.escapeHtml(countryName) + '</div>' +
148-
'<div class="tooltip-row"><span class="tooltip-label">Region</span>' +
149-
'<span class="tooltip-value">' + window.escapeHtml(regionName) + '</span></div>';
147+
window.escapeHtml(regionName) + '</div>';
150148
if (perfumeCount !== null && perfumeCount !== undefined) {
151149
html += '<div class="tooltip-row"><span class="tooltip-label">Perfumes</span>' +
152150
'<span class="tooltip-value">' + perfumeCount.toLocaleString() + '</span></div>';
@@ -232,15 +230,13 @@
232230
});
233231

234232
var count = regionCountMap[region] || null;
235-
var html = buildTooltipHtml(name, region, count);
236-
window.showTooltip(html, event.pageX, event.pageY);
233+
window.showTooltip(buildTooltipHtml(region, count), event.pageX, event.pageY);
237234
})
238235
.on('mousemove', function (event, d) {
239-
var name = d.properties.name;
240-
var region = getCountryRegion(name);
236+
var region = getCountryRegion(d.properties.name);
241237
if (!region) return;
242238
var count = regionCountMap[region] || null;
243-
window.showTooltip(buildTooltipHtml(name, region, count), event.pageX, event.pageY);
239+
window.showTooltip(buildTooltipHtml(region, count), event.pageX, event.pageY);
244240
})
245241
.on('mouseleave', function () {
246242
countryPaths
@@ -309,7 +305,7 @@
309305
}
310306

311307
function onStep(stepIndex) {
312-
if (!mapSvg || stepIndex === currentStep) return;
308+
if (!mapSvg) return;
313309
currentStep = stepIndex;
314310

315311
switch (stepIndex) {
@@ -318,12 +314,16 @@
318314
if (radarContainer) drawSideRadar(radarContainer, geoData, 'Europe');
319315
break;
320316
case 1:
321-
highlightMapRegions(['Europe', 'North America']);
322-
if (radarContainer) drawSideRadar(radarContainer, geoData, null);
317+
highlightMapRegion('North America');
318+
if (radarContainer) drawSideRadar(radarContainer, geoData, 'North America');
323319
break;
324320
case 2:
325-
resetMapHighlights();
326-
if (radarContainer) drawSideRadar(radarContainer, geoData, null);
321+
highlightMapRegion('Middle East');
322+
if (radarContainer) drawSideRadar(radarContainer, geoData, 'Middle East');
323+
break;
324+
case 3:
325+
highlightMapRegion('Asia');
326+
if (radarContainer) drawSideRadar(radarContainer, geoData, 'Asia');
327327
break;
328328
default:
329329
resetMapHighlights();

0 commit comments

Comments
 (0)