我知道外部的d3-scale-radial.js库,但是我只打算使用一维的圆形比例(而不是像径向条形图或折线图那样的二维)。所以我希望我不需要为看起来似乎很简单的任务包括一个额外的库。这是我使用Illustrator绘制的图像版本:
您会注意到这里没有“ y”轴。它基本上是一个点比例尺,但呈现为圆形。尽管它比多维径向图更简单,但精度和可伸缩性对我来说很重要,因此我不愿意通过将line
附加为刻度线,然后构造出一些三角伏特体来将圆定位在沿圆周的精确十进制值-这似乎是唯一的本地d3解决方案。
原生d3可以提供什么来简化简单的径向点图吗?还是我应该暂时放弃并接受radial.js库?
答案 0 :(得分:1)
不,没有本机D3比例尺,但是您不需要任何比例尺:一个简单的三角数学即可。
对于x位置,将半径乘以您的值的余弦,而对于y位置,则将半径乘以您的值的正弦。由于您的值从0
到1
,因此您就可以使用此定位圆(其中r
是半径):
.attr("cx", function(d) {
return r * Math.cos(d * Math.PI * 2)
})
.attr("cy", function(d) {
return r * Math.sin(d * Math.PI * 2)
})
但是,由于您的轴从顶部(即 12点钟)开始,因此将其减去Math.PI / 2
:
.attr("cx", function(d) {
return r * Math.cos(d * Math.PI * 2 - Math.PI / 2)
})
.attr("cy", function(d) {
return r * Math.sin(d * Math.PI * 2 - Math.PI / 2)
})
此外,如果您的值不再从0
到1
,请使用基本的线性比例尺对其进行映射。
最复杂的是绘制轴,但并不复杂。
以下是使用[0.1, 0.25, 0.7]
作为数据的演示:
const w = 300,
h = 300,
r = 100;
const data = [0.1, 0.25, 0.7];
const svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
const g = svg.append("g")
.attr("transform", "translate(" + [w / 2, h / 2] + ")");
const axisLine = g.append("circle")
.attr("r", r)
.style("fill", "none")
.style("stroke", "black");
const axisGroup = g.selectAll(null)
.data(d3.range(0, 1.05, 0.05))
.enter()
.append("g")
.attr("transform", function(d) {
return "rotate(" + (-90 + (d * 360)) + ")";
});
axisGroup.append("line")
.attr("x1", r - 4)
.attr("x2", r + 4)
.style("stroke", "black");
const points = g.selectAll(null)
.data(data)
.enter()
.append("circle")
.style("fill", "dodgerblue")
.attr("r", 8)
.attr("cx", function(d) {
return r * Math.cos(d * Math.PI * 2 - Math.PI / 2)
})
.attr("cy", function(d) {
return r * Math.sin(d * Math.PI * 2 - Math.PI / 2)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>