根据下拉列表

时间:2017-07-05 16:21:47

标签: javascript html json d3.js svg

我有力导向图的节点和链接数据。节点之间可以有一个,两个或三个链接:

{"nodes": [{"id": "Michael Scott", "numOfLinks": 1}
          ,{"id": "Jim Halpert", "numOfLinks": 1}
          ,{"id": "Pam Beasley", "numOfLinks": 2}
          ,{"id": "Kevin Malone", "numOfLinks": 2}
          ,{"id": "Angela", "numOfLinks": 3}
          ,{"id": "Dwight Schrute", "numOfLinks": 3}]
,"links": [{"source": "Michael Scott", "target": "Jim Halpert", "type": "red"}
          ,{"source": "Pam Beasley", "target": "Kevin Malone", "type": "red"}
          ,{"source": "Pam Beasley", "target": "Kevin Malone", "type": "white"}
          ,{"source": "Angela", "target": "Dwight Schrute", "type": "red"}
          ,{"source": "Angela", "target": "Dwight Schrute", "type": "white"}
          ,{"source": "Angela", "target": "Dwight Schrute", "type": "blue"}]
}

我有一个HTML下拉列表,供用户过滤掉没有一定数量链接的节点(和相应的链接):

<select id="selectLinkNumber" name="selectLinkNumber">
     <option value="1">All</option>
     <option value="2">Two or More Links</option>
     <option value="3">Three or More Links</option>
</select>

我已将此下拉列入我的d3代码:

var dropdown = d3.select("#selectLinkNumber")
var change = function() {
d3.selectAll("svg > *").remove()
var val = dropdown.node().options[dropdown.node().selectedIndex].value;

d3.json("test.json", function(error, graph) {
    //do stuff
    })
}
dropdown.on("change", change)
change();

这会导致图形被删除,并在从下拉列表中进行新选择时重新出现。目标是仅显示值大于或等于选择的节点。例如,如果选择“Three”,则只出现Angela,Dwight及其三个链接。如果选择“Two”,则选择Pam,Kevin,Angela,Dwight及其相应的链接。

逻辑上,我认为需要根据test.jsond3.json("test.json", function(error, graph) {行之后直接过滤val数据。但我不确定如何有效地完成这项工作。这个例子(https://jsfiddle.net/tgv6s5cd/14/)基本上就是我正在寻找的东西,但我无法通过手动数据创建和众多功能。我认为在引入test.json

后过滤一次会更简单

用户进行下拉选择后,如何过滤数据?

1 个答案:

答案 0 :(得分:0)

这是Javascript中的基本数组操作。 graph毕竟只是一个具有两个数组属性的对象。

d3.json("test.json", function(error, graph) {
    var filteredNodes = graph.nodes.filter(d => d.numOfLinks >= val);
    var names = filteredNodes.map(d => d.id);
    var filteredLinks = graph.links.filter((d) => {
        return (names.indexOf(d.source) >= 0) || 
               (names.indexOf(d.target) >= 0)
    });

    var filteredGraph = {
        nodes: filteredNodes,
        links: filteredLinks
    };
    // render
})