首页 文章

如何格式化拉丝时间轴(具有上下文相关值)

提问于
浏览
3

我有一个x轴,2009年至2016年为tickValues . 当我从时间窗口小部件中选择一个时间段时,勾选值将成为月份名称和年份的组合(感谢您,d3!) . 所以我以'2014年12月,2月'为例 . 选择更窄的范围会给我一周的名字和日期,例如'六月十四日' .

enter image description here

我希望月份名称显示为缩短的格式,例如12月,2月我知道这将是d3.time.format('%b'),但是我不能在不影响岁月的情况下将tickFormat设置为此(所有这些都是'Jan') .

如何为d3时标轴应用依赖于上下文的tickFormat?

2 回答

  • 1

    我相信你正在寻找d3.time.format.multi:

    例如:

    var customTimeFormat = d3.time.format.multi([
      [".%L", function(d) { return d.getMilliseconds(); }],
      [":%S", function(d) { return d.getSeconds(); }],
      ["%I:%M", function(d) { return d.getMinutes(); }],
      ["%I %p", function(d) { return d.getHours(); }],
      ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
      ["%b %d", function(d) { return d.getDate() != 1; }],
      ["%b", function(d) { return d.getMonth(); }],
      ["%Y", function() { return true; }]
    ]);
    
    //use the custom time format
    var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(customTimeFormat);
    

    这是一个有效的JS小提琴:https://jsfiddle.net/f5fgm9dt/8/

    我发现这有用:http://bl.ocks.org/mbostock/4149176

  • 0

    D3实现了您描述的自适应行为 - 根据值显示月份或年份 - 使用自己的构造之一: d3.time.format.multi() . 该函数, multi() 需要一组多个时间格式化选项,d3根据与每种格式相关的条件选择适当的格式 . 这就是某些 Value 观,如一年中的第一天,成为一年的价格,其他 Value 成为月份价格 .

    (注意:这在d3 3.x中,我猜是你正在使用的 . 在d3 4.x中可能有一个等价物,但我无法在4.x API文档中轻松找到它,所以如果你在4.x上,将需要更多的研究 . )

    该多格式函数的documentation提供了该时间格式选项数组的默认实现,即如果您不使用自己的格式覆盖它,则默认情况下实现d3将使用时间刻度 . 看起来像这样

    var format = d3.time.format.multi([
      [".%L", function(d) { return d.getMilliseconds(); }],
      [":%S", function(d) { return d.getSeconds(); }],
      ["%I:%M", function(d) { return d.getMinutes(); }],
      ["%I %p", function(d) { return d.getHours(); }],
      ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
      ["%b %d", function(d) { return d.getDate() != 1; }],
      ["%B", function(d) { return d.getMonth(); }],
      ["%Y", function() { return true; }]
    ]);
    

    因此,您可以将默认实现复制/粘贴到您自己的项目中,将其设置为轴的tickFormat,然后调整值 . 具体来说,为了回答你的问题,你需要修改该数组的倒数第二个元素,将其转换为:

    ["%b", function(d) { return d.getMonth(); }] // from %B to %b
    

    如果您的时间轴总是跨越数月或数天,您还可以删除该数组的前4或5个元素,因为这些格式永远不会在长时间 Span 中发挥作用 .

    如果这有帮助:如果仍然不清楚上面的格式和函数数组如何最终产生效果,想象一下 d 将在今年的第一天:它将 d.getMonth() 0 (因为在javascript中) 1月是0),事实上,对于 getMonth 上面使用的所有方法,日期将为零(如 getDategetHours 等) . 因此所有这些函数都会在javascript中返回 0 ,这是 false ,并且不会使用这些格式 . 只有最后一个才会返回 true (因为它是硬编码的),并且会显示一年的刻度( %Y ) . 现在,除了1月份之外的任何一个月的第1个刻度将具有非零 getMonth() (但是对于 getDay 等仍然为零),因此在这些情况下将使用倒数第二个格式 .

相关问题