You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Highcharts Map实现美国州-城市钻取及城市点击弹窗功能

Highcharts Map 钻取至城市并点击弹窗实现方案

关键修改说明

  • 修正原代码拼写错误:thrilup改为drillup
  • 将钻取层级从「县」替换为「城市点数据」(城市通常以点标记展示而非区域)
  • 给城市点绑定点击事件,触发自定义模态框
  • 添加基础HTML模态框用于展示城市详情

修改后的完整代码

<div id="container"></div>

<!-- 模态框结构 -->
<div id="cityModal" class="modal">
  <div class="modal-content">
    <span class="close">&times;</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>

核心细节说明

  1. 模态框实现:纯HTML/CSS构建基础模态框,包含点击关闭、点击外部关闭的交互逻辑,可根据需求自定义样式和内容字段。
  2. 钻取逻辑调整:放弃原有的县区域数据加载,改用城市点数据(mapbubble类型),更符合城市在地图上的展示逻辑;若需城市区域数据,需替换为对应拓扑数据源。
  3. 点击事件绑定:在城市系列的point.events.click回调中触发模态框,填充城市名称和自定义描述信息。
  4. 模拟数据说明:示例中使用模拟城市数据,实际项目需替换为真实的城市数据源接口,返回包含名称、经纬度、详情的结构化数据。

内容的提问来源于stack exchange,提问作者Muhammad Tanveer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:02:10