首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据与数据分离

数据与数据分离
EN

Stack Overflow用户
提问于 2013-12-31 08:59:16
回答 1查看 264关注 0票数 5

我正在绘制一个Dimple/D3图表,该图表将丢失的天数数据绘制为0。

代码语言:javascript
复制
date                fruit   count
2013-12-08 12:12    apples  2
2013-12-08 12:12    oranges 5
2013-12-09 16:37    apples  1
                             <- oranges inserted on 12/09 as 0
2013-12-10 11:05    apples  6
2013-12-10 11:05    oranges 2
2013-12-10 20:21    oranges 1

我几乎得到了nrabinowitz的excellent answer to work

我的数据的时间戳格式是YYYY-MM-DD HH-MM,而散列+d3的时间间隔(以天为单位)导致每天午夜的0点,即使有当天晚些时候的数据。

我发现的一个几乎解决方案是 to discard the hours/minutes,因此所有数据似乎都是从午夜开始的:

代码语言:javascript
复制
...
var dateHash = data.reduce(function(agg, d) { 
 agg[d.date.setHours(0,0,0,0)] = true; 
 return agg; 
}, {});
...

当每天只有一个条目的时候,这就像预期的那样工作,但是在有多个条目的日子里,值被加在一起。所以在上面12/10的数据中:苹果:6,橘子: 3。

理想情况下(在我看来),我会将绘图数据从date散列中分离出来,而散列则会丢弃小时/分钟。这将将午夜日期散列与D3日间隔进行比较,在午夜时用缺失的数据填充0,然后用完整的小时/分钟绘制真实的点。

我已经尝试过data2 = data.slice(),然后是setHours,但是图仍然得到了午夜点:

代码语言:javascript
复制
...
// doesn't work, original data gets converted
var data2 = data.slice();
var dateHash = data2.reduce(function(agg, d) { 
 agg[d.date.setHours(0,0,0,0)] = true; 
 return agg; 
}, {});
...

给nrabinowitz的道具,下面是经过修改的代码:

代码语言:javascript
复制
// get the min/max dates
var extent = d3.extent(data, function(d) { return d.date; }),
  // hash the existing days for easy lookup
  dateHash = data.reduce(function(agg, d) {
      agg[d.date] = true;

// arrr this almost works except if multiple entries per day
//    agg[d.date.setHours(0,0,0,0)] = true; 

      return agg;
  }, {}),
  headers = ["date", "fruit", "count"];

// make even intervals
d3.time.days(extent[0], extent[1])
    // drop the existing ones
    .filter(function(date) {
        return !dateHash[date];
    })
    // fruit list grabbed from user input
    .forEach(function(date) {
fruitlist.forEach(function(fruits) {
        var emptyRow = { date: date };
        headers.forEach(function(header) {
            if(header === headers[0]) {
                emptyRow[header] = fruits;}
            else if(header === headers[1]) {
                emptyRow[header] = 0;};
    // and push them into the array
        data.push(emptyRow);
    });
// re-sort the data
data.sort(function(a, b) { return d3.ascending(a.date, b.date); });

(我不关心时分制中的零分,只关心日报。如果time.interval从天改为小时,我怀疑哈希和D3会处理得很好。)

如何将日期散列与数据分离?这就是我该做的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-03 11:52:37

我想不出一种顺利的方法来做到这一点,但我已经编写了一些自定义代码,这些代码可以与您的示例一起工作,并且希望能够与您的实际情况一起工作。

代码语言:javascript
复制
var svg = dimple.newSvg("#chartContainer", 600, 400),
    data = [
        { date : '2013-12-08 12:12', fruit : 'apples', count : 2 },
        { date : '2013-12-08 12:12', fruit : 'oranges', count : 5 },
        { date : '2013-12-09 16:37', fruit : 'apples', count : 1 },
        { date : '2013-12-10 11:05', fruit : 'apples', count : 6 },
        { date : '2013-12-10 11:05', fruit : 'oranges', count : 2 },
        { date : '2013-12-10 20:21', fruit : 'oranges', count : 1 }
    ],
    lastDate = {},
    filledData = [],
    dayLength = 86400000,
    formatter = d3.time.format("%Y-%m-%d %H:%M");

// The logic below requires the data to be ordered by date
data.sort(function(a, b) { 
    return formatter.parse(a.date) - formatter.parse(b.date); 
});

// Iterate the data to find and fill gaps
data.forEach(function (d) {

    // Work from midday (this could easily be changed to midnight)
    var noon = formatter.parse(d.date).setHours(12, 0, 0, 0);

    // If the series value is not in the dictionary add it
    if (lastDate[d.fruit] === undefined) {
        lastDate[d.fruit] = formatter.parse(data[0].date).setHours(12, 0, 0, 0);
    }

    // Calculate the days since the last occurance of the series value and fill
    // with a line for each missing day
    for (var i = 1; i <= (noon - lastDate[d.fruit]) / dayLength - 1; i++) {
        filledData.push({ 
            date : formatter(new Date(lastDate[d.fruit] + (i * dayLength))), 
            fruit : d.fruit, 
            count : 0 });
    }

    // update the dictionary of last dates
    lastDate[d.fruit] = noon;

    // push to a new data array
    filledData.push(d);

}, this);

// Configure a dimple line chart to display the data
var chart = new dimple.chart(svg, filledData),
    x = chart.addTimeAxis("x", "date", "%Y-%m-%d %H:%M", "%Y-%m-%d"),
    y = chart.addMeasureAxis("y", "count"),
    s = chart.addSeries("fruit", dimple.plot.line);
s.lineMarkers = true;
chart.draw();

你可以在这里看到它的作用:

http://jsfiddle.net/LsvLJ/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20854624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档