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

如何使用d3.js的area()方法正确绘制正方形?

问题解答
  • 用d3.js的area区域生成器完全可以画出正方形,原有代码出不来预期效果,是三个地方存在错误。

原代码的错误点

  1. 数据点顺序混乱:d3.area是严格按照数组顺序连点生成路径的,原有数据点顺序为(0,0) → (5,0) → (0,5) → (5,5),连起来本身就是交叉折线,无法围成闭合正方形。
  2. 生成器配置逻辑偏差:代码中把y0固定为yScale(0),等于区域下边界永远贴在y=0的水平线上,只有上边界跟随数据变化,这种配置是为常规沿x轴展开的面积图设计的,无法围出方形轮廓。
  3. 比例尺存在拉伸变形:x比例尺0-6的数值范围对应150像素长度,y比例尺0-20的数值范围才对应150像素长度,x、y方向相同数值差对应的像素长度不一致,即便路径正确,画出来的也是拉长的矩形,不是正正方形。

正确实现代码

area生成器的工作逻辑很简单:按数组顺序连接所有(x, y1)点作为上轮廓,再倒序连接所有(x, y0)点作为下轮廓,最后自动把两段轮廓的首尾连起来,形成闭合区域。只要把上下轮廓的点设置成正方形的对应边,就能直接生成正方形:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg id="demo1" width="200" height="200"></svg>
<script>
// 两个点分别对应正方形左右两条边的位置
var data = [
  {x: 0, yTop: 5, yBottom: 0},
  {x: 5, yTop: 5, yBottom: 0}
];

// 修正比例尺,x、y单位数值对应相同像素长度,避免图形拉伸
var xScale = d3.scaleLinear().domain([0, 6]).range([25, 175]);
var yScale = d3.scaleLinear().domain([0, 6]).range([175, 25]);

var area = d3.area()
  .x(d => xScale(d.x))
  .y0(d => yScale(d.yBottom)) // 下轮廓连接(0,0)→(5,0),对应正方形下边
  .y1(d => yScale(d.yTop));   // 上轮廓连接(0,5)→(5,5),对应正方形上边
// 生成器会自动补全左右两条边:(5,5)连(5,0)、(0,0)连(0,5),刚好围成闭合正方形

d3.select("#demo1")
.append("path")
.attr("d", area(data))
.attr("fill", "red")
.attr("stroke", "black");
</script>

运行后就会在画布中间得到一个带黑色描边的红色正方形。如果要画任意角度、任意位置的正方形,只要对应调整x0/x1、y0/y1的取值,匹配正方形的轮廓点即可——area本质就是闭合路径生成工具,只要点的坐标和顺序正确,任何闭合多边形都能绘制,正方形当然也可以实现。

原错误代码运行效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:18:16