d3js汇总嵌套的JSON数组并总计一个总值

时间:2017-02-01 16:52:42

标签: javascript arrays json d3.js

我有这个JSON

[{
    "month": "september",
    "detail": [{
        "date": "01-09",
        "value": 5
    }, {
        "date": "02-09",
        "value": 5
    }, {
        "date": "03-09",
        "value": 5
    }, {
        "date": "04-09",
        "value": 5
    }, {
        "date": "05-09",
        "value": 5
    }, {
        "date": "06-09",
        "value": 5
    }, {
        "date": "07-09",
        "value": 0
    }]
},

{
    "month": "october",
    "detail": [{
        "date": "01-10",
        "value": 10
    }, {
        "date": "02-10",
        "value": 5
    }, {
        "date": "03-10",
        "value": 5
    }, {
        "date": "04-10",
        "value": 5
    }, {
        "date": "05-10",
        "value": 5
    }, {
        "date": "07-10",
        "value": 10
    }]
}

我想使用d3nest在每个特定月份的对象“detail”中汇总所有“值”。如果计算每个特定月份的所有值,将导致:9月 - 值:30&十月值:40。

我已经尝试过嵌套它,但我无法正确总结每个月的值。看我的代码。

d3.json('runningdata.json', function (error, data) {
console.log(data);

var Total = d3.nest()
.key(function(d) { return d.month; })
.rollup(function(value) { return d3.sum(value, function(v) { return v.detail.value; }); })

.entries(data);
console.log(JSON.stringify(Total));
});

以上所有这些都会导致:

[{"key":"september","values":0},{"key":"october","values":0}]

您可以注意到“密钥”正常工作,它们具有月份值。但是“值”字段导致0.我想要达到的目标是:

[{"key":"september","values":30},{"key":"october","values":40}]

但是当我尝试这个时:

.rollup(function(value) { return d3.sum(value, function(v) { return v.detail[0].value; }); })

而不是:

.rollup(function(value) { return d3.sum(value, function(v) { return v.detail.value; }); })

它显示了数组中第一个对象的值。

[{"key":"september","values":5},{"key":"october","values":10}]

我做错了什么?我一直在阅读有关d3嵌套的内容。 欢迎任何帮助。

注意: 我试图实现这一点,以制作一个图表,显示每个月的总数,当您点击特定月份时,它将以天为单位查看其月份的详细信息。

2 个答案:

答案 0 :(得分:2)

你必须像这样更新你的d3.sum函数:

d3.sum(value[0].detail, function(v) {
   return v.value;
});

所以你的整个代码将是:

var Total = d3.nest()
.key(function(d) {
    return d.month;
})
.rollup(function(value) {
    return d3.sum(value[0].detail, function(v) {
        return v.value;
    });
})
.entries(data);

答案 1 :(得分:1)

您可以使用基本的javascript .reduce()函数来完成这项工作。这会将对象结构数组汇总到一个对象中,其中月份作为属性名称,值的总和作为值。这样做的好处是,如果你想获得9月份的总数,你可以简单地说combined.september,而不是必须遍历一个数组,搜索对象与key财产等于" 9月"然后提取值。但是,如果您需要保留原始结构,请参阅我的答案底部的略微修改的版本。



var data = [{
    "month": "september",
    "detail": [{
        "date": "01-09",
        "value": 5
    }, {
        "date": "02-09",
        "value": 5
    }, {
        "date": "03-09",
        "value": 5
    }, {
        "date": "04-09",
        "value": 5
    }, {
        "date": "05-09",
        "value": 5
    }, {
        "date": "06-09",
        "value": 5
    }, {
        "date": "07-09",
        "value": 0
    }]
},

{
    "month": "october",
    "detail": [{
        "date": "01-10",
        "value": 10
    }, {
        "date": "02-10",
        "value": 5
    }, {
        "date": "03-10",
        "value": 5
    }, {
        "date": "04-10",
        "value": 5
    }, {
        "date": "05-10",
        "value": 5
    }, {
        "date": "07-10",
        "value": 10
    }]
}];

var combined = data.reduce(function (total, current){
  total[current.month] = current.detail.reduce(function(tot, curr) {
    return tot + curr.value;
  }, 0);
  return total;
}, {});

console.log(combined);




编辑 - 如果您需要保留原始{"键":" ...","值"," ..& #34;}结构

您可以使用.map()而不是.reduce()

var combined = data.map(function (elem){
  var total = elem.detail.reduce(function(total, current) {
    return total + current.value;
  }, 0);
  return {key: elem.month, values: total};
});

console.log(combined); 

// output:
// [ { key: 'september', value: 30 },
//   { key: 'october', value: 40 } ]