D3.js 在骨料上显示标签(交叉过滤器和还原)

D3.js 在骨料上显示标签(交叉过滤器和还原),d3.js,dc.js,crossfilter,D3.js,Dc.js,Crossfilter,我有一些(简化的)数据如下: { "PO": 1353901, "Qty": 1, "Levels": 3 }, { "PO": 1353901, "Qty": 2, "Levels": 3 }, { "PO": 50048309,"Qty": 1, "Levels": 1 }, { "PO": 50048309,"Qty": 4, "Levels": 1 }, { "PO": 50048309,"Qty": 1, "Levels": 1 } 您可以在这里看到两个采购订单的数据,每一

我有一些(简化的)数据如下:

 { "PO": 1353901, "Qty": 1, "Levels": 3 },
 { "PO": 1353901, "Qty": 2, "Levels": 3 },
 { "PO": 50048309,"Qty": 1, "Levels": 1 },
 { "PO": 50048309,"Qty": 4, "Levels": 1 },
 { "PO": 50048309,"Qty": 1, "Levels": 1 }
您可以在这里看到两个采购订单的数据,每一行代表一个独特的产品以及使用了多少产品。您还可以看到这些产品分布在多个级别

有助于理解成本的一个维度是材料密度。也就是说,每个级别使用了多少项。在
1353901
的情况下,在三个级别上使用了三个项目(数量汇总,级别不汇总),导致每个级别使用一个项目

对于
50048309
,一个层面上使用了六个项目,显示出更高的植入密度。这告诉我很多工作都集中在一个地方

对平面数据进行过滤很容易,并且不难将其分组到范围中。以
级别
为例:

var levels = ndx.dimension(function (d) {
    var level = d.Levels;
    if (level == 1) {
        return 'One';
    } else if (level == 2) {
        return 'Two';
    } else if (level == 3) {
        return 'Three';
    } else {
        return 'Four +';
    }
});
我可以在一个维度内轻松创建组和范围

对于聚合,我似乎不能做完全相同的事情。我想按每级使用的材料数量查看(过滤)
PO
。这不是一个很难获得每个订单的数字,但似乎很难在小组中查看。示例如下:

因为我从一个基于聚合的维度开始,在
采购订单
中,我将为每个采购订单返回一行


如何使每个
QtyPerLevel
范围返回一行?

我认为您需要预先计算。也就是说,使用采购订单中的总数量值向每个采购订单行添加一个新属性。在进行此操作时,您还可以计算
QtyPerLevel

 { "PO": 1353901, "Qty": 1, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
 { "PO": 1353901, "Qty": 2, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
 { "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
 { "PO": 50048309,"Qty": 4, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
 { "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 }
然后在
QtyPerLevel
上创建一个交叉筛选维度,并对其进行筛选或分组:

   var ndx = crossfilter([
         { "PO": 1353901, "Qty": 1, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
         { "PO": 1353901, "Qty": 2, "Levels": 3, "TotalQty": 3, "QtyPerLevel": 1 },
         { "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
         { "PO": 50048309,"Qty": 4, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 },
         { "PO": 50048309,"Qty": 1, "Levels": 1, "TotalQty": 6, "QtyPerLevel": 6 }]);
    var qtyPerLevelDim = ndx.dimension(function(d) { return d.QtyPerLevel; });
    var qtyPerLevelGrp = qtyPerLevelDim.group();

有道理。有可能存在某种疯狂的mapReduce函数,但我一直在绞尽脑汁寻找它。不能有完全平坦的数据,但进行一些预聚合可能是最实际的解决方案。我只需创建一个Map(或d3.Map),其中键为POs,值为qty,然后遍历所有数据并聚合Map上的PO数量。然后再次循环并使用从地图上查找的聚合数量更新所有记录。如果您使用的是JavaScript,那么就是这样。在后端可能有更好的选择,特别是如果您使用的是数据库,在这种情况下,我建议使用自加入。