// World map web component for brewlog stats page. // Map data: Al MacDonald, edited by Fritz Lekschas. License: CC BY-SA 3.0 const WORLD_SVG = ` `; customElements.define( "world-map", class extends HTMLElement { static get observedAttributes() { return ["data-countries", "data-max", "data-selected"]; } connectedCallback() { this._scheduleRender(); this._themeObserver = new MutationObserver(() => requestAnimationFrame(() => this._recolor()), ); this._themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"], }); } disconnectedCallback() { this._themeObserver?.disconnect(); this._themeObserver = null; } attributeChangedCallback(name) { if (!this.isConnected) return; if (name === "data-selected") { this._recolor(); } else { this._scheduleRender(); } } _scheduleRender() { if (this._pendingRender) return; this._pendingRender = true; requestAnimationFrame(() => { this._pendingRender = false; this._render(); }); } _parseCountries() { const attr = this.getAttribute("data-countries") || ""; const counts = new Map(); if (attr) { attr.split(",").forEach((pair) => { const [code, count] = pair.split(":"); if (code && count) counts.set(code.trim().toLowerCase(), parseInt(count, 10)); }); } this._counts = counts; this._max = parseInt(this.getAttribute("data-max") || "1", 10) || 1; } _render() { this._parseCountries(); this.innerHTML = ""; const container = document.createElement("div"); container.innerHTML = WORLD_SVG; const svg = container.querySelector("svg"); if (!svg) return; svg.style.width = "100%"; svg.style.height = "auto"; svg.style.display = "block"; this.appendChild(svg); svg.setAttribute("role", "img"); svg.setAttribute( "aria-label", "World map showing coffee origins by country", ); const srOnly = this.querySelector(".sr-only"); if (srOnly) srOnly.remove(); const raw = this.dataset.countries || ""; if (raw) { const entries = raw.split(",").map((e) => e.split(":")); const sr = document.createElement("div"); sr.className = "sr-only"; sr.innerHTML = "
| Country | Count |
|---|---|
| ${code.toUpperCase()} | ${count} |