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

如何在Leaflet弹窗中集成Chart.js并从popup元素读取数据生成图表?

实现方案

这个需求完全可以实现,核心逻辑为每次点击标记渲染完侧边弹窗内容后,直接从DOM中对应的评分类元素提取数值,更新已有的Chart.js实例即可,全程不需要读取原始GeoJSON数据,完全符合你适配后续JSON结构变动的要求。

核心修改步骤

1. 调整JS逻辑

首先全局保存图表实例,新增从弹窗提取数据更新图表的函数,再在标记点击事件中触发更新即可,修改后的完整JS代码如下:

var mymap = L.map('mapid').setView([39.46975, -0.37739], 8 );
L.tileLayer('https://api.mapbox.com/styles/v1/jamaldols/cktwljkom0vzo18l9ggtnky83/tiles/256/{z}/{x}/{y}@2x?access_token={accessToken}', {
    attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
    maxZoom: 12,
    minZoom: 8,
    id: 'mapbox/standard',
    tileSize: 512,
    zoomOffset: -1,
    accessToken: ''
}).addTo(mymap);

// 全局保存雷达图实例
let radarChart;

$.getJSON('data.geo.json', function (geojson) {
  L.geoJson(geojson, {
    pointToLayer: function (feature, latlng) {
      return L.marker(latlng);
    },
    onEachFeature: function (feature, layer) {
      const coordinates = feature.geometry.coordinates;
      const normalizedCoordinates = feature.geometry.coordinates.sort(function(a,b){return a.typeid-b.typeid});
      console.log( `Coordinates:     ${coordinates}`);
      console.log( `Coordinates N:   ${normalizedCoordinates}`);
      const content = `
      <p id="heading">${feature.properties.name}</p>
      <p class="scoreA"><strong>ScoreA: </strong>${feature.properties.scoreA}</p>
      <p class="scoreB"><strong>ScoreB: </strong>${feature.properties.scoreB}</p>
      <p class="scoreC"><strong>ScoreC: </strong>${feature.properties.scoreC}</p>
      <p class="scoreD"><strong>ScoreD: </strong>${feature.properties.scoreD}</p>
      <div class="popup__chart">chart</div>
      `;
      layer.on('click', function (e) {
        document.getElementById("popup__content").innerHTML = content;
        // 渲染完弹窗内容后直接调用更新图表方法
        updateChartFromPopup();
        $(".popup").fadeOut(10);
        $(".popup").fadeIn("slow");
        console.log( `Click on ${feature.properties.name}`);
        const maxZoom = mymap.getMaxZoom();
        console.log(maxZoom)
        mymap.flyTo(this.getLatLng(), maxZoom, {easeLinearity: 0.12, duration:1});
      });
    }
  }).addTo(mymap);
});

// 从弹窗DOM提取数据更新雷达图
function updateChartFromPopup() {
  // 提取各评分数值,自动过滤文本只保留数字
  const scoreA = parseInt($('.scoreA').text().replace('ScoreA: ', '').trim());
  const scoreB = parseInt($('.scoreB').text().replace('ScoreB: ', '').trim());
  const scoreC = parseInt($('.scoreC').text().replace('ScoreC: ', '').trim());
  const scoreD = parseInt($('.scoreD').text().replace('ScoreD: ', '').trim());
  // 更新图表数据并重绘
  radarChart.data.datasets[0].data = [scoreA, scoreB, scoreC, scoreD];
  radarChart.update();
}

$(document).ready(function(){
  // 页面加载完成后初始化雷达图
  const marksCanvas = document.getElementById("marksChart");
  const marksData = {
    labels: ["Score A", "Score B", "Score C", "Score D"],
    datasets: [{
      label: "城市评分",
      backgroundColor: "rgba(200,0,0,0.2)",
      borderColor: "rgba(200,0,0,1)",
      pointBackgroundColor: "rgba(200,0,0,1)",
      data: [0,0,0,0]
    }]
  };
  radarChart = new Chart(marksCanvas, {
    type: 'radar',
    data: marksData,
    options: {
      scales: {
        r: {
          min: 0,
          max: 100 // 可根据实际分值范围调整
        }
      }
    }
  });

  $(".popup__bar__close").click(function(){
    $('.popup').css('display', 'none');
    mymap.flyTo([39.46975, -0.37739], 8, {easeLinearity: 0.12, duration:1});
  });
});

2. 冗余代码清理

你当前HTML中加载了两次jQuery(3.3.1和2.1.3版本),会引发未知冲突,建议删除2.1.3版本的<script>引用即可。

后续适配说明

如果后续JSON新增了其他评分项,只需要做两处修改即可,不需要调整GeoJSON读取逻辑:

  • 在弹窗模板content中新增对应类名的评分元素
  • 在updateChartFromPopup函数中新增对应评分的提取逻辑,同时给雷达图的labels数组新增对应项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:27:05