为什么我的 d3 图表的 x 轴包含每个月的第一天作为一个刻度,即使我将刻度间隔设置为每 7 天?

Why does my d3 chart's x-axis include the first of every month as a tick even though I set the tick interval to every 7 days?

我是 d3 的新手,但我使用 d3.timeDay.every(7) 将 x 轴的刻度间隔设置为每 7 天一次。但是,当我创建图表时,我还会看到为每个月的第一天添加了一个刻度线。例如,my graph 在 10/1、10/8、10/15、10/22、10/29 和 11/1 显示刻度,即使 11/1 不是 10/29 之后的 7 天。如果我将此范围扩大到包括多个月,我会在每个月的第一天看到一个勾号。

我在下面包含了这个轴的代码。什么可能导致每个月的第一天显示为勾号?

  const xScale = d3.scaleTime().range([0, innerWidth]);
  const tickAmount = d3.timeDay.every(7);

  chart.append("g")
    .classed('x-axis', true)
    .attr("transform", "translate(0," + innerHeight + ")")
    .call(d3.axisBottom(xScale)
    .ticks(tickAmount)
    .tickSize(-innerHeight)
    .tickFormat(d3.timeFormat('%m/%d/%y')));

请尝试 const tickAmount = d3.timeWeek.every(1);

Note that for some intervals, the resulting dates may not be uniformly-spaced; d3.timeDay’s parent interval is d3.timeMonth, and thus the interval number resets at the start of each month. If step is not valid, returns null. If step is one, returns this interval. from the d3 docs

如果您愿意,您也可以使用 .tickFormat(function(d, i) { return d; }) 从显示中过滤掉给定的报价(例如,排除第一个报价:return i>0 ? d : ''),尽管这更 hacky。

找到了更好的方法from d3 issue tracker:

d3.axisBottom(x)
  .ticks(d3.timeDay.filter(d=>d3.timeDay.count(0, d) % N === 0))
  .tickFormat(d3.timeFormat('%m/%d/%y'))
  .tickSizeOuter(0)

这将使您每隔 N-th 天获得一致的报价,而不会重复月份。刻度存在并不意味着数据集中该日期存在点,但它们在日期范围内正确缩放。

这是一个演示:https://beta.observablehq.com/@thmsdnnr/d3-ticks-every-7-or-10-days