为什么这段代码可以计算列表中的一个项目而不是其他项目?

Why does this code work for counting one item in a list but not the others?

我正在尝试计算 .csv 文件中 "Manager" 的 "MIT" 和 "Instore" 的数量。我的代码可用于查找所有 "Manager",但不适用于其他两个。

我曾尝试将函数拆分为 3 个独立的函数,因为我认为问题可能出在一个函数中使用了多个 dc.numberDisplay,但这没有用。我已经尝试过这个功能,所以只有一个,如果它正在寻找它可以工作的经理,那么麻省理工学院就没有,而 Instores 则没有。我已经尝试更改代码的顺序,但仍然没有。我已将 console.log(p.mit_count) 放入 add_item、remove_item 的每一行并进行初始化。我已经将 console.log(d.value.mit_count) 放在 valueAccessor 中。

Scott,Instore,3,BMC,96
Mark,Instore,4,Intro,94
Wendy,Instore,3,Intro,76
Lucas,Instore,2,Intro,96
    .defer(d3.csv, "data/Results.csv")
    .await(makeGraphs)

//function for making and rendering graphs
function makeGraphs(error, staffData) {
    var ndx = crossfilter(staffData);
    show_number_of_staff(ndx);
    dc.renderAll();
}

function show_number_of_staff(ndx) {
    var dim = ndx.dimension(dc.pluck('Rank'));

    function add_item(p, v) {
        if (v.Rank == "Manager") {
            p.manager_count++;
        }
        else if (v.Rank == "MIT") {
            p.mit_count++;
        }
        else if (v.Rank == "Instore") {
            p.instore_count++;
        }
        return p;
    }

    function remove_item(p, v) {
        if (v.Rank == "Manager") {
            p.manager_count--;
        }
        else if (v.Rank == "MIT") {
            p.mit_count--;
        }
        else if (v.Rank == "Instore") {
            p.instore_count--;
        }
        return p;
    }

    function initialise(p, v) {
        return { manager_count: 0, mit_count: 0, instore_count: 0 };

    }

    var staffCounter = dim.group().reduce(add_item, remove_item, initialise);;

    dc.numberDisplay("#managerCount")
        .formatNumber(d3.format(".0"))
        .valueAccessor(function(d) {
            return d.value.manager_count;
        })
        .group(staffCounter);

    dc.numberDisplay("#mitCount")
        .formatNumber(d3.format(".0"))
        .valueAccessor(function(d) {
            return d.value.mit_count;
        })
        .group(staffCounter);

    dc.numberDisplay("#instoreCount")
        .formatNumber(d3.format(".0"))
        .valueAccessor(function(d) {
            return d.value.instore_count;
        })
        .group(staffCounter);
}

console.log(p.mit_count) 显示它计数为 13(正如我所期望的那样),但随后在 valueAccessor console.log(d.value.mit_count) 中显示 0。我不明白为什么这适用于 "Manager" 但没有别的。我几乎为这花了我一个多星期的时间而感到尴尬。就是这么简单!

我认为如果您登录 staffCounter.all(),您会发现它在 3 个单独的容器中计算经理、MIT 和 Instores。这是因为您的维度按 Rank 排序,然后您的组再次按 Rank 分箱,因此您最终得到每个排名一个分箱。

通常你会想传递一个 groupAll object, with one bin, to the numberDisplay. However, it is permissive and will also accept ordinary groups with multiple bins (source)。它将对垃圾箱进行排序并取走最后一个。

为什么?我不确定。我认为在几乎所有情况下,您都希望减少到一个 bin,但显然有人有一个用例,他们想要显示许多 bin 中的最大值。

我很惊讶地发现没有记录该行为,所以我更新了 the numberDisplay documentation

使用 groupAll 您的代码将类似于:

var staffCounter = ndx.groupAll().reduce(add_item, remove_item, initialise);
dc.numberDisplay("#managerCount")
    .formatNumber(d3.format(".0"))
    .valueAccessor(function(d) {
        return d.manager_count; // no .value here
    })
    .group(staffCounter);

请注意,此处未使用交叉过滤器维度。