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

Leaflet地图中ApexCharts仪表盘覆盖信息面板内容如何解决?

问题修复方案

根因说明

  • ApexCharts的render()方法为异步执行:你当前的代码先触发图表渲染,再同步更新信息面板文本,等图表异步渲染完成后,会直接清空你挂载的整个.info根容器的原有内容,导致先出现的文本被后续渲染的图表覆盖
  • 未对信息面板做功能分区,文本和图表共用同一个根容器,渲染逻辑互相冲突

修复步骤

1. 拆分信息面板容器结构

修改createInfoPanel方法,提前在信息面板根容器内创建两个独立子容器,分别存放文本信息和图表,避免后续渲染互相覆盖。

2. 调整更新逻辑

信息面板的update方法仅修改文本子容器的内容,不再覆盖整个根容器的HTML。

3. 修正图表挂载节点

将ApexCharts的挂载节点改为专门的图表子容器,不再直接挂载到信息面板根容器。

4. 优化图表实例管理

新增全局变量存储图表实例,每次渲染新图表前销毁旧实例,避免内存泄漏和重复渲染。

完整修改后代码

// 新增全局变量存储图表实例,方便销毁
let waterSystemChart = null;

function createInfoPanel(){
    info_panel.onAdd = function (map) {
        // 创建根容器
        this._div = L.DomUtil.create('div', 'info');
        // 新增两个独立子容器:文本区、图表区
        this._div.innerHTML = `
            <div class="info-content"></div>
            <div class="info-chart" style="margin-top: 15px;"></div>
        `;
        this.update();
        return this._div;
    };

    info_panel.update = function (properties) {
        // 仅更新文本容器内容,不触碰整个根容器和图表容器
        const contentEl = this._div.querySelector('.info-content');
        if(properties){
            contentEl.innerHTML = `<b>${properties['name']}</b>
                                    <br>Governance Type: ${properties['GovernanceType']}
                                    <br>Next Election Year: ${properties['UpcomingElectionYear']}
                                    <br>How is Leadership Chosen?: ${properties['Mechansim']}
                                    <br>Average Water Bill: $${properties['WaterBill']}
                                    <br>Bill Compared to County Average: ${properties['POA']}
                                    `;
        }else{
            contentEl.innerHTML = 'Hover over a Water System';
            // 鼠标移出时清空图表
            const chartEl = this._div.querySelector('.info-chart');
            chartEl.innerHTML = '';
            if(waterSystemChart){
                waterSystemChart.destroy();
                waterSystemChart = null;
            }
        }
    };

    info_panel.addTo(map);
}

// Function that defines what will happen on user interactions with each feature
function onEachFeature(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
        click: zoomToFeature
    });
}

// on mouse over, highlight the feature
function highlightFeature(e) {
    var layer = e.target;

    // style to use on mouse over
    layer.setStyle({
        weight: 2,
        color: '#666',
        fillOpacity: 0.7
    });

    if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        layer.bringToFront();
    }
    // 先更新文本信息,再渲染图表
    info_panel.update(layer.feature.properties);
    createDashboard(layer.feature.properties);
   
}

// on mouse out, reset the style, otherwise, it will remain highlighted
function resetHighlight(e) {
    geojson_layer.resetStyle(e.target);
    info_panel.update() // resets infopanel
}

// on mouse click on a feature, zoom in to it
function zoomToFeature(e) {
    map.fitBounds(e.target.getBounds());
}

// Creating dashboard
function createDashboard(properties){
    // 先销毁旧图表
    if(waterSystemChart){
        waterSystemChart.destroy();
        waterSystemChart = null;
    }

    console.log(properties)

    // data values
    let data = [
            properties['Hispanic_Pop'],
            properties['White_Pop'],
            properties['Black_Pop'],
            properties['AIAN_Pop'],
            properties['Asian_Pop'],
            properties['NHOPI_Pop'],
            properties['OtherRace_Pop'],
            properties['TwoMore_Pop'],
    ]
    
    // data fields
    let fields = [
        'Hispanic Population',
        'White Population',
        'Black Population',
        'American Indian and Alaskan Native Population ',
        'Asian Population',
        'Native Hawaiian and other Pacific Islander Population',
        'Other Race Population',
        'Two or more Race Population',
    ]

    var options2 = {
        chart: {
            type: 'pie',
            height: 300,
            width: '100%',  
            animations: {
                enabled: false,
            }
        },
        title: {
            text: 'Water System Demographics ' + properties['name'],
        },
        series: data,
        labels: fields,
        legend: {
            position: 'right',
            offsetY: 0,
            height: 230,
          }
    };

    // 挂载到专门的图表子容器,不再挂载到整个.info容器
    waterSystemChart = new ApexCharts(document.querySelector('.info .info-chart'), options2)
    waterSystemChart.render()
}

可选优化

可以给.info容器加固定宽度、最大高度和滚动样式,避免内容过长影响地图操作:

.info {
    padding: 10px;
    background: white;
    border-radius: 5px;
    box-shadow: 0 0 10px rgba(0,0,0,0.2);
    min-width: 300px;
    max-height: 80vh;
    overflow-y: auto;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:51:00