D3 Nesting And Object Traversal
i have a json as shared below and I am trying to nest the data prior to visualization. I wish to plot under gov and non-gov how every vendor is distributed for high and low project
Solution 1:
I don't know D3, but using vanilla JS you can transform the data as follows:
var input = [ { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "high" }, { "vendor": "V1", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V2", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V7", "ptype": "Gov", "critical": "low" }, { "vendor": "V8", "ptype": "Gov", "critical": "high" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "low" } ];
var working = input.reduce(function(p, c) {
var v = p[c.vendor];
if (!v) v = p[c.vendor] = {Gov: {high: 0, low: 0}, "Non-Gov": {high: 0, low: 0}};
v[c.ptype][c.critical]++;
return p;
}, {});
var output = Object.keys(working).map(function(v) {
var o = {};
o[v] = working[v];
return o;
});
console.log(output);
Or if you can use ES6 syntax you can make the .map()
part a lot shorter:
var input = [ { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "high" }, { "vendor": "V1", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V2", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V7", "ptype": "Gov", "critical": "low" }, { "vendor": "V8", "ptype": "Gov", "critical": "high" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "low" } ];
var working = input.reduce((p, c) => {
var v = p[c.vendor];
if (!v) v = p[c.vendor] = {Gov: {high: 0, low: 0}, "Non-Gov": {high: 0, low: 0}};
v[c.ptype][c.critical]++;
return p;
}, {});
var output = Object.keys(working).map(v => ({ [v]: working[v] }));
console.log(output);
EDIT: It occurred to me that maybe you don't want to hard-code the possible ptype
and critical
values, so...the following (ugly, unoptimsed) version grabs the values as it goes:
var input = [ { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "high" }, { "vendor": "V1", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V2", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V7", "ptype": "Gov", "critical": "low" }, { "vendor": "V8", "ptype": "Gov", "critical": "high" }, { "vendor": "V9", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V1", "ptype": "Gov", "critical": "high" }, { "vendor": "V2", "ptype": "Gov", "critical": "low" }, { "vendor": "V3", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V4", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V5", "ptype": "Non-Gov", "critical": "high" }, { "vendor": "V6", "ptype": "Gov", "critical": "high" }, { "vendor": "V7", "ptype": "Gov", "critical": "high" }, { "vendor": "V8", "ptype": "Non-Gov", "critical": "low" }, { "vendor": "V9", "ptype": "Gov", "critical": "high" }, { "vendor": "V10", "ptype": "Gov", "critical": "low" } ];
var working = input.reduce((p, c) => {
var v = p.vendors[c.vendor];
if (!v) v = p.vendors[c.vendor] = {};
if (!v[c.ptype]) v[c.ptype] = {};
if (!v[c.ptype][c.critical]) v[c.ptype][c.critical] = 1;
else v[c.ptype][c.critical]++;
p.ptypes[c.ptype] = true;
p.criticals[c.critical] = true;
return p;
}, {vendors:{}, ptypes:{}, criticals:{}});
var output = Object.keys(working.vendors).map(v => {
var c = working.vendors[v];
Object.keys(working.ptypes).forEach(p => {
if (!c[p]) c[p] = {};
Object.keys(working.criticals).forEach(q => c[p][q] || (c[p][q] = 0));
});
return { [v]: c };
});
console.log(output);
Solution 2:
i could do it this way..
var nested_data = d3.nest()
.key(function(d) { return d.vendor; }).sortKeys(d3.ascending)
.key(function(d) { return d.ptype; }).sortKeys(function(d) { return d;})
.key(function(d) { return d.critical; }).sortKeys(function(d) { return d;})
.rollup(function(leaves) { return leaves.length; })
.entries(j);
Thanks!
Post a Comment for "D3 Nesting And Object Traversal"