线性刻度刻度的 d3 scale.bandwidth() 等效吗?

Lea*_*ple 4 svg axis scale d3.js

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

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

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

Ger*_*ado 6

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

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

在 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]);
}
Run Code Online (Sandbox Code Playgroud)

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

这是一个演示:

function tickWidth(selection) {
    const ticks = selection.selectAll(".tick text")
        .nodes()
        .map(function(d) {
            return +d.textContent;
        });
    return scale(ticks[1]) - scale(ticks[0]);
}
Run Code Online (Sandbox Code Playgroud)
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]);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,此方法考虑了诸如 之类的方法axis.ticks(),这些方法修改了刻度:

<svg width="500" height="100"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
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]);
}
Run Code Online (Sandbox Code Playgroud)