【问题标题】:nvd3 formatting date returns always 1970-01-01nvd3 格式化日期总是返回 1970-01-01
【发布时间】:2014-05-27 13:55:13
【问题描述】:

我正在尝试使用 nvd3d3js 构建折线图,但是在 x 轴上使用日期域时遇到了一些问题。

这是我的代码:

data_lineChart = [
{
    "key" : "key1",
    "values" : [
        { "x" : "2014-04-20",
          "y" : -6
        },
        { "x" : "2014-04-13",
          "y" : -5
        },
        { "x" : "2014-04-06",
          "y" : -1
        },
      ]
},
{
    "key" : "key2",
    "values" : [
        { "x" : "2014-04-20",
          "y" : 6
        },
        { "x" : "2014-04-13",
          "y" : 5
        },
        { "x" : "2014-04-06",
          "y" : 1
        },
      ]
}
]

nv.addGraph(function() {
        var chart = nv.models.lineChart();
        chart.xAxis
            .tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(new Date(d)) });
        chart.yAxis
            .tickFormat(d3.format(',.2f'));
        chart.tooltipContent(function(key, y, e, graph) {
            var x = d3.time.format("%Y-%m-%d")(new Date(parseInt(graph.point.x)));
            var y = String(graph.point.y);
            var y = 'There is ' +  String(graph.point.y)  + ' calls';
            tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
            return tooltip_str;
        });
        d3.select('#chart1 svg')
            .datum(data_lineChart)
            .transition()
            .duration(500)
            .call(chart);
    return chart;
});

我得到的是一个 x 轴,其中每个日期都是 1970-01-01,这是因为

中的 d
chart.xAxis
        .tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(new Date(d)) });

范围从 1 到 -1,而不是预期的 x 值。

这有什么问题?

编辑: 从@AmeliaBR 的解决方案开始,我设法使用以下代码完成了这项工作:

var chart = nv.models.lineChart().x( function(d){ return new Date(d.x);} );
chart.xScale = d3.time.scale();
chart.xAxis.tickFormat(function(d) { return d3.time.format("%d-%m-%Y")(new Date(d)) });

这是因为,在 tickFormat 函数中,d 是作为带有 UNIX 时间戳的 int 传递的,因此我需要在格式化之前再次解析日期。

【问题讨论】:

  • 我想你需要d3.time.format("%Y-%m-%d")(d.x)
  • TypeError: d is undefined
  • @LarsKotthoff,没有 d 传递给刻度格式函数的值将是刻度值本身。问题在链条的上层。

标签: javascript json d3.js charts nvd3.js


【解决方案1】:

您永远不会告诉 NVD3 您的 x 值是日期。默认情况下,对于折线图,NVD3 使用线性(数字)x 轴。当它尝试将每个 x 值日期字符串转换为数字时,它会得到 NaN(不是数字)。因此,它最终没有任何有效的 x 值来创建 x 轴域,并使用 [-1,1] 作为默认值。

您需要告诉图表函数如何从数据中获取有效的线性值。为此,您可以在图表对象上设置 x-accessor 函数:

    var chart = nv.models.lineChart()
                  .x( function(d){ return Date(d.x);} );

您还可以明确告诉图表使用Date scale 作为 x 轴。这不是必需的(一旦将字符串转换为日期,它们可以自动转换为有效数字),但它会产生更好的刻度值(基于日期和时间单位的偶数倍,而不是毫秒的倍数)。

    chart.xScale = d3.time.scale();
    chart.xAxis
        .tickFormat(function(d) { return d3.time.format("%Y-%m-%d")(d) });

请注意,从日期时间刻度传递给刻度格式的刻度值是日期值,因此您只需格式化打印即可,不需要任何转换。

【讨论】:

  • TypeError: d.getFullYear is not a function..为什么没有这个库的文档? :\
  • 是的,我真的希望也有更多的 NVD3 文档,但是我想从事它的人把所有的时间都花在编写代码而不是文档上。如果您删除自定义刻度格式功能,您仍然会收到错误吗?如果是这样,那意味着问题出在您的数据字符串到日期的原始转换中。如果您使用d3 date formatter parse function,您可以更好地控制转换。
  • 另外,您可能希望更改工具提示函数以反映 x 值现在将是 Date 对象的事实...
  • 我已经根据您的回答用工作代码编辑了问题,谢谢:)
  • 很高兴你能成功。我不确定为什么 tickFormatting 函数没有得到传递的日期对象,但它是再次进行转换的一个小修复。
【解决方案2】:

你为什么不直接将纪元时间传递给 x,使用 dateObj.getTime()

更多信息: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Date/getTime

这是我的代码示例:

chart.xAxis     //Chart x-axis settings
      .axisLabel('Date')
      .tickFormat(function(d) { return d3.time.format('%d-%m-%y')(new Date(d)); })
      .rotateLabels(-15); //This is optional but very useful sometimes

这是我传递给值对象的 x 类型:

var tmp = new Date(someDate);
tmp = tmp.getTime();
values : [{x:tmp, y:someData}, {x:tmp1, y:someData1}, etc]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多