如何让 d3 tickFormat 为 (day, time) 但仅在日期相同时显示时间?

Chr*_*ker 4 d3.js

我有一个 D3 图表,我希望轴上有日期、时间的刻度(例如“1 月 20 日,上午 12:00”)。

这很容易,我只需:

xAxis.tickFormat(d3.time.format('%b %-d, %-I:%M%p'));
Run Code Online (Sandbox Code Playgroud)

这会产生

  • 1 月 20 日 12:00
  • 1 月 20 日中午 12:00
  • 1 月 21 日 12:00
  • 1 月 21 日中午 12:00
  • ETC...

我希望它做的是当日期与前一个刻度相同时,不显示日期而只显示时间。(基本上只显示不同的部分)

  • 1 月 20 日 12:00
  • 12:00 PM
  • 1 月 21 日 12:00
  • 12:00 PM

这可能吗?据我所知,您提供给 tickFormat 的回调没有给出提供给前一个函数的值。它为您提供当前值、刻度索引和第三个数字(不确定它的用途)

Dog*_*ert 5

在 D3 v3 中,您可以使用axis.scale().ticks()访问上一个刻度,并使用自定义tickFormat来检查并返回适当的文本:

var data = [new Date("2016/01/01"), new Date("2016/01/03")];

var scale = d3.time.scale()
  .domain(d3.extent(data))
  .range([0, 400]);

var timeFormatWithDate = d3.time.format("%b %-d, %-I:%M%p");
var timeFormatWithoutDate = d3.time.format("%-I:%M%p");

var axis = d3.svg.axis()
  .scale(scale)
  .orient("left")
  .tickFormat(function(d, i) {
    var ticks = axis.scale().ticks();
    if (i > 0 && ticks[i - 1].getDay() === d.getDay()) {
      return timeFormatWithoutDate(d);
    } else {
      return timeFormatWithDate(d);
    }
  });

d3.select("body")
  .append("svg")
  .attr("width", 400)
  .attr("height", 420)
  .append("g")
  .attr("transform", "translate(200, 10)")
  .data(data)
  .call(axis);
Run Code Online (Sandbox Code Playgroud)

截屏

https://jsfiddle.net/Dogbert/gy5h364g/3/