【问题标题】:Equivalent of d3 scale.bandwidth() for a linear scale's ticks?相当于线性刻度的刻度的 d3 scale.bandwidth()?
【发布时间】:2019-05-30 06:57:46
【问题描述】:

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

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

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

【问题讨论】:

    标签: d3.js svg scale axis


    【解决方案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]);
    }
    

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

    这是一个演示:

    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>

    【讨论】:

      猜你喜欢
      • 2016-06-03
      • 2013-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多