${escapeHTML(node.name)}${escapeHTML(node.detail || '')}
${isVehicleNode ? `
${dict.onlineText}: ${node.online}/${node.count} · ${formatNumber(node.dist, 1)} km
` : ''}
`,
+ offset: new AMap.Pixel(0, -32)
+ });
+ infoWindowList.push(infoWindow);
+ marker.on('mouseover', () => infoWindow.open(map, node.lnglat));
+ marker.on('mouseout', () => infoWindow.close());
+ if (node.kind === 'vehicleProvince') marker.on('click', () => map.setZoomAndCenter(7.4, node.lnglat));
+ if (node.kind === 'vehicleCity') marker.on('click', () => map.setZoomAndCenter(9.8, node.lnglat));
+ if (node.kind === 'vehicleDistrict') marker.on('click', () => map.setZoomAndCenter(12.2, node.lnglat));
+ if (node.kind === 'stationProvince' || node.kind === 'stationCluster') marker.on('click', () => map.setZoomAndCenter(7.2, node.lnglat));
+ if (node.kind === 'stationCity') marker.on('click', () => map.setZoomAndCenter(11.2, node.lnglat));
+ marker.setMap(map); markerList.push(marker);
+ }
+}
+
+function renderRankingList(type) {
+ const box = document.getElementById('rankingListBox');
+ if (!box || !dashboard) return;
+ box.innerHTML = '';
+ let rows;
+ if (currentMode === 'vehicle') {
+ rows = buildVehicleRegionNodes().nodes
+ .sort((a, b) => type === 'secondary' ? b.dist - a.dist : b.count - a.count)
+ .slice(0, 12)
+ .map(item => ({
+ name: item.name,
+ value: type === 'secondary' ? `${formatNumber(item.dist, 1)} km` : item.kind === 'vehiclePoint' ? `${formatNumber(item.speedKmh, 1)} km/h` : countLabel(item.count, 'vehicle'),
+ location: item.lnglat,
+ zoom: item.kind === 'vehicleProvince' ? 7.4 : item.kind === 'vehicleCity' ? 9.8 : item.kind === 'vehicleDistrict' ? 12.2 : 14
+ }));
+ } else {
+ const { level, allNodes, visibleNodes } = stationViewportSummary();
+ const byHydrogen = type === 'secondary';
+ rows = [...visibleNodes]
+ .filter(node => !byHydrogen || node.hasHydrogen)
+ .sort((a, b) => byHydrogen ? b.hydrogenKg - a.hydrogenKg : b.count - a.count || a.name.localeCompare(b.name, 'zh-CN'))
+ .map(node => ({
+ name: node.name,
+ value: byHydrogen ? `${formatNumber(node.hydrogenKg, 1)} kg` : countLabel(node.count, 'station'),
+ location: node.lnglat,
+ zoom: level === 'province' ? 7.2 : level === 'city' ? 11.2 : 14
+ }));
+ updateStationViewportMeta(visibleNodes.length, allNodes.length);
+ if (!rows.length) {
+ const message = byHydrogen && visibleNodes.length ? i18n[currentLang].rankNoHydrogenData : i18n[currentLang].stationViewportEmpty;
+ box.innerHTML = `