清除较低级别的D3嵌套数据

时间:2018-11-08 17:17:08

标签: d3.js

我在处理D3嵌套数据时遇到麻烦。当前,我的代码通过两个变量leadercompetent来嵌套数据。然后,代码汇总数据以获取每个符合领导能力的调查类别的计数。

var summary = d3.nest()
    .key(function(d) {return d.leader})
    .key(function(d) {return d.competent})
        .sortKeys(function(a, b) {return scaleValues.indexOf(a) - scaleValues.indexOf(b)})
    .rollup(function(l) {return l.length})
    .entries(data)

输出看起来像这样:

​0: {…}
    ​​key: "John"
    ​​values: (2) […]
    ​​​    0: Object { key: "Agree", value: 3 }
    ​​​    1: Object { key: "Strongly Agree", value: 6 }
    ​​​length: 2
​1: {…}
    key: "Emily"
​​    values: (2) […]
​​​        0: Object { key: "Agree", value: 4 }
​​​        1: Object { key: "Strongly Agree", value: 6 }
​​​    length: 2
length: 2

然后我清理数据,以确保将缺失的合格调查类别添加到计数0中。

makeAllKeys = function(d) {
    allKeys = scaleValues
        return allKeys
}

summary = summary.map(function(d) {
    return {
        key: d.key,
        values: makeAllKeys(+d.key).map(function(k) {
            value = d.values.filter(function(v) {return v.key == k})[0]
            return value || ({key: k, values:0})
        })
    }
})

现在输出看起来像这样:

0: {…}
​​    key: "John"
​​​​    values: (5) […]
​​​​​    ​​    0: Object { key: "Strongly Disagree", values: 0 }
​​​​​    ​​    1: Object { key: "Disagree", values: 0 }
​​​​​    ​​    2: Object { key: "Neutral", values: 0 }
​​​​​    ​​    3: Object { key: "Agree", value: 3 }
​​​​​    ​​    4: Object { key: "Strongly Agree", value: 6 }
​​​​​    length: 5
1: {…}
​​​​    key: "Emily"
​​​​    values: (5) […]
​​​​​    ​​    0: Object { key: "Strongly Disagree", values: 0 }
​​​​​    ​​    1: Object { key: "Disagree", values: 0 }
​​​​​    ​​    2: Object { key: "Neutral", values: 0 }
​​​​​    ​​    3: Object { key: "Agree", value: 4 }
​​​​​    ​​    4: Object { key: "Strongly Agree", value: 6 }
​​​​​    length: 5
length: 2

现在,我想使用company作为键将另一层添加到嵌套中。

var summary = d3.nest()
    .key(function(d) {return d.leader})
    .key(function(d) {return d.company})
    .key(function(d) {return d.competent})
        .sortKeys(function(a, b) {return scaleValues.indexOf(a) - scaleValues.indexOf(b)})
    .rollup(function(l) {return l.length})
    .entries(data)

这是添加了company键的输出的样子:

0: {…}
​​​​    key: "John"
​​    ​​    ​​values: (2) […]
​​​​​    ​​    ​​    0: {…}
​​    ​​    ​​    ​​    ​​​​key: "A"
​​    ​​    ​​    ​​    ​​​​values: (2) […]
​​​​​​​    ​​    ​​    ​​    ​​    0: Object { key: "Agree", value: 2 }
​​    ​​    ​​    ​​    ​​    ​​​​​1: Object { key: "Strongly Agree", value: 3 }
​​​​​​​    ​​    ​​    ​​    length: 2
​​​    ​​    ​​    ​​​1: {…}
​​​​​​    ​​    ​​    ​​    key: "B"
​​    ​​    ​​    ​​    ​​​​values: (2) […]
​​    ​​    ​​    ​​    ​​    ​​​​​0: Object { key: "Agree", value: 1 }
​​​​​​​    ​​    ​​    ​​    ​​    1: Object { key: "Strongly Agree", value: 3 }
​​​​​​​    ​​    ​​    ​​    length: 2
​​​​​    ​​    length: 2
​1: Object { key: "Emily", values: (2) […] }
​length: 2

但是,由于它们在嵌套结构中处于另一个较低的级别,因此我正在努力修改可修复缺失的调查类别的代码。

下面提供了完整的测试代码和示例数据。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>D3 Page Template</title>
        <script src="https://d3js.org/d3.v4.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>

    <body>
        <script type = "text/javascript">

            // Define scales
            var scaleValues = ["Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]
            var scaleValues2 = ["Very Unlikely", "Unlikely", "Neutral", "Likely", "Very Likely"]

            // Import the data
            d3.csv("stackoverflow.csv", function(error, data) {
                if (error) throw error

                var data = data
                    .map(function(d) {return {leader: d.leader, company: d.company, competent: d.competent, personable: d.personable, helpful: d.helpful, recommend: d.recommend}})
                    .filter(function(d) {return d.competent != "NA"})
                    .filter(function(d) {return d.personable != "NA"})
                    .filter(function(d) {return d.helpful != "NA"})
                    .filter(function(d) {return d.recommend != "NA"})
                    .filter(function(d) {return d.leader != "NA"})
                    .filter(function(d) {return d.leader != "I don't remember"})
                data.forEach(function(d) {
                    d.competent = d.competent.replace(/[^a-z0-9+]+/gi, " ")
                    d.personable = d.personable.replace(/[^a-z0-9+]+/gi, " ")
                    d.helpful = d.helpful.replace(/[^a-z0-9+]+/gi, " ")
                    d.recommend = d.recommend.replace(/[^a-z0-9+]+/gi, " ")
                })
                console.log(data)

                makeAllKeys = function(d) {
                    allKeys = scaleValues
                    return allKeys
                }

                var summary = d3.nest()
                    .key(function(d) {return d.leader})
                    // .key(function(d) {return d.company})
                    .key(function(d) {return d.competent})
                        .sortKeys(function(a, b) {return scaleValues.indexOf(a) - scaleValues.indexOf(b)})
                    .rollup(function(l) {return l.length})
                    .entries(data)

                summary = summary.map(function(d) {
                    return {
                        key: d.key,
                        values: makeAllKeys(+d.key).map(function(k) {
                            value = d.values.filter(function(v) {return v.key == k})[0]
                            return value || ({key: k, values:0})
                        })
                    }
                })
                console.log(summary)
            })
        </script>
    </body>
</html>

stackoverflow.csv

company,competent,personable,helpful,recommend,leader
A,Agree,Agree,Agree,Likely,John
A,Strongly Agree,Strongly Agree,Agree,Very Unlikely,John
A,Agree,Strongly Agree,Strongly Agree,Very Likely,John
A,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,John
A,Strongly Agree,Strongly Agree,Neutral,Very Likely,John
A,Agree,Strongly Agree,Strongly Agree,Very Likely,Emily
A,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,Emily
A,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,Emily
A,Agree,Strongly Agree,Strongly Agree,Likely,Emily
A,Agree,Strongly Agree,Agree,Neutral,Emily
B,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,John
B,Agree,Agree,Agree,Likely,John
B,Strongly Agree,Strongly Agree,Agree,Likely,John
B,Strongly Agree,Strongly Agree,Strongly Agree,Likely,John
B,Agree,Strongly Agree,Agree,Likely,Emily
B,Strongly Agree,Strongly Agree,Strongly Agree,Likely,Emily
B,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,Emily
B,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,Emily
B,Strongly Agree,Strongly Agree,Strongly Agree,Very Likely,Emily

1 个答案:

答案 0 :(得分:1)

微小变化:

summary.map...中,d.values现在将是一个数组(由于company中使用了nest键),因此您必须映射此{ {1}}在内部就像您上一次尝试一样。

这是更有意义的代码更改:

d.values

是的, var summary = d3.nest() .key(function(d) {return d.leader}) .key(function(d) {return d.company}) .key(function(d) {return d.competent}) .sortKeys(function(a, b) {return scaleValues.indexOf(a) - scaleValues.indexOf(b)}) .rollup(function(l) {return l.length}) .entries(data) .map(function(d) { return { key: d.key, values: d.values.map(function (row){ return { key: row.key, values: makeAllKeys(+d.key).map(function(k) { value = row.values.filter(function(v) {return v.key == k})[0] return value || ({key: k, values:0}) }) } }) } }) 可以链接到.map本身。

现在d3.nest如下所示:

summary

这里有一个供参考的plunkr链接:http://plnkr.co/edit/Zz7dsTbmO8dI3n3SKkP3?p=preview

希望这会有所帮助。