D3.js从复选框中进行多项选择,并根据选择过滤节点和链接

时间:2016-12-02 20:38:57

标签: javascript jquery html d3.js

我希望修改现有的强制有向图并使其更灵活。 以下是Jsfiddle。现在有单选按钮来控制节点和链接的不透明度。有4种节点类型:

   Agent,Customer,Phone,ID_Card

单击任一单选按钮将降低除选定节点及其传入和传出链接之外的所有节点和链接的不透明度。

我正在尝试添加复选框而不是单选按钮,以便可以进行多项选择。

因此,例如,如果s是选择集,那么您将使任何节点在s中的节点处不透明 并且任何链接都是不透明的,其中s中的start_node和s中的end_node。

例如,如果选择“客户”和“代理”节点,则所有客户,代理节点应该是不透明的,以及它们之间的所有链接。

如果选择“客户”,“代理”,“ID_Card”,则所有3个节点以及“客户”和“代理”,“代理”,“ID_Card”,“客户”和“ID_卡”之间的所有链接都应该是不透明的。

此外,应该处理取消选中的节点,并相应地过滤图表

以下是 HTML

      <div id="map"></div>
      <div id="legend">
  <h3>Filter</h3>
  <div class="input-group" id="filters">
  <script>/*<<label>
      <input type="checkbox" name="filter" value="all" > All</label>
    <br />
    <label>
  <input type="checkbox" name="filter" value="Customer"> type=Customer</label>
    <label>
      <input type="checkbox" name="filter" value="Phone"> type=Phone</label>
   <br />
   <label>
   <input type="checkbox" name="filter" value="ID_Card"> type=ID_Card</label>
   <br />

以下是 JSON

    var IDData = JSON.stringify([
  ["node/105173", "node/38180995", "Agent", "Customer", "1379644.0", 1, 264, "1374903"],
  ["node/1061", "node/21373542", "Agent", "Customer", "530848.0", 1, 3000, "529502"],
  ["node/10750", "node/59648369", "Agent", "Customer", "1454228.0", 1, 120, "1454118"],
  ["node/10750", "node/78569210", "Agent", "Customer", "1425251.0", 1, 234, "1421416"],
  ["node/10750", "node/96726118", "Agent", "Customer", "1376239.0", 1, 434, "1376152"],
  ["node/10946829", "node/11190", "Customer", "Agent", "1409620.0", 20, 3380, "1406665"],
  ["node/10946829", "node/57774036", "Customer", "Customer", "1460029.0", 3, 960, "1459731"],
  ["node/109947", "node/97911872", "Agent", "Customer", "1323025.0", 1, 600, "1315582"],...])

我解析了这个动态JSON数据并使其格式适合使用下面的javascript代码呈现图形:

         var galData = JSON.parse(IDData);
var startnodes = [];
var endnodes = [];
var startnodetype = [];
var endnodetype = [];
var PayTime = [];
var TXN_COUNT = [];
var Total_Amt = [];
var SendTime = [];
galData.map(function(e, i) {
  startnodes.push(e[0]);
  endnodes.push(e[1]);
  startnodetype.push(e[2]);
  endnodetype.push(e[3]);
  PayTime.push(e[4]);
  TXN_COUNT.push(e[5]);
  Total_Amt.push(e[6]);
  SendTime.push(e[7]);
});
var final_data = createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime);
makeGraph("#Network_graph", final_data);

为了使复选框工作,我尝试了以下代码:

     d3.selectAll("input[name=filter]").on("change", function(d) {
  var filter = document.getElementsByName('filter')

  var value = []

    var value[i]= this.value;

    node.style("opacity", 1);
    link.style("opacity", 1);
for(var i = 0; i < filter.length; ++i) {
if filter[i].checked {
    if (value[i] !== "all") {
      node.filter(function(d) {
          return d.type != value[i]; //this 
        })
        .style("opacity", "0.2");

        }}})

这件作品应该过滤节点,并且只将选中的节点保持为不透明:

使用类似的方法我打算保持所选链接不透明:

link.filter(function(d) {
      return d.source.type != value[i] &&
        d.target.type != value[i];
    })
    .style("opacity", "0.2");

  link.filter(function(d) {
      return d.source.type == value[i] &&
        d.target.type == value[i];
    })
    .style("opacity", "1");
}

但我没有让这个工作。还在学习Javascript / d3.js。所以,寻求帮助。

1 个答案:

答案 0 :(得分:1)

处理复选框时,您必须检查所有,以查看哪一个已选中,哪一个未选中。现在,您的代码正在处理复选框,就好像它们是单选按钮一样。

这是一个解决方案。在.on("change"功能中,我们会发现检查了哪些复选框:

function getCheckedBoxes(chkboxName) {
    var checkboxes = document.getElementsByName(chkboxName);
    var checkboxesChecked = [];
    for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].checked) {
            checkboxesChecked.push(checkboxes[i].defaultValue);
        }
    }
    return checkboxesChecked.length > 0 ? checkboxesChecked : " ";
}

然后我们将填充一个数组(此处命名为checkedBoxes):

var checkedBoxes = getCheckedBoxes("checkb");

使用该数组,我们将设置节点和链接的不透明度:

node.filter(function(d) {
        return checkedBoxes.indexOf(d.type) < 0;
    })
    .style("opacity", "0.2");

link.filter(function(d) {
        return checkedBoxes.indexOf(d.source.type) < 0 &&
            checkedBoxes.indexOf(d.target.type) < 0;
    })
    .style("opacity", "0.2");

link.filter(function(d) {
        return checkedBoxes.indexOf(d.source.type) > -1 &&
            checkedBoxes.indexOf(d.target.type) > -1;
    })
    .style("opacity", "1");

这是您更新的小提琴:http://jsfiddle.net/jcbpvev6/

PS:你必须为&#34; All&#34;创建一个特殊条件。复选框。