我遇到的最接近的答案是@Lars Kotthoff 建议的多尺度时间格式。我将自定义时间格式化程序编辑为:
http://jsfiddle.net/BdGv5/1/
var customTimeFormat = timeFormat([
[d3.time.format("%Y"), function() { return true; }],
[d3.time.format("%b"), function(d) { return d.getMonth(); }],
[function(){return "";}, function(d) { return d.getDate() != 1; }]
]);
因此,放大时仍然会生成刻度本身,但标签将为空字符串。
UPDATE:
我最终创建了自己在 .ticks() 中使用的函数。 Ticks 将刻度范围作为 t0 和 t1 传递给您的函数。我将图表宽度除以标签大小(和填充),以找到不重叠的最大标签数量,并使用下划线删除所有其他刻度(如果发生重叠)。
http://jsfiddle.net/BdGv5/3/
function customTickFunction(t0, t1, dt)
{
var labelSize = 30; // largest label is 23 pixels ("May")
var maxTotalLabels = Math.floor(width / labelSize);
function step(date, offset)
{
date.setMonth(date.getMonth() + offset);
}
var time = d3.time.month.ceil(t0), times = [];
while (time < t1) times.push(new Date(+time)), step(time, 1);
if(times.length > maxTotalLabels)
times = _.filter(times, function(d){
return (d.getMonth() + 1) % 2;
});
return times;
}
var domain = xScale.domain();
var xAxisMonthsFunction = d3.svg.axis().scale(xScale)
.ticks(customTickFunction)
.tickFormat(d3.time.format("%b"))
.orient("bottom");
更新2:
http://jsfiddle.net/BdGv5/5/
使刻度调整进一步不仅仅是 1 个级别,现在它有 4 个级别 (2、3、4、6)。
function customTickFunction(t0, t1, dt)
{
var labelSize = 30; // largest label is 23 pixels ("May")
var maxTotalLabels = Math.floor(width / labelSize);
function step(date, offset)
{
date.setMonth(date.getMonth() + offset);
}
var time = d3.time.month.ceil(t0), times = [], monthFactors = [2,3,4,6];
while (time < t1) times.push(new Date(+time)), step(time, 1);
var i;
for(i=1 ; times.length > maxTotalLabels ; i++)
times = _.filter(times, function(d){
return (d.getMonth()) % monthFactors[i] == 0;
});
return times;
}