I'm trying to produce a box plot which will show the total number of networks single devices have connected to grouped by their vendor.
Data Format:
{
"SSID": "eduroam",
"identifier": "Client",
"latitude": 52.4505,
"longitude": -1.9361,
"mac": "dc:d9:16:##:##:##",
"packet": "PR-REQ",
"timestamp": "2018-07-10 12:25:26",
"vendor": "Huawei Technologies Co.Ltd"
}
Fiddle with data https://jsfiddle.net/v4a8g2bo/
I have managed to get a sum of the networks a single device has connected to using the following code. Data filtered before to only contain unique networks to a mac address, therefore using a counter works to count networks.
var mac = ndx.dimension(function (d) { return d["mac"]; });
var SSIDstoSingleMAC = mac.group().reduceSum(function (d) { return
+d.counter});
My problem lies when trying to then pass this grouped sum into a further group that will output an array for use in the box plot chart
var vendor = ndx.dimension(function (d) { return d["vendor"]; });
//Used to count number of networks per device
var mac = ndx.dimension(function (d) { return d["mac"]; });
var SSIDstoSingleMAC = mac.group().reduceSum(function (d) { return
+d.counter});
//This is where things fall down
var boxplotGroup = SSIDstoSingleMAC.group().reduce(
function (p, v) {
let dv = v.counter;
if (dv != null) p.push(dv);
return p;
},
function (p, v) {
let dv = v.counter;
if (dv != null) p.splice(p.indexOf(dv), 1);
return p;
},
function () {
return [];
}
);
var boxPlot = dc.boxPlot("#boxPlot");
boxPlot
.width(1200)
.height(600)
.dimension(vendor)
.group(boxplotGroup)
.tickFormat(d3.format('.1f'))
.elasticY(true)
.elasticX(true)
;
This is the goal: Ex. Apple [7,5,10,2] = four apple devices.. device one has connected to 7 networks... ect..
ATTEMPT AT HIDDEN GROUP
Gordon mentioned in the comments that two groups can't be passed recursively in crossfilter. I'm now trying to produce a hidden group that can accumulate the networks per mac address using the following code from the DC git however I can't get this to mesh up with the boxplot reducer.. Am I going in the right direction here?
https://github.com/dc-js/dc.js/wiki/FAQ#accumulate-values
var allDim = ndx.dimension(function (d) { return d; });
function accumulate_group(source_group) {
return {
all:function () {
var cumulate = 0;
return source_group.all().map(function(d) {
cumulate += d.counter;
return {key:d.mac, value:cumulate};
});
}
};
}
var boxPlotDim = accumulate_group(allDim);
var boxPlotGroup = boxPlotDim.group().reduce(
function(p,v) {
p.push(v.value());
return p;
},
function(p,v) {
p.splice(p.indexOf(v.value()), 1);
return p;
},
function() {
return [];
}
);
var boxPlot = dc.boxPlot("#boxPlot");
boxPlot
.width(1200)
.height(600)
.dimension(vendor)
.group(boxPlotGroup)
.tickFormat(d3.format('.1f'))
.elasticY(true)
.elasticX(true)
;
Thanks Adam