D3.js D3时间刻度轴刻度在年份边界上是不规则的

D3.js D3时间刻度轴刻度在年份边界上是不规则的,d3.js,D3.js,更新:已使用解决方案更新 计算刻度位置时,是否可以使时间刻度轴的默认刻度生成器忽略月份和年份边界 如中所示,当带有日刻度的D3时间刻度轴跨越年底时,默认的刻度生成器有时会绘制间距不规则的刻度。此代码(也在上面的要点中)导致轴上每隔两天都有刻度,12月31日和1月1日除外,这两天都是绘制的,导致外观不规则。我用红色突出显示了不受欢迎的记号标签 <!DOCTYPE html> <meta charset="utf-8"> <style> p { width:

更新:已使用解决方案更新

计算刻度位置时,是否可以使时间刻度轴的默认刻度生成器忽略月份和年份边界

如中所示,当带有日刻度的D3时间刻度轴跨越年底时,默认的刻度生成器有时会绘制间距不规则的刻度。此代码(也在上面的要点中)导致轴上每隔两天都有刻度,12月31日和1月1日除外,这两天都是绘制的,导致外观不规则。我用红色突出显示了不受欢迎的记号标签

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  p { width: 600px; margin-bottom: 30px; }
  .chart { shape-rendering: crispEdges; }
  .axis text { font: 10px sans-serif; }
  .axis line, .axis path { fill: none; stroke: black; }
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var start_date = "2013-12-21T00:00:00Z",
    end_date   = "2014-01-07T00:00:00Z",
    iso        = d3.time.format.iso,
    t1         = iso.parse(start_date),
    t2         = iso.parse(end_date),

var margin = {top: 0, right: 10, bottom: 20, left: 10},
    width  = 600 - margin.left - margin.right,
    height = 100 - margin.top - margin.bottom;

var x = d3.time.scale()
    .domain([t1, t2])
    .range([0, width])

var xAxis = d3.svg.axis()
    .scale(x)

var svg = d3.select("body").append("svg")
    .attr("class", "chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append('g')
    .attr('class', 'x axis')
    .call(xAxis)
  .selectAll('text')
    .attr('fill', function(d) { if(is_problematic(d)) { return "red"; } })

function is_problematic(d) {
  return ((d.getDate() == 31) || (d.getDate() == 1));
}

p{宽度:600px;边距底部:30px;}
.chart{形状呈现:CrispEdge;}
.axis文本{font:10px无衬线;}
.axis line、.axis path{填充:无;笔划:黑色;}
var start_date=“2013-12-21T00:00:00Z”,
end_date=“2014-01-07T00:00:00Z”,
iso=d3.time.format.iso,
t1=iso.parse(开始日期),
t2=iso.parse(结束日期),
var margin={top:0,right:10,bottom:20,left:10},
宽度=600-边距。左侧-边距。右侧,
高度=100-margin.top-margin.bottom;
var x=d3.time.scale()
.域([t1,t2])
.范围([0,宽度])
var xAxis=d3.svg.axis()
.比例(x)
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“类别”、“图表”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
append('g')
.attr('class','x轴')
.呼叫(xAxis)
.selectAll('text')
.attr('fill',函数(d){if(是有问题的(d)){返回“red”;})
函数有问题(d){
返回((d.getDate()==31)| |(d.getDate()==1));
}

如果明确设置刻度值,可以避免奇怪的年终取整问题:

var xAxis = d3.svg.axis()
    .scale(x)
    .tickValues(d3.time.days(t1, t2).filter(function(d, i){ return !(i % 2); }))

谢谢你,亚当。我忘了在我的问题中提到,我希望相同的代码处理不同长度的序列。如果我通过覆盖默认值每隔一个标签显示一次,当显示100天时,轴将变得过于拥挤。我希望以某种方式保留现有的标签筛选行为。您的回答让我找到了解决方案,即计算标签之间需要跳过多少间隔。因为我知道标签的宽度,也知道图表的宽度,所以我在解决方案中使用了
var max\u label\u count=width/label\u width,var label\u skip=Math.ceil(interval.range(t1,t2).length/max\u label\u count)
,然后将
label\u skip
替换为
2