基于Highcharts Map实现美国州-城市钻取及城市点击弹窗功能
Highcharts Map 钻取至城市并点击弹窗实现方案
关键修改说明
- 修正原代码拼写错误:
thrilup改为drillup - 将钻取层级从「县」替换为「城市点数据」(城市通常以点标记展示而非区域)
- 给城市点绑定点击事件,触发自定义模态框
- 添加基础HTML模态框用于展示城市详情
修改后的完整代码
<div id="container"></div> <!-- 模态框结构 --> <div id="cityModal" class="modal"> <div class="modal-content"> <span class="close">×</span> <h2 id="cityName"></h2> <p id="cityInfo"></p> </div> </div> <style> /* 模态框基础样式 */ .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.4); } .modal-content { background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 80%; max-width: 500px; border-radius: 8px; } .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; } .close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; } </style> <script> // 模态框操作元素 const modal = document.getElementById("cityModal"); const closeBtn = document.getElementsByClassName("close")[0]; const cityNameEl = document.getElementById("cityName"); const cityInfoEl = document.getElementById("cityInfo"); // 关闭模态框逻辑 closeBtn.onclick = function() { modal.style.display = "none"; } window.onclick = function(event) { if (event.target === modal) { modal.style.display = "none"; } } const drilldown = async function (e) { if (!e.seriesOptions) { const chart = this; const stateKey = e.point.drilldown; chart.showLoading('<i class="icon-spinner icon-spin icon-3x"></i>'); // 替换为真实城市数据源接口,此处为模拟数据 const cityData = await new Promise(resolve => { setTimeout(() => { resolve([ { name: '纽约市', lat: 40.7128, lon: -74.0060, value: 1, desc: '美国人口最多的城市' }, { name: '洛杉矶', lat: 34.0522, lon: -118.2437, value: 2, desc: '加州最大城市' }, { name: '芝加哥', lat: 41.8781, lon: -87.6298, value: 3, desc: '中西部核心城市' } ]); }, 1000); }); // 转换城市数据为Highcharts兼容格式 const data = cityData.map(city => ({ name: city.name, lat: city.lat, lon: city.lon, value: city.value, desc: city.desc })); // 调整地图视图至当前州范围 chart.mapView.update( Highcharts.merge( { insets: undefined }, e.point.series.custom.mapView ), false ); chart.hideLoading(); chart.addSeriesAsDrilldown(e.point, { name: `${e.point.name} 城市`, type: 'mapbubble', // 用气泡图展示城市点 data, dataLabels: { enabled: true, format: '{point.name}' }, plotOptions: { mapbubble: { point: { events: { // 点击城市点触发模态框 click: function() { cityNameEl.textContent = this.name; cityInfoEl.textContent = this.desc; modal.style.display = "block"; } } } } } }); } }; // 钻取返回顶层地图时重置视图 const drillup = function (e) { if (e.seriesOptions.custom && e.seriesOptions.custom.mapView) { e.target.mapView.update( Highcharts.merge( { insets: undefined }, e.seriesOptions.custom.mapView ), false ); } }; (async () => { const topology = await fetch( 'https://code.highcharts.com/mapdata/countries/us/us-all.topo.json' ).then(response => response.json()); const data = Highcharts.geojson(topology); const mapView = topology.objects.default['hc-recommended-mapview']; // 给各州设置钻取标识 data.forEach((d, i) => { d.drilldown = d.properties['hc-key']; d.value = i; }); // 初始化地图 Highcharts.mapChart('container', { chart: { events: { drilldown, drillup } }, title: { text: '美国各州城市钻取地图' }, colorAxis: { min: 0, minColor: '#E6E7E8', maxColor: '#005645' }, mapView, mapNavigation: { enabled: true, buttonOptions: { verticalAlign: 'bottom' } }, plotOptions: { map: { states: { hover: { color: '#EEDD66' } } } }, series: [{ data, name: 'USA', dataLabels: { enabled: true, format: '{point.properties.postal-code}' }, custom: { mapView } }], drilldown: { activeDataLabelStyle: { color: '#FFFFFF', textDecoration: 'none', textOutline: '1px #000000' }, drillUpButton: { relativeTo: 'spacingBox', position: { x: 0, y: 60 } } } }); })(); </script>
核心细节说明
- 模态框实现:纯HTML/CSS构建基础模态框,包含点击关闭、点击外部关闭的交互逻辑,可根据需求自定义样式和内容字段。
- 钻取逻辑调整:放弃原有的县区域数据加载,改用城市点数据(
mapbubble类型),更符合城市在地图上的展示逻辑;若需城市区域数据,需替换为对应拓扑数据源。 - 点击事件绑定:在城市系列的
point.events.click回调中触发模态框,填充城市名称和自定义描述信息。 - 模拟数据说明:示例中使用模拟城市数据,实际项目需替换为真实的城市数据源接口,返回包含名称、经纬度、详情的结构化数据。
内容的提问来源于stack exchange,提问作者Muhammad Tanveer
相关产品推荐
相关产品推荐

