score:1

Accepted answer

You can just use basic javascript .reduce() function to do the trick. This will roll up your array of object structure into a single object with the months as the property name and the sum of the values as the value. The advantage to doing it this way is that if you want to get, say, the total for the month of September, you can simply say combined.september, rather than having to iterate through an array, searching for the object with the key property equal to "september" and then extracting the value. However, if you need to keep your original structure, see the slightly modified version at the bottom of my answer.

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);

Edit -- if you need to keep your original {"key": "..", "values", ".."} structure

You can use .map() rather than .reduce() like so:

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 } ]

score:2

You have to update your d3.sum function like so:

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

So your whole code would be:

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);

Related Query

More Query from same tag