Javascript D3.js勾号格式:显示月份变化的时间

Javascript D3.js勾号格式:显示月份变化的时间,javascript,d3.js,Javascript,D3.js,我使用D3(v4)来显示一个在x轴上有日期的条形图 我试图让勾号显示月份的第1天,除非它是我希望它显示月份的第一天,即指示月份的变化时间。我甚至不知道从哪里开始 当前格式如下所示: 但我希望它看起来更像这样: 生成轴的当前代码如下所示: let timeFormat = "%b %d" xAxis = g => g .attr("transform", `translate(0, ${height - margin.bottom})`) .call(d3.axi

我使用D3(v4)来显示一个在x轴上有日期的条形图

我试图让勾号显示月份的第1天,除非它是我希望它显示月份的第一天,即指示月份的变化时间。我甚至不知道从哪里开始

当前格式如下所示:

但我希望它看起来更像这样:

生成轴的当前代码如下所示:

let timeFormat = "%b %d"
xAxis = g => g
      .attr("transform", `translate(0, ${height - margin.bottom})`)
      .call(d3.axisBottom(x).tickFormat(d3.timeFormat(timeFormat)))
我基本上需要一些类似于

let timeFormat = "%d == 0" ? "%b" :  "%d"
我知道在这种情况下这是胡说八道,但它说明了我要寻找的逻辑

下面是我的图表的一个简化版本:

let key=[];
var w=400;
var h=200;
var保证金={
前30名,
底数:40,
左:50,,
右:20,,
}
变量宽度=w-margin.left-margin.right
变量高度=h-margin.top-margin.bottom
风险值数据=[
{
“计数”:100,
“日期”:“2018-11-30T00:00:00”
},
{
“计数”:50,
“日期”:“2018-12-01T00:00:00”
},
{
“计数”:75,
“日期”:“2018-12-02T00:00:00”
},
]
var x=d3.scaleTime()
.domain(d3.extent(数据,函数(d){返回新日期(d.Date)}))
.范围([0,宽度]);
变量y=d3.scaleLinear()
.domain([0,d3.max(数据,d=>d.count)])
.范围([高度,0]);
var svg=d3。选择('body')。追加('svg'))
.attr('类','图表')
.attr('宽度',w)
.attr('高度',h);
var chart=svg.append('g')
.classed('graph',true)
.attr('transform','translate('+margin.left+','+margin.top+'));
let timeFormat=“%b%d”
chart.append('g')
.classed('x轴',真)
.attr(“变换”、“平移(0)”、“高度+”)
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat(timeFormat))
.滴答声(2)
)
chart.append('g')
.classed('y轴',真)
.call(d3.axisLeft(y))

您可以从
刻度
中获取
刻度
,并使用该刻度查看上一个刻度是否是另一个月,然后根据该刻度选择格式:

const longFormat = d3.timeFormat('%b');
const shortFormat = d3.timeFormat('%d');
const axis = d3.axisBottom(x);
axis.tickFormat((d, i) => {
    const ticks = axis.scale().ticks();

    if (i > 0 && ticks[i - 1].getMonth() === d.getMonth()) {
        return shortFormat(d);
    }
    else {
        return longFormat(d);
    }
});

xAxis = g => g
    .attr("transform", `translate(0, ${height - margin.bottom})`)
    .call(axis)
编辑:如果您不使用时间刻度,而是使用
缩放键
,您应该能够使用域来计算格式:

const ticks = axis.scale().domain();
另一个版本:

    function multiFormat(date) {
      var formatMillisecond = d3.timeFormat(".%L"),
        formatSecond = d3.timeFormat(":%S"),
        formatMinute = d3.timeFormat("%I:%M"),
        formatHour = d3.timeFormat("%I %p"),
        formatDay = d3.timeFormat("%_d"),
        formatWeek = d3.timeFormat("%_d"),
        formatMonth = d3.timeFormat("%b"),
        formatYear = d3.timeFormat("%Y");
      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(d){return multiFormat(d);})
...
函数多格式(日期){
var Format毫秒=d3.timeFormat(“.%L”),
formatSecond=d3.timeFormat(“:%S”),
formatMinute=d3.timeFormat(“%I:%M”),
formatHour=d3.timeFormat(“%I%p”),
formatDay=d3.timeFormat(“%\u d”),
formatWeek=d3.timeFormat(“%\u d”),
formatMonth=d3.timeFormat(“%b”),
formatYear=d3.timeFormat(“%Y”);
返回(d3.时间秒(日期)<日期?格式毫秒
:d3.时间分钟(日期)<日期?格式秒
:d3.时间小时(日期)<日期?分钟
:d3.时间日(日期)<日期?格式小时
:d3.时间月(日期)<日期?(d3.时间周(日期)<日期?格式日:格式周)
:d3.时间年(日期)<日期?格式月
:年份(日期);
}
...
.tickFormat(函数(d){返回多格式(d);})
...
let key=[];
var w=400;
var h=200;
var保证金={
前30名,
底数:40,
左:50,,
右:20,,
}
变量宽度=w-margin.left-margin.right
变量高度=h-margin.top-margin.bottom
风险值数据=[
{
“计数”:100,
“日期”:“2018-11-30T00:00:00”
},
{
“计数”:50,
“日期”:“2018-12-01T00:00:00”
},
{
“计数”:75,
“日期”:“2018-12-02T00:00:00”
},
]
var x=d3.scaleTime()
.domain(d3.extent(数据,函数(d){返回新日期(d.Date)}))
.范围([0,宽度]);
变量y=d3.scaleLinear()
.domain([0,d3.max(数据,d=>d.count)])
.范围([高度,0]);
var svg=d3。选择('body')。追加('svg'))
.attr('类','图表')
.attr('宽度',w)
.attr('高度',h);
var chart=svg.append('g')
.classed('graph',true)
.attr('transform','translate('+margin.left+','+margin.top+'));
函数多格式(日期){
var Format毫秒=d3.timeFormat(“.%L”),
formatSecond=d3.timeFormat(“:%S”),
formatMinute=d3.timeFormat(“%I:%M”),
formatHour=d3.timeFormat(“%I%p”),
formatDay=d3.timeFormat(“%\u d”),
formatWeek=d3.timeFormat(“%\u d”),
formatMonth=d3.timeFormat(“%b”),
formatYear=d3.timeFormat(“%Y”);
返回(d3.时间秒(日期)<日期?格式毫秒
:d3.时间分钟(日期)<日期?格式秒
:d3.时间小时(日期)<日期?分钟
:d3.时间日(日期)<日期?格式小时
:d3.时间月(日期)<日期?(d3.时间周(日期)<日期?格式日:格式周)
:d3.时间年(日期)<日期?格式月
:年份(日期);
}
chart.append('g')
.classed('x轴',真)
.attr(“变换”、“平移(0)”、“高度+”)
.call(d3.axisBottom(x)
.tickFormat(函数(d){返回多格式(d);})
.滴答声(2)
)
chart.append('g')
.classed('y轴',真)
.call(d3.axisLeft(y))

也许你的问题是第一个日期不是
0
,是
1
,你不能这样检查,
%d
%b
是占位符,也许你需要检查
是否让timeFormat=d3.timeFormat(“%d”)=“01”?“%b”:“%d”
@oma“第一次约会”是什么意思?我知道我不能这样检查,我在我的问题中说,这只是为了说明我所问问题背后的逻辑。你能检查一下我第二条评论的内容吗?它在工作?不,它不工作,它只是显示一天。这是因为它只是声明一个字符串,所以它不能更改它的值,因为它不会对每个勾号重复调用。谢谢你的帮助。谢谢,这正是我要找的东西。我现在得到错误“d3.axisBottom(…).scale(…)。ticks不是函数”。这可能是D3版本(我使用的是v4)的问题吗?哦,可能。我也在使用这段代码,但我使用的是v5。如果我能在跳到5之前看到它,我会后悔的。@Charlie你能在这里创建一个代码片段或者为y创建一个jsFiddle吗