diff --git a/src/App.jsx b/src/App.jsx index 6d4ee97..57e5ea0 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2012,32 +2012,33 @@ const shortDateFormat = new Intl.DateTimeFormat('en-GB', { }) const timezoneMapPoints = { - 'America/Los_Angeles': [18, 42], - 'America/Denver': [24, 43], - 'America/Chicago': [30, 45], - 'America/New_York': [37, 43], - 'America/Toronto': [38, 40], - 'America/Sao_Paulo': [43, 68], - 'America/Mexico_City': [27, 54], - 'Europe/London': [48, 36], - 'Europe/Paris': [51, 39], - 'Europe/Berlin': [53, 37], - 'Europe/Madrid': [49, 42], - 'Europe/Rome': [53, 43], - 'Europe/Amsterdam': [51, 37], - 'Europe/Stockholm': [54, 31], - 'Europe/Warsaw': [56, 37], - 'Europe/Moscow': [63, 34], - 'Africa/Cairo': [58, 49], - 'Africa/Johannesburg': [58, 75], - 'Asia/Dubai': [66, 52], - 'Asia/Kolkata': [72, 56], - 'Asia/Singapore': [79, 66], - 'Asia/Tokyo': [88, 45], - 'Asia/Seoul': [85, 44], - 'Asia/Shanghai': [81, 48], - 'Australia/Sydney': [90, 78], - 'Pacific/Auckland': [95, 84], + 'America/Los_Angeles': [34.05, -118.24], + 'America/Denver': [39.74, -104.99], + 'America/Chicago': [41.88, -87.63], + 'America/New_York': [40.71, -74.01], + 'America/Toronto': [43.65, -79.38], + 'America/Phoenix': [33.45, -112.07], + 'America/Sao_Paulo': [-23.55, -46.63], + 'America/Mexico_City': [19.43, -99.13], + 'Europe/London': [51.51, -0.13], + 'Europe/Paris': [48.86, 2.35], + 'Europe/Berlin': [52.52, 13.41], + 'Europe/Madrid': [40.42, -3.7], + 'Europe/Rome': [41.9, 12.5], + 'Europe/Amsterdam': [52.37, 4.9], + 'Europe/Stockholm': [59.33, 18.07], + 'Europe/Warsaw': [52.23, 21.01], + 'Europe/Moscow': [55.76, 37.62], + 'Africa/Cairo': [30.04, 31.24], + 'Africa/Johannesburg': [-26.2, 28.04], + 'Asia/Dubai': [25.2, 55.27], + 'Asia/Kolkata': [22.57, 88.36], + 'Asia/Singapore': [1.35, 103.82], + 'Asia/Tokyo': [35.68, 139.65], + 'Asia/Seoul': [37.57, 126.98], + 'Asia/Shanghai': [31.23, 121.47], + 'Australia/Sydney': [-33.87, 151.21], + 'Pacific/Auckland': [-36.85, 174.76], } const countryNames = { @@ -2092,22 +2093,15 @@ const countryMapPoints = { ZA: [24, -29], } -function mapPointFromPercent(x, y) { - return [ - 85 - (y / 100) * 145, - (x / 100) * 360 - 180, - ] -} - function timezonePoint(timezone = '') { if (timezoneMapPoints[timezone]) return timezoneMapPoints[timezone] - if (timezone.startsWith('America/')) return [30, 48] - if (timezone.startsWith('Europe/')) return [53, 38] - if (timezone.startsWith('Africa/')) return [56, 60] - if (timezone.startsWith('Asia/')) return [75, 52] - if (timezone.startsWith('Australia/')) return [88, 76] - if (timezone.startsWith('Pacific/')) return [92, 70] - return [50, 50] + if (timezone.startsWith('America/')) return [39, -96] + if (timezone.startsWith('Europe/')) return [50, 10] + if (timezone.startsWith('Africa/')) return [0, 20] + if (timezone.startsWith('Asia/')) return [34, 100] + if (timezone.startsWith('Australia/')) return [-25, 134] + if (timezone.startsWith('Pacific/')) return [-15, 170] + return [20, 0] } function filledLast30Days(rows) { @@ -2128,6 +2122,7 @@ function filledLast30Days(rows) { } function MiniLineChart({ accent = 'text-fury-cyan', data, label, metric, stroke = '#e82517' }) { + const [hoveredPoint, setHoveredPoint] = useState(null) const width = 320 const height = 112 const padding = 12 @@ -2143,7 +2138,7 @@ function MiniLineChart({ accent = 'text-fury-cyan', data, label, metric, stroke const latest = points.at(-1)?.value || 0 return ( -
+

{label}

@@ -2161,15 +2156,31 @@ function MiniLineChart({ accent = 'text-fury-cyan', data, label, metric, stroke cy={point.y} fill={stroke} key={`${metric}-${point.date}`} + onBlur={() => setHoveredPoint(null)} + onFocus={() => setHoveredPoint(point)} + onMouseEnter={() => setHoveredPoint(point)} + onMouseLeave={() => setHoveredPoint(null)} r="4" tabIndex="0" - > - - {`${shortDateFormat.format(new Date(point.date))}: ${formatNumber(point.value)} ${label.toLowerCase()}, ${formatNumber(point.visitors || 0)} visitors`} - - + /> ))} + + {hoveredPoint ? ( +
+ {shortDateFormat.format(new Date(hoveredPoint.date))}: {formatNumber(hoveredPoint.value)} {label.toLowerCase()} + + {formatNumber(hoveredPoint.visitors || 0)} visitors + +
+ ) : null}
) } @@ -2543,8 +2554,7 @@ function LocationSignalMap({ countries, locations }) { }) fallbackLocations.forEach((location) => { - const [x, y] = timezonePoint(location.timezone) - const [lat, lon] = mapPointFromPercent(x, y) + const [lat, lon] = timezonePoint(location.timezone) const radius = 7 + (Number(location.visitors || 0) / maxLocationVisitors) * 16 L.circleMarker([lat, lon], { color: '#000000',