我的数据格式为
data={
"Month": "Jan",
"typeA": [
{
"A": 24000,
"B": 24000,
"C": 24000
}],
"typeB": [
{
"A": 20000,
"B": 14000,
"C": 10000
}],
"typeC": [
{
"A": 34000,
"B": 44000,
"C": 54000
}]
},
{
"Month": "Feb",
"typeA": [
{
"A": 84000,
"B": 64000,
"C": 14000
}],
"typeB": [
{
"A": 20000,
"B": 34000,
"C": 10000
}],
"typeC": [
{
"A": 30000,
"B": 40000,
"C": 50000
}]
}
]
我想计算每个类型的总和(即typeA,TypeB)的个别月份, 即我想要下面格式的数据,
Month: jan
typeA:72000
typeB:44000
typeC:13200
Month:feb
typeA:162000
typeB:64000
typeC:120000
我正在使用d3.nest()来实现这个目标,
这是我的代码,
var months= d3.nest()
.key(function (d) { return (d.Month) })
.key(function (d) { return (d.typeA) })
.key(function (d) { return (d.typeB) })
.key(function (d) { return (d.typeC) })
.rollup(function (leaves) {
return d3.sum(leaves, function (d) { return d3.sum(sum,d3.values(d.A,d.B,d.C,d.D)) });
})
.entries(data);
我无法在这里获得元素的总和。我总和为零。谁能告诉我我做错了什么?
答案 0 :(得分:1)
我对d3.nest
不太熟悉。但我认为您可以使用JavaScript Array map函数获得结果。试试这段代码。
var data=[{
"Month": "Jan",
"typeA": [
{
"A": 24000,
"B": 24000,
"C": 24000
}],
"typeB": [
{
"A": 20000,
"B": 14000,
"C": 10000
}],
"typeC": [
{
"A": 34000,
"B": 44000,
"C": 54000
}]
},
{
"Month": "Feb",
"typeA": [
{
"A": 84000,
"B": 64000,
"C": 14000
}],
"typeB": [
{
"A": 20000,
"B": 34000,
"C": 10000
}],
"typeC": [
{
"A": 30000,
"B": 40000,
"C": 50000
}]
}
];
var results = data.map(function(d){
return {
Month: d.Month ,
typeA: d3.sum(d3.values(d.typeA[0])),
typeB: d3.sum(d3.values(d.typeB[0])),
typeC: d3.sum(d3.values(d.typeC[0]))
}
});
alert(JSON.stringify(results));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
答案 1 :(得分:1)
你可以像这样嵌套......
data = [{
"Month": "Jan",
"typeA": [
{
"A": 24000,
"B": 24000,
"C": 24000
}],
"typeB": [
{
"A": 20000,
"B": 14000,
"C": 10000
}],
"typeC": [
{
"A": 34000,
"B": 44000,
"C": 54000
}]
},
{
"Month": "Feb",
"typeA": [
{
"A": 84000,
"B": 64000,
"C": 14000
}],
"typeB": [
{
"A": 20000,
"B": 34000,
"C": 10000
}],
"typeC": [
{
"A": 30000,
"B": 40000,
"C": 50000
}]
}],
months = d3.nest()
var months = d3.nest()
.key(function(d){return d.Month})
.rollup(function(leaves){
//leaves is an array so use d3.sum
return d3.sum(leaves, function(d) {
//d can be an object who's value can be an array
//use d3.sum
return d3.sum(d3.values(d), function(e){
//
return d3.sum(e, function(f) {
return d3.sum(d3.values(f))
});
})
} )
})
.entries(data);
d3.select("#output").text(JSON.stringify(months));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="output"></div>
答案 2 :(得分:1)
您只需要像这样更改代码:
添加];
的{{1}}
data
将您的代码更改为:
data = [
{
"Month": "Jan",
"typeA": [
{
"A": 24000,
"B": 24000,
"C": 24000
}
],
"typeB": [
{
"A": 20000,
"B": 14000,
"C": 10000
}
],
"typeC": [
{
"A": 34000,
"B": 44000,
"C": 54000
}
]
},
{
"Month": "Feb",
"typeA": [
{
"A": 84000,
"B": 64000,
"C": 14000
}
],
"typeB": [
{
"A": 20000,
"B": 34000,
"C": 10000
}
],
"typeC": [
{
"A": 30000,
"B": 40000,
"C": 50000
}
]
}
];
修改强>
您也可以使用此类var months = d3.nest()
.key(function(d) { return (d.Month) })
.rollup(function (v) {
return {
typeA: d3.sum(d3.values(v[0].typeA[0])),
typeB: d3.sum(d3.values(v[0].typeB[0])),
typeC: d3.sum(d3.values(v[0].typeC[0]))
} })
.map(data);
console.log(JSON.stringify(months));
函数,但请记住,返回的值是d3.sum()
'您在代码中遗漏的部分',以查看实际需要的结果解析数据。
string
答案 3 :(得分:1)
不幸的是,我的另一个答案是针对不同的问题,但我会留下它,以防它有用。
@Gabriel的答案非常酷,但是使用的是d3功能,但它不是通用的,而且类别是硬编码的,这并不理想。
这是一种在(大多数)普通JS中完成通用的方法。唯一的假设是每个数组元素的第一个成员是被分组的标题,而其他成员是要卷起的标题。无论如何,以及通用,这种方式很短。
我还提供了@Gabriel答案的一个版本,以表明它也很容易概括。
var data = [{
"Month": "Jan",
"typeA": [
{
"A": 24000,
"B": 24000,
"C": 24000
}],
"typeB": [
{
"A": 20000,
"B": 14000,
"C": 10000
}],
"typeC": [
{
"A": 34000,
"B": 44000,
"C": 54000
}]
},
{
"Month": "Feb",
"typeA": [
{
"A": 84000,
"B": 64000,
"C": 14000
}],
"typeB": [
{
"A": 20000,
"B": 34000,
"C": 10000
}],
"typeC": [
{
"A": 30000,
"B": 40000,
"C": 50000
}]
}],
//////////////////////////////////////////////////////////////////////////////////
//Method one: without rollup
// assume that the first member of each object in the array is a heading
// e.g. Month
//////////////////////////////////////////////////////////////////////////////////
headings = data.reduce(function(headings, d) {
var h = d3.keys(d)[0]; //get the heading
return (headings [d[h]] = d3.keys(d).filter(function(p, i){return i}) //filter out the heading
.reduce(function(s, p){ //sum each of the other members
//p is the category being summed
return (s[p] = d3.sum(d3.values(d[p][0])), s);
}, {}), headings);
}, {});
d3.select("#output").text(JSON.stringify(headings));
//////////////////////////////////////////////////////////////////////////////////
//Method two: @Gabriel solution generalised
//////////////////////////////////////////////////////////////////////////////////
var months = d3.nest()
.key(function(d) { return (d.Month) })
.rollup(function (v) {
return d3.keys(v[0]).filter(function(p, i){return i}) //filter out the heading
.reduce(function(s, p){ //sum each of the other members
//p is the category being summed
return (s[p] = d3.sum(d3.values(v[0][p][0])), s);
}, {});
})
.map(data);
d3.select("#output2").text(JSON.stringify(months));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="output"></div></br>
<div id="output2"></div>