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

标签 javascript jquery html d3.js

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

   Agent,Customer,Phone,ID_Card

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

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

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

例如,如果选择了“Customer”和“Agent”节点,那么所有 Customer、Agent 节点以及它们之间的所有链接都应该是不透明的。

如果选择了“Customer”、“Agent”、“ID_Card”,则所有 3 个节点以及“Customer”和“Agent”之间的所有链接,“Agent”和“ID_Card”以及“Customer”和“ID_card”应该不透明。

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

下面是 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。所以,寻求帮助。

最佳答案

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

这是一个解决方案。在 .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");

这是您更新的 fiddle :http://jsfiddle.net/jcbpvev6/

PS:您必须为“全部”复选框创建一个特殊条件。

关于javascript - D3.js 从复选框中进行多项选择并根据选择过滤节点和链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40940483/

相关文章:

javascript - 如何让页脚固定在底部?

javascript - 如何在显示前页面自动滚动到底部

javascript - jQuery - 获取 .NET RequiredFieldValidator "ControlToValidate"的值

html - 如何在文本区域换行后启用 BR 标签

html - 封面图像上的灰度文本

字符串中的 JavaScript 变量

javascript - 按价格对元素排序,顺序是10、100、12、13、140?

javascript - 在对象数组javascript中查找重复项

javascript - 如何使用按钮重置网页

javascript - 添加并应用带有按钮/链接的新 CSS 样式表