【问题标题】:D3 time scale axis ticks are irregular on year boundariesD3 时间刻度轴刻度在年份边界上不规则
【发布时间】:2014-01-23 00:24:14
【问题描述】:

更新:bl.ocks.org example 已更新解决方案。

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

this bl.ocks.org example 中所见,当带有日刻度的 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));
}

【问题讨论】:

    标签: d3.js


    【解决方案1】:

    如果您明确设置刻度值,您将避免奇怪的年终舍入问题:

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

    fixed

    【讨论】:

    • 谢谢亚当。我忘了在我的问题中提到我想要相同的代码来处理不同长度的系列。如果我通过覆盖默认的刻度值来显示所有其他标签,那么当显示 100 天时,轴将变得过于拥挤。我希望以某种方式保留现有的标签剔除行为。
    • 你的回答让我想到了我的解决方案,即计算我需要在标签之间跳过多少间隔。因为我知道标签的宽度,也知道图表的宽度,所以我在您的解决方案中使用了var max_label_count = width / LABEL_WIDTH, var label_skip = Math.ceil(interval.range(t1, t2).length / max_label_count),然后用label_skip 替换了2
    猜你喜欢
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多