d3.js ticks函数给出了比需要更多的元素

时间:2013-04-08 13:15:20

标签: d3.js

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

var x = d3.scale.linear().domain([0, 250]);
按预期,

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]

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

我有一个与序数尺度类似的问题,我只是编写了一些代码来在我的数据中选择均匀间隔的间隔。因为我希望它始终选择轴上的第一个和最后一个数据元素,所以我只计算中间部分。因为有些东西不能均匀分配,而不是在一个或两个箱子中留下残余物,所以当我走的时候,我将它散布在箱子上;直到没有更多的残余。

可能有一种更简单的方法可以实现这一目标,但这就是我所做的:

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]; });
}

您可以通过以下方式调用该功能:

getTickvalues(yourData, numValues, [optionalAccessor]);

如果yourData是您的数据数组,则numvalues是您想要的刻度数。如果您的数组包含复杂的数据结构,那么可选的访问器就派上用场了。

最后,您将其输入轴。而不是滴答声(numTicks),它只是对d3的暗示,而是改为调用tickValues()。

我很难理解你的tickValues必须与你的数据完全匹配顺序量表。这对于线性尺度可能有用也可能没有帮助,但我认为无论如何我都会分享它。

希望这有帮助。

  • 专利

答案 1 :(得分:1)

您可以通过将x.ticks(11)替换为所需的数组来解决此问题。

因此,如果您的代码看起来像这样,x就是您的线性比例:

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()视为一个建议。

答案 2 :(得分:0)

  axis.tickvalues((function(last, values) {
    var myArray = [0];
    for(var i = 1; i < values; i++) {
      myArray.push(last*i/(values-1))
    }
    return myArray;
  })(250, 11));

这应该为您提供一个均匀间隔的数组,用于指定特定范围内所需的刻度值数。