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

在d3js中如何实现柱状图柱子位于x轴刻度之间的效果?

使用D3.js实现跨刻度柱状图的方案

核心实现逻辑

你需要的这种柱子刚好填充两个相邻x轴刻度区间的效果,直接用d3.scaleBand序数波段比例尺的原生特性就可以实现,不需要额外计算柱子位置和宽度。

分步实现代码

  • 第一步:初始化画布和测试数据
// 测试数据集,可替换为你的实际数据
const data = [
  { category: "1月", value: 132 },
  { category: "2月", value: 198 },
  { category: "3月", value: 87 },
  { category: "4月", value: 245 },
  { category: "5月", value: 166 }
];
// 定义画布尺寸和边距
const margin = { top: 20, right: 20, bottom: 30, left: 40 },
      width = 600 - margin.left - margin.right,
      height = 400 - margin.top - margin.bottom;
const svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left},${margin.top})`);
  • 第二步:定义比例尺(核心配置)
    x轴使用d3.scaleBand,将padding设为0即可让柱子完全填满两个相邻刻度的区间:
// x轴比例尺,domain为所有类目值
const x = d3.scaleBand()
  .domain(data.map(d => d.category))
  .range([0, width])
  .padding(0); // 设为0取消柱子间距,完全占满刻度区间
// y轴线性比例尺
const y = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([height, 0]);
  • 第三步:绘制坐标轴
    此时x轴的刻度会自动对齐到每个柱子的左右边界,刚好匹配“柱子位于两个刻度之间”的需求:
// 绘制底部x轴
svg.append("g")
  .attr("transform", `translate(0,${height})`)
  .call(d3.axisBottom(x));
// 绘制左侧y轴
svg.append("g")
  .call(d3.axisLeft(y));
  • 第四步:绘制柱状图
    直接调用x.bandwidth()作为柱子宽度,就能让每个柱子的宽度刚好等于两个相邻刻度的间距:
svg.selectAll(".bar")
  .data(data)
  .enter()
  .append("rect")
  .attr("class", "bar")
  .attr("x", d => x(d.category)) // 柱子左边界对应当前刻度位置
  .attr("width", x.bandwidth()) // 宽度刚好延伸到下一个刻度
  .attr("y", d => y(d.value))
  .attr("height", d => height - y(d.value))
  .attr("fill", "steelblue");

效果调整说明

如果需要柱子之间保留少量间隙,只需要调整scaleBand的padding参数即可,调整后x轴刻度仍然会自动对齐每根柱子的左右边界,不会出现刻度和柱子错位的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:18:03