处理 d3.js 轴上的日期

Posted

技术标签:

【中文标题】处理 d3.js 轴上的日期【英文标题】:dealing with dates on d3.js axis 【发布时间】:2012-01-08 05:56:56 【问题描述】:

如何根据 d3.js 中的日期制作我的线 x 轴?

我正在尝试自学如何使用 d3.js。我一直在查看它附带的示例,并一直在尝试使用 json 传递的数据重新创建折线图。我可以将数据输入折线图,但 x 轴应该是日期而不是数字。我使用的日期格式是 MM/DD/YY,但图表将所有内容都绘制为 0。我的 json 数据很好,但我无法弄清楚如何绘制 x 坐标。这直接取自下载时 d3.js 示例文件夹中的 line.js。日期部分不起作用。我希望有人能给我举个例子,或者能够解释我如何使它起作用。

d3.json('jsonChartData.action',
  function (data) 
    console.log(data);

    var w = 450,
    h = 275,
    p = 30,
    x = d3.scale.linear().domain([0, 100]).range([0, w]),
    y = d3.scale.linear().domain([0, 100]).range([h, 0]);

    var vis = d3.select("body")
    .data([data])
    .append("svg:svg")
    .attr("width", w + p * 2)
    .attr("height", h + p * 2)
    .append("svg:g")
    .attr("transform", "translate(" + p + "," + p + ")");

    var rules = vis.selectAll("g.rule")
    .data(x.ticks(5))
    .enter().append("svg:g")
    .attr("class", "rule");

    rules.append("svg:line")
    .attr("x1", x)
    .attr("x2", x)
    .attr("y1", 0)
    .attr("y2", h - 1);

    rules.append("svg:line")
    .attr("class", function(d)  return d ? null : "axis"; )
    .attr("y1", y)
    .attr("y2", y)
    .attr("x1", 0)
    .attr("x2", w + 1);

    rules.append("svg:text")
    .attr("x", x)
    .attr("y", h + 3)
    .attr("dy", ".71em")
    .attr("text-anchor", "middle")
    .text(x.tickFormat(10));

    rules.append("svg:text")
    .attr("y", y)
    .attr("x", -3)
    .attr("dy", ".35em")
    .attr("text-anchor", "end")
    .text(y.tickFormat(10));

    vis.append("svg:path")
    .attr("class", "line")
    .attr("d", d3.svg.line()
    .x(function(d)  return x(d3.time.days(new Date(d.jsonDate))); )
    .y(function(d)  return y(d.jsonHitCount); ));

    vis.selectAll("circle.line")
    .data(data)
    .enter().append("svg:circle")
    .attr("class", "line")
    .attr("cx", function(d)  return x(d3.time.days(new Date(d.jsonDate))); )
    .attr("cy", function(d)  return y(d.jsonHitCount); )
    .attr("r", 3.5);
  );

我的操作打印出的 JSON:

["jsonDate":"09\/22\/11","jsonHitCount":2,"seriesKey":"Website Usage",`"jsonDate":"09\/26\/11","jsonHitCount":9,"seriesKey":"Website Usage","jsonDate":"09\/27\/11","jsonHitCount":9,"seriesKey":"Website Usage","jsonDate":"09\/29\/11","jsonHitCount":26,"seriesKey":"Website Usage","jsonDate":"09\/30\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/03\/11","jsonHitCount":3,"seriesKey":"Website Usage","jsonDate":"10\/06\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/11\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/12\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/13\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"10\/14\/11","jsonHitCount":5,"seriesKey":"Website Usage","jsonDate":"10\/17\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/18\/11","jsonHitCount":6,"seriesKey":"Website Usage","jsonDate":"10\/19\/11","jsonHitCount":8,"seriesKey":"Website Usage","jsonDate":"10\/20\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"10\/21\/11","jsonHitCount":4,"seriesKey":"Website Usage","jsonDate":"10\/24\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"10\/25\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"10\/27\/11","jsonHitCount":3,"seriesKey":"Website Usage","jsonDate":"11\/01\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"11\/02\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"11\/03\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"11\/04\/11","jsonHitCount":37,"seriesKey":"Website Usage","jsonDate":"11\/08\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"11\/10\/11","jsonHitCount":39,"seriesKey":"Website Usage","jsonDate":"11\/11\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"11\/14\/11","jsonHitCount":15,"seriesKey":"Website Usage","jsonDate":"11\/15\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"11\/16\/11","jsonHitCount":5,"seriesKey":"Website Usage","jsonDate":"11\/17\/11","jsonHitCount":4,"seriesKey":"Website Usage","jsonDate":"11\/21\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"11\/22\/11","jsonHitCount":3,"seriesKey":"Website Usage","jsonDate":"11\/23\/11","jsonHitCount":11,"seriesKey":"Website Usage","jsonDate":"11\/24\/11","jsonHitCount":2,"seriesKey":"Website Usage","jsonDate":"11\/25\/11","jsonHitCount":1,"seriesKey":"Website Usage","jsonDate":"11\/28\/11","jsonHitCount":10,"seriesKey":"Website Usage","jsonDate":"11\/29\/11","jsonHitCount":3,"seriesKey":"Website Usage"]`

【问题讨论】:

【参考方案1】:

您正在尝试使用 d3.scale.linear() 来表示日期,但这是行不通的。您需要改用d3.time.scale() (docs):

// helper function
function getDate(d) 
    return new Date(d.jsonDate);


// get max and min dates - this assumes data is sorted
var minDate = getDate(data[0]),
    maxDate = getDate(data[data.length-1]);

var x = d3.time.scale().domain([minDate, maxDate]).range([0, w]);

那么你不需要处理时间间隔函数,你可以传递x一个日期:

.attr("d", d3.svg.line()
    .x(function(d)  return x(getDate(d)) )
    .y(function(d)  return y(d.jsonHitCount) )
);

在这里工作:http://jsfiddle.net/nrabinowitz/JTrnC/

【讨论】:

如何从中获得 UTC 时区间隔?我正在尝试按照文档中的说明添加 .utc,但我似乎无法让它工作。 .utc 应该可以工作 - 但我认为它在这里不会有太大作用;你的日期必须是正确的。据我了解,.utc 子类更多的是关于格式化。 在 D3 版本 4 中称为 scaleTime: github.com/d3/d3-scale/blob/master/README.md#time-scales

以上是关于处理 d3.js 轴上的日期的主要内容,如果未能解决你的问题,请参考以下文章

D3.js:使用图像(在数据中指定文件名)作为轴上的刻度值

如何进行 d3.js 轴的本地化?

使用 d3.js 制作分组条形图

如何从解析的 d3.js 日期创建新的日期格式

堆叠列不格式化 x 轴上的日期时间戳

d3.js 需要在 y 轴上重复值