有没有办法只计算 "Race" 中 "Person" 的每个实例一次,然后相应地显示一个饼图?

Is there a way to count each instance of "Person" in "Race" only once, then display a pie chart accordingly?

我试图从 JSON 文件中显示 LOTR 中每个种族的字符数,问题是数据计算了字符的每个实例,因为它们在JSON 因此使我的数据膨胀得比预期结果大得多。例如:

{
    "Film": "The Fellowship Of The Ring",
    "Chapter": "05: A Long Expected Party",
    "Character": "Bilbo",
    "Race": "Hobbit",
    "Words": 326
},

我尝试使用内置的 dc 工具来相应地提取和显示这些数据,但是如上所述,这会使我的数据膨胀。我很确定我需要使用 for 循环遍历数据集,但到目前为止我能想到的只是基本语句:

function show_race_data(ndx) {
    var dim = ndx.dimension(dc.pluck('Race'));
    var group = dim.group();

    dc.pieChart('#race-graph')
        .height(550)
        .width(300)
        .radius(90)
        .transitionDuration(1500)
        .dimension(race_dim)
        .group(total_chars_per_race);
}

我想我需要像这样对字符进行分组:

var group = dim.group(character)

然后循环:

let character = function(d.character) {
    if (character <= 0;)
       character ++;
    } else if (character >= 1;)
       character --;
}

我希望我的输出能够在没有 inflation 的情况下正确显示我想要的数据。

我想我会像这样处理它(脱离我的头脑并且未经测试 下面的演示)。

我们将计算每个字符的出现次数,将它们添加到对象中并从对象中删除它们(如果您喜欢 ES6,可以是 Map)。

var dim = ndx.dimension(dc.pluck('Race'));
var raceCharGroup = dim.group().reduce(
    function(p, v) { // add
        p[v.Character] = (p[v.Character] || 0) + 1;
        return p;
    },
    function(p, v) { // remove
        if(--p[v.Character] === 0)
            delete p[v.Character];
        return p;
    },
    function() { // init
        return {};
    });

当我们看到一个新字符时,我们从 0 开始新条目。当我们减少计数并变为 0 时,我们删除该条目。

很好,但是现在我们有一个对象而不是一些字符。但是我们可以改变饼图解释这些对象的方式,只计算键的数量:

pie.valueAccessor(function(kv) {
    return Object.keys(kv.value).length;
})

我相信还有其他方法可以做到这一点,但这很好,因为它使用了惯用的 group.reduce.

Here's a demo fiddle.