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

如何通过HTML单选框切换Mapbox choropleth地图的Chroma.js着色属性并刷新?

我来帮你搞定这个单选框切换Chroma.js分级着色的问题!结合Mapbox和Chroma.js实现属性切换并刷新地图其实很顺畅,下面是完整的实现思路和可直接复用的代码示例:

实现步骤详解

1. 先搞定HTML单选框控制区

先在页面上添加一组单选框,让用户可以切换要展示的人口属性,每个单选框的value对应你数据源里的属性名:

<div class="map-controls">
  <label>
    <input type="radio" name="populationProp" value="total" checked> 总人口
  </label>
  <label>
    <input type="radio" name="populationProp" value="free"> 自由人口
  </label>
  <label>
    <input type="radio" name="populationProp" value="slave"> 奴隶人口
  </label>
  <label>
    <input type="radio" name="populationProp" value="white"> 白人人口
  </label>
</div>

2. 初始化Mapbox与Chroma.js核心逻辑

首先完成Mapbox地图的初始化,然后封装两个关键函数:一个生成Chroma.js颜色比例尺,另一个负责更新地图图层的着色样式:

// 替换成你的Mapbox Access Token
mapboxgl.accessToken = '你的Mapbox Token';
const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v11',
  center: [-98.58, 39.82], // 美国中心坐标,可根据你的数据调整
  zoom: 4
});

// 全局变量存储当前选中的属性,默认用total
let dataStyleProp = 'total';

// 生成Chroma.js颜色比例尺的工具函数
function generateColorScale(geoData, propName) {
  // 提取所有要素的目标属性值,过滤掉无效值
  const propertyValues = geoData.features
    .map(feature => feature.properties[propName])
    .filter(val => val !== null && val !== undefined);
  
  // 使用Chroma.js创建等差分级的颜色比例尺(这里用9阶YlOrRd配色)
  return chroma.scale('YlOrRd').domain(chroma.limits(propertyValues, 'e', 9));
}

// 更新地图分级着色的核心函数
function refreshChoropleth(activeProp) {
  // 获取当前加载的GeoJSON数据源(要和你添加图层时的数据源ID对应)
  const sourceData = map.getSource('population-data')._data;
  const colorScale = generateColorScale(sourceData, activeProp);

  // 用Mapbox的setPaintProperty实时更新图层样式
  map.setPaintProperty('population-layer', 'fill-color', [
    'interpolate',
    ['linear'],
    ['get', activeProp],
    // 遍历Chroma的颜色断点,生成Mapbox的插值规则
    ...colorScale.domain().flatMap((domainVal, index) => {
      if (index < colorScale.domain().length - 1) {
        return [domainVal, colorScale(domainVal)];
      }
      return [];
    }),
    // 给最大值设置最高阶颜色
    [colorScale.domain().at(-1), colorScale(colorScale.domain().at(-1))]
  ]);
}

3. 绑定单选框切换事件,实现实时刷新

等地图加载完成后,初始化默认属性的着色效果,再给所有单选框绑定切换事件,触发地图样式更新:

map.on('load', () => {
  // 这里假设你已经添加了GeoJSON数据源和图层,示例代码如下:
  // map.addSource('population-data', {
  //   type: 'geojson',
  //   data: './your-population-data.geojson' // 你的数据路径
  // });
  // map.addLayer({
  //   id: 'population-layer',
  //   type: 'fill',
  //   source: 'population-data',
  //   paint: {
  //     'fill-opacity': 0.8,
  //     'fill-color': '#cccccc' // 初始默认颜色
  //   }
  // });

  // 初始化加载默认属性的着色效果
  refreshChoropleth(dataStyleProp);

  // 给所有单选框绑定切换事件
  document.querySelectorAll('input[name="populationProp"]').forEach(radio => {
    radio.addEventListener('change', (e) => {
      dataStyleProp = e.target.value;
      // 调用刷新函数更新地图
      refreshChoropleth(dataStyleProp);
    });
  });
});

几个关键注意事项

  • 确保你的图层ID、数据源ID和代码里的命名完全对应,不然会找不到对象报错
  • Chroma.js的分级方式可以按需调整:比如把chroma.limits的e换成q可以做分位数分级,换成k做等间隔分级
  • 如果数据里存在无效值(比如null),一定要在生成颜色比例尺时过滤掉,避免颜色计算出错
  • Mapbox的setPaintProperty是实时更新样式的,不需要重新加载图层,这就是实现“刷新地图”的核心

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:51:23