1

我有这个简单的线性比例:

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]

我该如何解决?

4

3 回答 3

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 是您想要的刻度数。如果您的数组包含复杂的数据结构,那么可选访问器会派上用场。

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

我了解到您的 tickValues 必须与您的数据完全匹配序数刻度的艰难方法。这对线性比例可能有用也可能没有,但我想无论如何我都会分享它。

希望这可以帮助。

于 2013-04-09T02:33:16.753 回答
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() 视为建议。

于 2013-04-08T16:00:55.167 回答
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));

这应该为您提供一个均匀分布的数组,用于指定您想要在特定范围内的刻度值的数量。

于 2016-04-28T00:01:28.043 回答