d3时间序列,从数据中读取日期,按日期计数条目

d3 timeseries, reading date from data, counting entries by date

本文关键字:日期 读取 时间序列 数据 d3 取日期      更新时间:2023-09-26

我试图在d3中构建一条时间序列线,使用日期作为x轴,使用每个日期的条目数作为y轴。我很难将数据对象的日期部分通过日期格式化程序,然后是小数位数,然后移动到我的行中。

在Codepen中查看http://codepen.io/equivalentideas/pen/HaoIs/

提前感谢您的帮助!

            var data = [{"title":"1","date":"20140509"},{"title":"2)","date":"20140401"},{"title":"3","date":"20140415"},{"title":"4","date":"20140416"},{"title":"5","date":"20140416"},{"title":"6","date":"20140422"},{"title":"7","date":"20140422"},{"title":"8","date":"20140423"},{"title":"9","date":"20140423"},{"title":"10","date":"20140423"},{"title":"11","date":"20140502"},{"title":"12","date":"20140502"}
            var width = "100%",
                height = "8em";
            var parseDate = d3.time.format("%Y%m%d").parse;
            // X Scale
            var x = d3.time.scale()
                .range([0, width]);
            // Y Scale
            var y = d3.scale.linear()
                .range([height, 0]);
            // define the line
            var line = d3.svg.line()
                .x(function(d) {
                    return x(d.date);
                })
                .y(function(d) {
                    return y(+d);
                })

            data.forEach(function(d) {
                d.date = parseDate(d.date);
            });
            x.domain(d3.extent(data, function(d) { return d.date; }));
            y.domain(d3.extent(data, function(d) { return d; }));
            // build the svg canvas
            var svg = d3.select("body")
                        .append("svg")
                        .attr("width", width)
                        .attr("height", height);
            // build the line
            svg.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("d", line);

目前我得到一个js控制台错误

Error: Invalid value for <path> attribute d="MNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaNLNaN,NaN" 

您尚未使用parseDate。你错过了这个:

data.forEach(function(d) {
    d.date = parseDate(d.date);
});

看看这个例子。

一些明显可见的问题:

1( 您没有将svg附加到bodydiv的任何部分。你应该有一条这样的线:

d3.select("body").append("svg").attr("width", width).attr("height", height);

2( 我怀疑d3能否理解你对width的定义height。宽度和高度是图表大小的定义

3( 我认为不需要dateParse,因为d3会在内部为您做这件事。

最后,查看Niranjan提供的示例。

这里还有一些其他问题。首先,宽度/高度不是数字,因此yScale和xScale范围无效(这就是为什么在行路径中得到"NaN"的原因(。

这很糟糕:

var width = "100%",
height = "8em";

因为这些将没有有效的数值范围,如以下比例定义所要求的:

// X Scale
var x = d3.time.scale().range([0, width]);
// Y Scale
var y = d3.scale.linear().range([height, 0]);

在数值svg路径坐标中,"8em"到0意味着什么?所以,让它们变成数字:

var width = 500,
height = 100;

修复后,仍然会出现错误,因为y值的映射不起作用。您需要不同日期的计数直方图。您应该以这种方式生成数据,并将其输入到行生成器中。

var generateData = function(data){
    var newData = [];
    var dateMap = {};
    data.forEach(function(element){
        var newElement;
        if(dateMap[element.date]){
            newElement = dateMap[element.date];
        } else {
            newElement = { date: parseDate(element.date), count: 0 };
            dateMap[element.date] = newElement;
            newData.push(newElement);
        }
        newElement.count += 1;
    });
    newData.sort(function(a,b){
        return a.date.getTime() - b.date.getTime();
    });
    return newData;
};

一旦你解决了这两件事,它就会起作用。这里有一个jsFiddle:http://jsfiddle.net/reblace/j3LzY/