D3.js 如何在d3.scaleTime()轴刻度中禁用年?
对于D3(v4,升级到v5也是一个选项),我正在绘制一个时间间隔的时间序列。数据的持续时间未知,通常为秒数,我们有一个开始日期戳和一个结束日期戳 我目前正在生成一个x轴,其中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
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);
}