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

如何在D3.js中为条形图的每个条形应用不同填充图案?

将D3.js条形图的每个条形应用不同填充图案的解决方案

没问题,我来帮你把定义好的三种填充图案分别对应到每个条形上。咱们一步步来修改你的代码:

第一步:整理SVG图案定义

首先,你不需要为每个pattern单独创建<defs>标签,把所有图案定义放到同一个<defs>里更规范,而且要确保这些defs在主图表的SVG里(或者至少在同一个文档中,这样D3能找到它们)。

第二步:给每个条形匹配对应图案

因为你的CSV里有3条数据,正好对应3个图案,我们可以创建一个图案ID的数组,然后在绘制条形时根据数据的索引来选择对应的图案。

修改后的完整代码

<!doctype html>
<html>
<head>
<style>
 .bar { /* 移除默认填充色,避免覆盖动态设置的图案 */ }
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<!-- 主图表SVG -->
<svg width="600" height="500">
  <!-- 将所有图案定义合并到同一个defs中 -->
  <defs>
    <pattern id="pattern1" x="10" y="10" width="20" height="20" patternUnits="userSpaceOnUse" >
      <circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
    </pattern>
    <pattern id="pattern2" x="10" y="10" width="20" height="20" patternUnits="userSpaceOnUse" >
      <circle cx="10" cy="10" r="5" style="stroke: none; fill: #0000ff" />
    </pattern>
    <pattern id="pattern3" x="10" y="10" width="20" height="20" patternUnits="userSpaceOnUse" >
      <circle cx="10" cy="10" r="3" style="stroke: none; fill: #0000ff" />
    </pattern>
  </defs>
</svg>

<!-- 如果你不需要预览图案的话,可以删掉下面这个SVG -->
<svg>
  <rect x="0" y="10" width="100" height="100" style="stroke: #000000; fill: url(#pattern1);" />
  <rect x="100" y="10" width="100" height="100" style="stroke: #000000; fill: url(#pattern2);" />
  <rect x="200" y="10" width="100" height="100" style="stroke: #000000; fill: url(#pattern3);" />
</svg>

<script>
 var svg = d3.select("svg"),
 margin = 200,
 width = svg.attr("width") - margin,
 height = svg.attr("height") - margin
 var xScale = d3.scaleBand().range([0, width]).padding(0.4),
 yScale = d3.scaleLinear().range([height, 0]);
 var g = svg.append("g")
 .attr("transform", "translate(" + 100 + "," + 100 + ")");

 // 定义图案ID数组,顺序对应CSV中的三条数据
 const patternIds = ["pattern1", "pattern2", "pattern3"];

 d3.csv("Year.csv", function(error, data) {
 if (error) {
 throw error;
 }
 xScale.domain(data.map(function(d) { return d.year; }));
 yScale.domain([0, d3.max(data, function(d) { return d.value; })]);
 g.append("g")
 .attr("transform", "translate(0," + height + ")")
 .call(d3.axisBottom(xScale));
 g.append("g")
 .call(d3.axisLeft(yScale).tickFormat(function(d){ return d; }).ticks(10));
 g.selectAll(".bar")
 .data(data)
 .enter().append("rect")
 .attr("class", "bar")
 .attr("x", function(d) { return xScale(d.year); })
 .attr("y", function(d) { return yScale(d.value); })
 .attr("width", xScale.bandwidth())
 .attr("height", function(d) { return height - yScale(d.value); })
 // 根据数据索引匹配对应的图案
 .attr("fill", function(d, index) {
   return `url(#${patternIds[index]})`;
 });
 });
</script>
</body>
</html>

关键改动说明

  • 合并了所有<pattern>到同一个<defs>中,确保SVG能正确识别这些图案资源。
  • 创建了patternIds数组,把三个图案的ID按顺序存起来,对应CSV里2001、2002、2003三条数据。
  • 在设置条形的fill属性时,使用D3提供的第二个参数index(数据项在数组中的位置),来匹配对应的图案ID,实现第一个条形用pattern1、第二个用pattern2、第三个用pattern3的效果。
  • 移除了.bar类的默认fill: steelblue,避免覆盖我们动态设置的图案填充。

这样修改后,每个条形就会分别应用你定义的三种填充图案啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 21:44:10