D3.js 如何在d3.scaleTime()轴刻度中禁用年?

D3.js 如何在d3.scaleTime()轴刻度中禁用年?,d3.js,D3.js,对于D3(v4,升级到v5也是一个选项),我正在绘制一个时间间隔的时间序列。数据的持续时间未知,通常为秒数,我们有一个开始日期戳和一个结束日期戳 我目前正在生成一个x轴,其中startTime和endTime是数字时间戳,width和height是数字,xAxisGroupSelection是D3选择: const xScale = d3.scaleTime() .domain([0, startTime - endTime) .range([0, width]) const xAxi

对于D3(v4,升级到v5也是一个选项),我正在绘制一个时间间隔的时间序列。数据的持续时间未知,通常为秒数,我们有一个开始日期戳和一个结束日期戳

我目前正在生成一个x轴,其中
startTime
endTime
是数字时间戳,
width
height
是数字,
xAxisGroupSelection
是D3选择:

const xScale = d3.scaleTime()
  .domain([0, startTime - endTime)
  .range([0, width])

const xAxis = d3.axisBottom()
  .scale(this.xScale)

xAxisGroupSelection
  .attr('transform', `translate(0, ${height})`)
  .call(xAxis)
这很好的一点是,它为数字提供了合理的格式。例如,它将秒设置为
:01
,毫秒设置为
.500
,如果我得到一个相当长的间隔,持续几分钟或几小时,它将处理这个问题

问题是,由于它读取的是
0
时间戳,因此在概要文件的开头添加了
1970
年份标签。对于时间戳
0
,这当然是正确的年份,但我不希望它以秒为时间序列显示任何年份。是否有任何方法使用D3配置我可以保持默认的时间格式,但不添加年(或月、日等)的刻度


1970
.500
:01
.500
显然,我有很多迂回的方法可以删除或修改它,从使用CSS第一个子规则隐藏它到在D3中手动选择它并修改它的值,但我想知道是否可以在D3中这样做 使用D3比例/轴/格式/时间API的干净方式

我可以告诉D3的轴刻度生成器忽略大于分钟的时间单位吗?我已经查过了,但什么也找不到。我想也许可以使用



更新:看起来我需要创建一个自定义函数来传递到
.tickFormat()
,类似于,但复制了默认时间格式化程序,并在条件逻辑中添加了一个截止点。那么下一个问题:我在哪里可以找到默认的D3时间格式逻辑…

查看D3源代码,似乎默认的智能时间刻度格式化程序都在D3 scale/src/time.js中的私有函数中。它看起来是完全可以接受或保留的:您可以按原样使用它,也可以通过将自定义函数传递给
.tickFormat()
来完全替换它

因此,您需要创建一个自定义函数,从
d3 scale/src/time.js
calendar
导出中复制所需的逻辑,尤其是嵌套的
函数tickFormat(date)

在我的例子中,它的一个重要部分是将时间戳0格式化为返回0的特例,而不是对1970年第一毫秒的最广泛描述。所以我的功能基本上是:

xAxis.tickFormat((date) => {
  // If this describes 0 milliseconds from the Epoch, return '0'
  if (d3.timeFormat('%Q')(date) === '0') return '0'
  // Then copy and paste as many lines as needed from `d3-scale/src/time.js`
  // from the `function tickFormat` adding the definitions of the formatters
  // like `formatMillisecond` etc from the `calendar` scope
})
我试图找到一种方法来提取默认的勾号格式化程序,这样我就可以只进行0检查,然后使用默认值而不复制任何内容,但是我找不到任何方法来访问它


除了D3源代码中的代码外,D3中还有一个条件时间格式的演示:

查看D3源代码,默认的智能时间刻度格式化程序似乎都在D3 scale/src/time.js中的私有函数中。它看起来是完全可以接受或保留的:您可以按原样使用它,也可以通过将自定义函数传递给
.tickFormat()
来完全替换它

因此,您需要创建一个自定义函数,从
d3 scale/src/time.js
calendar
导出中复制所需的逻辑,尤其是嵌套的
函数tickFormat(date)

在我的例子中,它的一个重要部分是将时间戳0格式化为返回0的特例,而不是对1970年第一毫秒的最广泛描述。所以我的功能基本上是:

xAxis.tickFormat((date) => {
  // If this describes 0 milliseconds from the Epoch, return '0'
  if (d3.timeFormat('%Q')(date) === '0') return '0'
  // Then copy and paste as many lines as needed from `d3-scale/src/time.js`
  // from the `function tickFormat` adding the definitions of the formatters
  // like `formatMillisecond` etc from the `calendar` scope
})
我试图找到一种方法来提取默认的勾号格式化程序,这样我就可以只进行0检查,然后使用默认值而不复制任何内容,但是我找不到任何方法来访问它

除了D3源代码中的代码外,D3中还有一个条件时间格式的演示:

您可以在轴上使用.tickFormat(),其格式化函数如下:

function multiFormat(date) {
return (d3.timeSecond(date) < date ? formatMillisecond
: d3.timeMinute(date) < date ? formatSecond
: d3.timeHour(date) < date ? formatMinute
: d3.timeDay(date) < date ? formatHour
: d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : 
formatWeek)
: d3.timeYear(date) < date ? formatMonth
: formatYear)(date);
}
您可以在轴上使用.tickFormat(),并使用如下格式化函数:

function multiFormat(date) {
return (d3.timeSecond(date) < date ? formatMillisecond
: d3.timeMinute(date) < date ? formatSecond
: d3.timeHour(date) < date ? formatMinute
: d3.timeDay(date) < date ? formatHour
: d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : 
formatWeek)
: d3.timeYear(date) < date ? formatMonth
: formatYear)(date);
}