/* 流量統計:每日點擊長條圖(Chart.js)+ 全球訪客地圖(jsVectorMap)。 */ (function () { "use strict"; var el = document.getElementById("analyticsData"); if (!el) return; var data; try { data = JSON.parse(el.textContent); } catch (e) { return; } var TA = window.T_AN || { times: "次", sep: ":" }; // 依語言的單位/分隔字 // ---- 點擊趨勢(日 / 週 / 月 可切換)---- var dc = document.getElementById("dailyChart"); if (dc && typeof Chart !== "undefined") { var series = data.series || { day: [], week: [], month: [] }; var chart = null; function render(range) { var s = series[range] || []; if (chart) chart.destroy(); chart = new Chart(dc, { type: "bar", data: { labels: s.map(function (x) { return x.label; }), datasets: [{ data: s.map(function (x) { return x.hits; }), backgroundColor: "#8a1f2b" }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function (c) { return c.parsed.y + " " + TA.times; } } } }, scales: { x: { grid: { display: false } }, y: { beginAtZero: true, ticks: { precision: 0 } } } } }); } render("day"); document.querySelectorAll(".range-btn").forEach(function (b) { b.addEventListener("click", function () { document.querySelectorAll(".range-btn").forEach(function (x) { x.classList.remove("active"); }); b.classList.add("active"); render(b.getAttribute("data-range")); }); }); } // ---- 全球訪客地圖(jsVectorMap,依國家點擊數上色 choropleth)---- var wm = document.getElementById("worldMap"); if (wm && typeof jsVectorMap !== "undefined" && data.countries && data.countries.length) { var byCode = {}, maxH = 0; data.countries.forEach(function (c) { byCode[c.cc] = c; if (c.hits > maxH) maxH = c.hits; }); function lerp(a, b, t) { return Math.round(a + (b - a) * t); } function colorFor(hits) { // 淺紅→深紅;次數越多越深 var t = 0.28 + 0.72 * (maxH ? hits / maxH : 1); return "rgb(" + lerp(236, 138, t) + "," + lerp(202, 31, t) + "," + lerp(206, 43, t) + ")"; } try { new jsVectorMap({ selector: "#worldMap", map: "world", zoomButtons: true, zoomOnScroll: false, backgroundColor: "transparent", regionStyle: { initial: { fill: "#e6e4df", stroke: "#ffffff", "stroke-width": 0.4 }, // 無資料:淺灰 hover: { fillOpacity: 0.75 } }, onRegionTooltipShow: function (event, tooltip, code) { var info = byCode[code]; if (info) tooltip.text(info.country + TA.sep + info.hits + " " + TA.times, true); } }); // 直接把有訪客的國家上色(避開套件色階對單一數值的 bug);用「重試輪詢」而非單次 // setTimeout:地圖 SVG 有時渲染較慢(冷載入/CDN 未快取,英文頁較常見), // 單次上色會在區塊還沒出現前就跑掉 → 地圖不變色。改成每 120ms 重試、最多 ~3 秒, // 直到每個有訪客國家的區塊都存在並上色。!important 確保不被 hover/mouseout 覆蓋。 function colorize(tries) { var svg = wm.querySelector("svg"); var allDone = !!svg; if (svg) { data.countries.forEach(function (c) { var el = svg.querySelector('[data-code="' + c.cc + '"]'); if (el) el.style.setProperty("fill", colorFor(c.hits), "important"); else allDone = false; }); } if (!allDone && tries > 0) setTimeout(function () { colorize(tries - 1); }, 120); } colorize(25); } catch (e) { // 若地圖套件載入失敗,靜默略過(下方仍有國家排行清單) } } })();