How to pass ES6 rest parameters dynamically in d3.group

Viewed 190

I am trying to group data in D3.js version 6.

d3.group(data, d=> d.Header, d=>Group);

This works fine but if I want to dynamically group data on multiple columns, How do I pass it?

function group(values, ...keys) {
  return nest(values, _identity_js__WEBPACK_IMPORTED_MODULE_0__.default, _identity_js__WEBPACK_IMPORTED_MODULE_0__.default, keys);
}

In d3.js library it expects rest parameters. Can someone help how to pass rest parameters in a function dynamically?

2 Answers

I could do it using .apply method to create arguments dynamically.

yColumns = ["column1", "column2"]
var arg = [oData.data];
yColumns.forEach(col => {
  var func = function(data){
      return data[col];
  }
  arg.push(func);
 });

 d3.group.apply(null,arg);

This approach is similar to your answer but it builds the array of functions within the call to d3.group

I've used groups in the example simply so it will log, but just change to group if you need the output as a nested Map:

const data = [
  {"a": "a1", "b": "b1", "c": "c1", "d": "d1", "v": 1},
  {"a": "a1", "b": "b1", "c": "c2", "d": "d1", "v": 11},
  {"a": "a1", "b": "b2", "c": "c3", "d": "d1", "v": 21},
  {"a": "a1", "b": "b2", "c": "c4", "d": "d1", "v": 31},
  {"a": "a2", "b": "b3", "c": "c5", "d": "d1", "v": 41},
  {"a": "a2", "b": "b3", "c": "c6", "d": "d1", "v": 51},
  {"a": "a2", "b": "b4", "c": "c7", "d": "d1", "v": 61},
  {"a": "a2", "b": "b4", "c": "c8", "d": "d1", "v": 71}
];

const groupMulti = (data, ...keys) => {
  return d3.groups( //<--- change to group if you need Map as output
    data,
    ...keys.map(k => (d => d[k]))
  )
}

const arr = groupMulti(data, "a", "b");

console.log(arr);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.3.0/d3.min.js"></script>

Related