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

如何用D3实现自定义SVG图形的25%间隔百分比条件填充

当然可以用D3实现这种模块化的条件填充!你的二进制数组思路其实已经找对了方向,不过我们还能让它更灵活,彻底摆脱预存SVG文件的繁琐,完全发挥D3数据驱动的优势。

数据结构的选择

你想到的二进制数组[1,1,1,0]是完全可行的,直接对应每个房屋的填充状态。不过如果想更灵活(比如以后调整间隔,比如改成20%间隔对应5个图标),可以直接用目标百分比来推导填充数组,不用手动写二进制数组:

  • 比如目标75%,间隔25%,总共有100/25=4个图标,需要填充75/25=3个,自动生成[1,1,1,0]。

D3实现步骤(附代码)

我们可以用SVG的<defs>定义一个房屋模板,然后通过D3的数据绑定批量生成并设置填充状态,这样代码更简洁可维护:

  1. 先准备SVG容器和房屋模板:
<svg width="400" height="100" id="houseChart">
  <defs>
    <!-- 定义一个可复用的房屋路径 -->
    <path id="houseShape" d="M20,0 L40,20 L40,60 L0,60 L0,20 Z M10,40 L30,40 L30,60 L10,60 Z" />
  </defs>
</svg>
  1. 用D3实现数据驱动的绘制:

方式一:直接使用二进制数组

// 75%对应的填充状态数组
const fillData = [1,1,1,0];
const spacing = 50; // 房屋之间的间距

d3.select("#houseChart")
  .selectAll(".house-icon")
  .data(fillData)
  .enter()
  .append("use")
  .attr("href", "#houseShape") // 复用房屋模板
  .attr("class", "house-icon")
  .attr("x", (d, index) => index * spacing) // 水平排列
  .attr("fill", d => d === 1 ? "#2ecc71" : "none") // 根据数据设置填充
  .attr("stroke", "#333")
  .attr("stroke-width", 2);

方式二:通过百分比自动生成填充数据

这种方式更灵活,修改百分比或间隔只需要改参数:

const targetPercent = 75;
const intervalPercent = 25;
const totalIcons = 100 / intervalPercent; // 计算总图标数量

// 自动生成填充状态数组
const fillData = Array.from({ length: totalIcons }, (_, i) => {
  return i < (targetPercent / intervalPercent) ? 1 : 0;
});

// 后续绘制代码和方式一一致
d3.select("#houseChart")
  .selectAll(".house-icon")
  .data(fillData)
  .enter()
  .append("use")
  .attr("href", "#houseShape")
  .attr("class", "house-icon")
  .attr("x", (d, index) => index * 50)
  .attr("fill", d => d === 1 ? "#2ecc71" : "none")
  .attr("stroke", "#333")
  .attr("stroke-width", 2);

为什么这比预存SVG更好?

  • 模块化:只需要一个房屋模板,不管是25%、50%还是其他间隔,都不用新增SVG文件;
  • 数据驱动:修改百分比或间隔只需要调整参数,D3会自动处理图标数量和填充状态;
  • 可扩展性:如果以后需要动态更新(比如用户拖动滑块改变百分比),只需要更新fillData并重新绑定数据,D3的enter/update/exit模式可以高效更新DOM;

这样就完全利用了D3的核心能力,摆脱了硬编码的SVG文件依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:41:58