dc.js 气泡图 - 多维分组问题,无法让自定义缩减器工作
dc.js bubble chart - multidimension grouping issue and unable to get custom reducer to work
我目前正尝试在 dc.js 中为我的硕士论文制作一个仪表板,今天我遇到了一个真正的障碍,如果有人可以提供帮助,我将不胜感激。我是 Javascript 和 dc 的新手,所以我会尽力解释......
我的数据格式(具有可见 SSID 的探测请求):
{"vendor":"Huawei Technologies Co.Ltd","SSID":"eduroam","timestamp":"2018-07-10 12:25:26","longitude":-1.9361,"mac":"dc:d9:16:##:##:##","packet":"PR-REQ","latitude":52.4505,"identifier":"Client"}
我的数据格式(带广播/受保护 SSID 的探测请求):
{"vendor":"Nokia","SSID":"Broadcast","timestamp":"2018-07-10 12:25:26","longitude":-1.9361,"mac":"dc:d9:16:##:##:##","packet":"PR-REQ","latitude":52.4505,"identifier":"Client"}
我正在尝试生成一个气泡图,它将供应商显示为气泡(大小由为该供应商收集的数据包量表示)然后针对 X 轴不受保护(任何 SSID!= 广播)和 Y 绘制气泡轴保护(数据中 "Broadcast" 的数据包)
我的意思的草图
到目前为止我已经取得了什么
我已经设法让条形图/row/pie 图表正常工作,因为它们只需要我使用一个维度并 运行 它们通过一组。但我认为我从根本上误解了如何将多个维度传递给一个组。
对于顶部的每个,如果数据中存在广播,则将新值 0 / 1 添加到三倍。
然后我使用自定义减速器计算与 unpro 和 pro 相关的 0 / 1,这将用于绘制 X / Y
我已经尝试重新设计纳斯达克示例,但毫无进展
代码:
queue()
.defer(d3.json, "/uniquedevices")
.await(plotVendor);
function plotVendor(error, packetsJson) {
var packets = packetsJson;
packets.forEach(function (d) {
if(d["SSID"] == "Broadcast") {
d.unpro = 0;
d.pro = 1;
} else {
d.unpro = 1;
d.pro = 0;
}
});
var ndx = crossfilter(packets);
var vendorDimension = ndx.dimension(function(d) {
return [ d.vendor, d.unpro, d.pro ];
});
var vendorGroup = vendorDimension.group().reduce(
function (p, v) {
++p.count;
p.numun += v.unpro;
p.numpr += v.pro;
return p;
},
function (p, v) {
--p.count;
p.numun -= v.unpro;
p.numpr -= v.pro;
return p;
},
function () {
return {
numun: 0,
numpr: 0
};
}
);
var vendorBubble = dc.bubbleChart("#vendorBubble");
vendorBubble
.width(990)
.height(250)
.transitionDuration(1500)
.margins({top: 10, right: 50, bottom: 30, left: 40})
.dimension(vendorDimension)
.group(vendorGroup)
.yAxisPadding(100)
.xAxisPadding(500)
.keyAccessor(function (p) {
return p.key[1];
})
.valueAccessor(function (p) {
return p.key[2];
})
.radiusValueAccessor(function (d) { return Object.keys(d).length;
})
.maxBubbleRelativeSize(0.3)
.x(d3.scale.linear().domain([0, 10]))
.y(d3.scale.linear().domain([0, 10]))
.r(d3.scale.linear().domain([0, 20]))
dc.renderAll();
};
我认为您正在正确聚合数据,缺失的部分是
您的访问器应该查看 value
的内部(这是 crossfilter 聚合的地方)
.keyAccessor(function (p) {
return p.value.numpr;
})
.valueAccessor(function (p) {
return p.value.numun;
})
.radiusValueAccessor(function (d) {
return d.value.count;
})
您的密钥应该只是供应商 - crossfilter 维度不是几何维度,它们是您过滤和分类的依据:
var vendorDimension = ndx.dimension(function(d) {
return d.vendor;
});
您可能需要初始化 count
因为 ++undefined
是 NaN
:
function () { // reduce-init
return {
count: 0,
numun: 0,
numpr: 0
};
}
您的 fiddle 的分支,添加了所有依赖项,禁用了包装功能,并且 elasticX/elasticY(可能不是您想要的,但更容易调试):
我目前正尝试在 dc.js 中为我的硕士论文制作一个仪表板,今天我遇到了一个真正的障碍,如果有人可以提供帮助,我将不胜感激。我是 Javascript 和 dc 的新手,所以我会尽力解释......
我的数据格式(具有可见 SSID 的探测请求):
{"vendor":"Huawei Technologies Co.Ltd","SSID":"eduroam","timestamp":"2018-07-10 12:25:26","longitude":-1.9361,"mac":"dc:d9:16:##:##:##","packet":"PR-REQ","latitude":52.4505,"identifier":"Client"}
我的数据格式(带广播/受保护 SSID 的探测请求):
{"vendor":"Nokia","SSID":"Broadcast","timestamp":"2018-07-10 12:25:26","longitude":-1.9361,"mac":"dc:d9:16:##:##:##","packet":"PR-REQ","latitude":52.4505,"identifier":"Client"}
我正在尝试生成一个气泡图,它将供应商显示为气泡(大小由为该供应商收集的数据包量表示)然后针对 X 轴不受保护(任何 SSID!= 广播)和 Y 绘制气泡轴保护(数据中 "Broadcast" 的数据包)
我的意思的草图
到目前为止我已经取得了什么
我已经设法让条形图/row/pie 图表正常工作,因为它们只需要我使用一个维度并 运行 它们通过一组。但我认为我从根本上误解了如何将多个维度传递给一个组。
对于顶部的每个,如果数据中存在广播,则将新值 0 / 1 添加到三倍。
然后我使用自定义减速器计算与 unpro 和 pro 相关的 0 / 1,这将用于绘制 X / Y
我已经尝试重新设计纳斯达克示例,但毫无进展
代码:
queue()
.defer(d3.json, "/uniquedevices")
.await(plotVendor);
function plotVendor(error, packetsJson) {
var packets = packetsJson;
packets.forEach(function (d) {
if(d["SSID"] == "Broadcast") {
d.unpro = 0;
d.pro = 1;
} else {
d.unpro = 1;
d.pro = 0;
}
});
var ndx = crossfilter(packets);
var vendorDimension = ndx.dimension(function(d) {
return [ d.vendor, d.unpro, d.pro ];
});
var vendorGroup = vendorDimension.group().reduce(
function (p, v) {
++p.count;
p.numun += v.unpro;
p.numpr += v.pro;
return p;
},
function (p, v) {
--p.count;
p.numun -= v.unpro;
p.numpr -= v.pro;
return p;
},
function () {
return {
numun: 0,
numpr: 0
};
}
);
var vendorBubble = dc.bubbleChart("#vendorBubble");
vendorBubble
.width(990)
.height(250)
.transitionDuration(1500)
.margins({top: 10, right: 50, bottom: 30, left: 40})
.dimension(vendorDimension)
.group(vendorGroup)
.yAxisPadding(100)
.xAxisPadding(500)
.keyAccessor(function (p) {
return p.key[1];
})
.valueAccessor(function (p) {
return p.key[2];
})
.radiusValueAccessor(function (d) { return Object.keys(d).length;
})
.maxBubbleRelativeSize(0.3)
.x(d3.scale.linear().domain([0, 10]))
.y(d3.scale.linear().domain([0, 10]))
.r(d3.scale.linear().domain([0, 20]))
dc.renderAll();
};
我认为您正在正确聚合数据,缺失的部分是
您的访问器应该查看
value
的内部(这是 crossfilter 聚合的地方).keyAccessor(function (p) { return p.value.numpr; }) .valueAccessor(function (p) { return p.value.numun; }) .radiusValueAccessor(function (d) { return d.value.count; })
您的密钥应该只是供应商 - crossfilter 维度不是几何维度,它们是您过滤和分类的依据:
var vendorDimension = ndx.dimension(function(d) { return d.vendor; });
您可能需要初始化
count
因为++undefined
是NaN
:function () { // reduce-init return { count: 0, numun: 0, numpr: 0 }; }