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

如何在D3绘制的SVG世界地图上显示国家名称?

在D3世界地图上显示各国名称的实现方法

嘿,要给你的D3世界地图加上各国名称其实不难,核心就是找对每个国家的中心位置,再把名称和地图数据对应上就行。结合你的现有代码,我给你梳理具体实现步骤:

步骤1:先搞定国家名称与ID的映射

你用的这个world-110m2.json只存了国家的地理形状和ID,没直接带名称字段,所以得先整个映射表,把每个国家的ID对应到它的名称上。我给你写个示例,你可以按需补全:

// 国家ID→名称的映射(示例部分数据,需要你补充完整哦)
const countryNames = {
  "4": "Afghanistan",
  "8": "Albania",
  "12": "Algeria",
  "20": "Andorra",
  "24": "Angola",
  // 剩下的国家可以查topojson对应的ID来补充
};

步骤2:添加国家名称的文本标签

在你画完国家路径的代码后面,加一段生成文本的逻辑就行。这里用D3的path.centroid()来获取每个国家的中心位置,把文本放在那儿:

// 给每个国家加名称文本
g.selectAll("text.country-name")
  .data(topojson.object(topology, topology.objects.countries).geometries)
  .enter()
  .append("text")
  .attr("class", "country-name")
  // 用质心坐标定位文本
  .attr("x", d => path.centroid(d)[0])
  .attr("y", d => path.centroid(d)[1])
  // 让文本在中心位置居中对齐
  .attr("text-anchor", "middle")
  .attr("font-size", "10px")
  .attr("fill", "#333")
  // 根据ID匹配对应的国家名称,找不到就显示空
  .text(d => countryNames[d.id] || "");

步骤3:优化显示效果(可选)

如果遇到小国家名称重叠、看不清的情况,可以做点优化:

  • 过滤掉面积太小的国家,比如岛国,避免挤在一起:
.text(d => {
  // 计算国家面积,小于阈值就不显示名称
  const area = d3.geoArea(d);
  return area > 0.001 ? countryNames[d.id] || "" : "";
})
  • 给文本加个白色阴影,在深色地图上更清楚:
.country-name {
  text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
}

整合后的完整代码片段

把这些代码加到你的现有逻辑里,核心部分大概是这样:

d3.json("https://gist.githubusercontent.com/d3noob/5193723/raw/world-110m2.json", function (error, topology) { 
  // 先定义国家名称映射
  const countryNames = {
    "4": "Afghanistan",
    "8": "Albania",
    "12": "Algeria",
    // 记得补全其他国家哦
  };

  let world = g 
    .selectAll("path") 
    .data(topojson.object(topology, topology.objects.countries).geometries) 
    .enter() 
    .append("path") 
    .attr("d", path); 

  // 添加国家名称文本
  g.selectAll("text.country-name")
    .data(topojson.object(topology, topology.objects.countries).geometries)
    .enter()
    .append("text")
    .attr("class", "country-name")
    .attr("x", d => path.centroid(d)[0])
    .attr("y", d => path.centroid(d)[1])
    .attr("text-anchor", "middle")
    .attr("font-size", "10px")
    .attr("fill", "#333")
    .text(d => countryNames[d.id] || "");

  // 城市标记的代码保持不变
  let locations = g 
    .selectAll("circle") 
    .data(cities) 
    .enter() 
    .append("circle"); 
});

内容的提问来源于stack exchange,提问作者Suresh.W

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:30:37