圆点刻度

时间:2019-10-11 05:58:37

标签: javascript d3.js math svg

我知道外部的d3-scale-radial.js库,但是我只打算使用一维的圆形比例(而不是像径向条形图或折线图那样的二维)。所以我希望我不需要为看起来似乎很简单的任务包括一个额外的库。这是我使用Illustrator绘制的图像版本:

enter image description here

您会注意到这里没有“ y”轴。它基本上是一个点比例尺,但呈现为圆形。尽管它比多维径向图更简单,但精度和可伸缩性对我来说很重要,因此我不愿意通过将line附加为刻度线,然后构造出一些三角伏特体来将圆定位在沿圆周的精确十进制值-这似乎是唯一的本地d3解决方案。

问题

原生d3可以提供什么来简化简单的径向点图吗?还是我应该暂时放弃并接受radial.js库?

1 个答案:

答案 0 :(得分:1)

不,没有本机D3比例尺,但是您不需要任何比例尺:一个简单的三角数学即可。

对于x位置,将半径乘以您的值的余弦,而对于y位置,则将半径乘以您的值的正弦。由于您的值从01,因此您就可以使用此定位圆(其中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)
})

此外,如果您的值不再从01,请使用基本的线性比例尺对其进行映射。

最复杂的是绘制轴,但并不复杂。

以下是使用[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>