等价于 d3 scale.bandwidth() 用于线性刻度的刻度?

Equivalent of d3 scale.bandwidth() for a linear scale's ticks?

在 D3 中,您可以 return 两个带之间的宽度 band.bandwidth()

如果您已在轴上设置刻度,那么对于您给定的域,d3.scaleLinear() 是否有等效项?

因此,如果您的 tickValues 域是 [-2,-1,0,1,2]scaleLinear.tickWidth() 将为您提供 scaleLinear(0)scaleLinear(1)(或 scaleLinear(-2)scaleLinear(-1)),或者你设置的刻度之间的差异。

如您所知,没有这样的方法。此外,线性标度的带宽(不携带任何信息)的概念本身也没有什么意义。

但是对你的问题的有趣思考是它与线性比例本身无关,它是关于使用该比例生成的(如你所说"...假设您已在轴上设置刻度").

在 D3 中,当我们使用刻度时生成的轴是非常不可预测的(即刻度数及其值),特别是在使用时间刻度时。除此之外,您可以使用 axis.ticks()axis.tickArguments() 更改刻度。因此,使用 scale.ticks() 获取刻度值并不是一种准确的方法。

话虽这么说,您可以使用将轴组本身(一个 SVG <g> 元素)传递给的函数,就像我刚刚写的这个:

function tickWidth(selection) {
    const ticks = selection.selectAll(".tick text")
        .nodes()
        .map(function(d) {
            return +d.textContent;
        });
    return scale(ticks[1]) - scale(ticks[0]);
}

它所做的基本上是获取 .ticks 组内的所有 <text> 元素,将它们转换为数字(它们是字符串)并返回比例的差异。

这是一个演示:

const svg = d3.select("svg");
const scale = d3.scaleLinear()
  .range([50, 450])
  .domain([0, 100]);
const axis = d3.axisBottom(scale);
const axisGroup = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);

const bandwidth = tickWidth(axisGroup);

console.log("the bandwidth is: " + bandwidth + " pixels")

function tickWidth(selection) {
  const ticks = selection.selectAll(".tick text").nodes().map(function(d) {
    return +d.textContent;
  });
  return scale(ticks[1]) - scale(ticks[0]);
}
<svg width="500" height="100"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>

如您所见,此方法考虑了 axis.ticks() 等修改刻度的方法:

const svg = d3.select("svg");
const scale = d3.scaleLinear()
  .range([50, 450])
  .domain([0, 100]);
const axis = d3.axisBottom(scale)
  .ticks(5);
const axisGroup = svg.append("g")
  .attr("transform", "translate(0,50)")
  .call(axis);

const bandwidth = tickWidth(axisGroup);

console.log("the bandwidth is: " + bandwidth + " pixels")

function tickWidth(selection) {
  const ticks = selection.selectAll(".tick text").nodes().map(function(d) {
    return +d.textContent;
  });
  return scale(ticks[1]) - scale(ticks[0]);
}
<svg width="500" height="100"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>