d3.js ticks函数提供了超出需要的元素

d3.js ticks函数提供了超出需要的元素,d3.js,D3.js,我有一个简单的线性刻度: var x = d3.scale.linear().domain([0, 250]); chart.selectAll("line") .data(x.ticks(11)) .enter() .append("line") .attr("x1", x) .attr("x2", x) .attr("y1", 0) .attr("y2",120) .style("stroke", "#CCC"); x.ti

我有一个简单的线性刻度:

var x = d3.scale.linear().domain([0, 250]);
chart.selectAll("line")
    .data(x.ticks(11))
    .enter()
    .append("line")
    .attr("x1", x)
    .attr("x2", x)
    .attr("y1", 0)
    .attr("y2",120)
    .style("stroke", "#CCC");
x.ticks(6)
按预期返回:

[0, 50, 100, 150, 200, 250]
但是,
x.ticks(11)
返回:

[0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240]
当我想要的是:

[0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250]

如何修复此问题?

您可以通过使用所需阵列替换x.ticks(11)来修复此问题

如果你的代码是这样的,x是你的线性比例:

var x = d3.scale.linear().domain([0, 250]);
chart.selectAll("line")
    .data(x.ticks(11))
    .enter()
    .append("line")
    .attr("x1", x)
    .attr("x2", x)
    .attr("y1", 0)
    .attr("y2",120)
    .style("stroke", "#CCC");
您可以使用阵列替换x.ticks(11):

var desiredArray = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250]
chart.selectAll("line")
    .data(desiredArray)
    .enter()
    .append("line")
    .attr("x1", x)
    .attr("x2", x)
    .attr("y1", 0)
    .attr("y2",120)
    .style("stroke", "#CCC");

线性比例将根据输入自动放置所需的轴。ticks()没有给你你想要的间隔的原因是因为d3只是把ticks()当作一个建议。

我对顺序刻度也有类似的问题,我只是写了一些代码来选择数据中的等距间隔。因为我希望它总是选择轴上的第一个和最后一个数据元素,所以我只计算中间部分。因为有些东西不能平均分配,而不是把剩余的部分放在一两个箱子里,所以我会把它们分散在箱子里;直到没有更多的残留

可能有一种更简单的方法来实现这一点,但以下是我所做的:

function getTickValues(data, numValues, accessor)
{
  var interval, residual, tickIndices, last, i;

  if (numValues <= 0)
  {
    tickIndices = [];
  }
  else if (numValues == 1)
  {
    tickIndices = [ Math.floor(numValues/2) ];
  }
  else
  {
    // We have at least 2 ticks to display.
    // Calculate the rough interval between ticks.
    interval = Math.floor(data.length / (numValues-1));

    // If it's not perfect, record it in the residual.
    residual = Math.floor(data.length % (numValues-1));

    // Always label our first datapoint.
    tickIndices = [0];

    // Set stop point on the interior ticks.
    last = data.length-interval;

    // Figure out the interior ticks, gently drift to accommodate
    // the residual.
    for (i=interval; i<last; i+=interval)
    {
      if (residual > 0)
      {
        i += 1;
        residual -= 1;
      }
      tickIndices.push(i);
    }
    // Always graph the last tick.
    tickIndices.push(data.length-1);
  }

  if (accessor)
  {
    return tickIndices.map(function(d) { return accessor(d); });
  }
  return tickIndices.map(function(i) { return data[i]; });
}
其中,yourData是数据数组,numvalues是所需的刻度数。如果您的数组包含复杂的数据结构,那么可选的访问器就派上了用场

最后,将其输入轴。显然,您可以调用tickValues()而不是ticks(numTicks),后者只是对d3的一个提示

我从中学到了一个艰难的过程,即你的数值必须与你的数据完全匹配。这可能对线性比例有帮助,也可能没有帮助,但我想无论如何我都会分享它

希望这有帮助

轴。数值((函数(最后一个,数值){
var myArray=[0];
对于(变量i=1;i

这将为您提供一个均匀分布的数组,用于指定特定范围内所需的刻度值的数量。

我之所以使用
ticks()
,是有原因的。我想要一个动态数组,而不是静态数组。看看d3源代码,尤其是d3_scale_linearTickRange(domain,m),它生成用于滴答声的值,您将无法生成具有25到滴答声的步长的动态数组,因为滴答声试图生成基于10次幂(如20或0.2)的步长。如果您想要不同的步长,如您正在寻找的25步长,则必须动态生成不带刻度的数组。