display home country in map

This commit is contained in:
2026-06-12 19:19:20 +09:00
parent 6701398da7
commit f198c05063
6 changed files with 140 additions and 34 deletions

View File

@@ -3,7 +3,7 @@
import * as d3 from 'd3';
import { feature } from 'topojson-client';
import worldData from 'world-atlas/countries-50m.json';
import { getSelected, toggle, setTotalCount } from '../layout/selection.svelte.js';
import { getSelected, toggle, setTotalCount, getHomeCountryCode } from '../layout/selection.svelte.js';
const TERRITORY_PARENT = {
'016': '840', // American Samoa -> United States
@@ -49,6 +49,27 @@
return TERRITORY_PARENT[d.id] || d.id;
}
const HOME_COLOR = '#8b5cf6';
const HOME_COLOR_HOVER = '#7c3aed';
const VISITED_COLOR = '#22c55e';
const VISITED_COLOR_HOVER = '#16a34a';
const UNVISITED_COLOR = '#ffffff';
const UNVISITED_COLOR_HOVER = '#f0f6fa';
function countryColor(d, sel, homeCode) {
const id = effId(d);
if (!sel.has(id)) return UNVISITED_COLOR;
if (id === homeCode) return HOME_COLOR;
return VISITED_COLOR;
}
function countryHoverColor(d, sel, homeCode) {
const id = effId(d);
if (!sel.has(id)) return UNVISITED_COLOR_HOVER;
if (id === homeCode) return HOME_COLOR_HOVER;
return VISITED_COLOR_HOVER;
}
let frameEl;
let _paths = null;
let _g = null;
@@ -62,8 +83,9 @@
function updateAllFills() {
if (!_paths || !_g) return;
const sel = getSelected();
_paths.attr('fill', d => sel.has(effId(d)) ? '#22c55e' : '#ffffff');
_g.selectAll('.micro-state').attr('fill', d => sel.has(effId(d)) ? '#22c55e' : '#ffffff');
const hc = getHomeCountryCode();
_paths.attr('fill', d => countryColor(d, sel, hc));
_g.selectAll('.micro-state').attr('fill', d => countryColor(d, sel, hc));
}
$effect(updateAllFills);
@@ -100,8 +122,10 @@
.style('display', 'none');
function updateFill(sel) {
sel.attr('fill', d => getSelected().has(effId(d)) ? '#22c55e' : '#ffffff');
_g.selectAll('.micro-state').attr('fill', d => getSelected().has(effId(d)) ? '#22c55e' : '#ffffff');
const s = getSelected();
const hc = getHomeCountryCode();
sel.attr('fill', d => countryColor(d, s, hc));
_g.selectAll('.micro-state').attr('fill', d => countryColor(d, s, hc));
}
function attachEvents(sel) {
@@ -111,7 +135,9 @@
updateFill(d3.select(event.currentTarget));
})
.on('mouseenter', (event, d) => {
d3.select(event.currentTarget).attr('fill', getSelected().has(effId(d)) ? '#16a34a' : '#f0f6fa');
const s = getSelected();
const hc = getHomeCountryCode();
d3.select(event.currentTarget).attr('fill', countryHoverColor(d, s, hc));
tooltip.style('display', 'block').text(d.properties.name);
})
.on('mousemove', (event) => {
@@ -119,7 +145,9 @@
tooltip.style('left', (x + 10) + 'px').style('top', (y - 28) + 'px');
})
.on('mouseleave', (event, d) => {
d3.select(event.currentTarget).attr('fill', getSelected().has(effId(d)) ? '#22c55e' : '#ffffff');
const s = getSelected();
const hc = getHomeCountryCode();
d3.select(event.currentTarget).attr('fill', countryColor(d, s, hc));
tooltip.style('display', 'none');
});
}
@@ -141,13 +169,14 @@
const { width, height } = this.getBBox();
if (width < threshold && height < threshold) {
const [cx, cy] = path.centroid(d);
const hc = getHomeCountryCode();
const c = _g.append('circle')
.attr('class', 'micro-state')
.datum(d)
.attr('cx', cx)
.attr('cy', cy)
.attr('r', 2)
.attr('fill', getSelected().has(effId(d)) ? '#22c55e' : '#ffffff')
.attr('fill', countryColor(d, getSelected(), hc))
.attr('stroke', '#94a3b8')
.attr('stroke-width', 0.5);
attachEvents(c);