【问题标题】:how to format time on xAxis use d3.js如何使用 d3.js 在 x 轴上格式化时间
【发布时间】:2013-03-06 11:00:50
【问题描述】:

根据http://bl.ocks.org/mbostock/3883245上的演示

我不知道如何在 xAxis 上格式化时间

这是我的代码: js:

变量数据 = [{ "creat_time": "2013-03-12 15:09:04", “记录状态”:“好的”, "roundTripTime": "16" }, { "creat_time": "2013-03-12 14:59:06", “记录状态”:“好的”, “往返时间”:“0” }, { "creat_time": "2013-03-12 14:49:04", “记录状态”:“好的”, “往返时间”:“297” }, { "creat_time": "2013-03-12 14:39:06", “记录状态”:“好的”, “往返时间”:“31” },{ "creat_time": "2013-03-12 14:29:03", “记录状态”:“好的”, “往返时间”:“0” }]; var margin = {上:20,右:20,下:30,左:50}; var 宽度 = 960 - margin.left - margin.right; var height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; var x = d3.time.scale() .range([0, 宽度]); var y = d3.scale.linear() .range([高度, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("底部"); var yAxis = d3.svg.axis() .scale(y) .orient("左"); var line = d3.svg.line() .x(函数(d){返回x(d.creat_time);}) .y(function(d) { return y(d.roundTripTime); }); var svg = d3.select("body").append("svg") .attr("宽度", width + margin.left + margin.right) .attr("高度", 高度 + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); data.forEach(函数(d){ d.creat_time = parseDate(d.creat_time); d.roundTripTime = +d.roundTripTime; }); x.domain(d3.extent(data, function(d) { return d.creat_time; })); y.domain(d3.extent(data, function(d) { return d.roundTripTime;})); svg.append("g") .attr("类", "x 轴") .attr("变换", "翻译(0," + 高度 + ")") .call(xAxis); svg.append("g") .attr("类", "y 轴") .call(yAxis) .append("文本") .attr("变换", "旋转(-90)") .attr("y", 6) .attr("dy", ".71em") .style("文本锚", "结束") .text("返回时间(ms)"); svg.append("路径") .datum(数据) .attr("类", "行") .attr("d", 行);

这是 svg:

在 svg 中,时间是 12 小时制,但在我的数据中,时间是 24 小时制。 如何在 svg 和 data 上保持相同的格式?

感谢任何帮助。 (ps:希望你不要介意我的英语,它太糟糕了。)

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    您可以在轴对象上使用 tickFormat 函数,如下所示

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickFormat(d3.time.format("%H"));
    

    %H 指定 hour (24-hour clock) as a decimal number [00,23]。查看此链接D3 time formatting 了解更多信息

    您可以在此支流24hr time example 中查看一个工作示例

    【讨论】:

    • 我更新了指向格式参考的链接,因为这篇文章将我带到了正确的位置,并额外点击了几下 - 并获得了支持
    【解决方案2】:

    公认的答案确实是正确的,但就我而言,我需要灵活地调整格式以适应不同的比例(想想缩放),还要确保使用 24 小时制。关键是定义多分辨率时间格式。详情请参阅Documentation 页面。

    我的代码:

    var axisTimeFormat = d3.time.format.multi([
        [".%L", function(d) { return d.getMilliseconds(); }],
        [":%S", function(d) { return d.getSeconds(); }],
        ["%H:%M", function(d) { return d.getMinutes(); }],
        ["%H:%M", 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; }]
     ]);
    
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom")
        .tickFormat(axisTimeFormat);
    

    【讨论】:

      【解决方案3】:

      我想将this link 添加到一个很棒的演示页面。当您可以选择您的案例所需的格式说明符时,这是一个游乐场。当您不记得/不知道应该将什么格式说明符传递给 d3.timeFormat 函数时,它非常有用。

      我还想注意,如果你有 d3 版本 4,你应该使用 d3.timeFormat 函数,而不是 d3.time.format

      【讨论】:

      • 我收到了TypeError: d3.timeFormat.multi is not a function。那么是否还需要其他一些更改?
      【解决方案4】:

      在 v4 中,

      ...
      var scaleX = d3.scaleTime().range([0, width]);
      var axisBottom = d3.axisBottom(scaleX)
                         .ticks(d3.timeMinute, 10); // Every 10 minutes
      ...
      

      注意使用d3.timeMinute - 而不是d3.timeMinutes

      【讨论】:

        【解决方案5】:

        对于 d3 v4 及更高版本中的多分辨率时间格式d3.time.multi 已被弃用。相反,您可以自己定义格式并使用三元来检测正确的时间,使用time intervals

        var formatMillisecond = d3.timeFormat(".%L"),
            formatSecond = d3.timeFormat(":%S"),
            formatMinute = d3.timeFormat("%I:%M"),
            formatHour = d3.timeFormat("%I %p"),
            formatDay = d3.timeFormat("%a %d"),
            formatWeek = d3.timeFormat("%b %d"),
            formatMonth = d3.timeFormat("%B"),
            formatYear = d3.timeFormat("%Y");
        
        function multiFormat(date) {
          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);
        }
        

        当调用像d3.timeDay(date)这样的时间间隔时,它会将当前日期下降到一天、一周等。

        如果下限日期等于当前日期,则d3.timeSecond(date) &lt; date 将为假。但如果它更小(这意味着,您可以确定日期),那就是真的,我们使用格式化程序。

        在实践中:

        var d = new Date(2020,1,2) // 2020-02-02T00:00
        
        // floor to nearest second
        d3.timeSecond(d) // 2020-02-02T00:00, date gets floored but is equal to date 
                         // after flooring, since it already was :00 seconds
        d3.timeSecond(d) < d // equal so false, move on to next precision
        
        // ...
        // floor to nearest month
        d3.timeMonth(d) // 2020-02-01T00:00, date gets floored to months
        d3.timeMonth(d) < d // floored date is now smaller, so true, and use month formatter
        

        来自d3-time-format的代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-11
          • 2012-05-20
          • 1970-01-01
          相关资源
          最近更新 更多