简体   繁体   English

基于按钮单击过滤强制有向图的节点和链接

[英]Filtering nodes and links of a forced directed graph based on a button click

I have a fully working force directed graph . 我有一个完全工作的力导向图。 Next stage is to add buttons in the main html data to filter further. 下一步是在主html数据中添加按钮以进一步过滤。 I have had no luck so far in making it work. 到目前为止,我还没有运气。 Would appreciate any inputs. 将不胜感激任何投入。 Clicking of "High_Txn" should render only those nodes whose links have a value d.Total_Amount > 100 . 单击“High_Txn”应仅呈现链接值为d.Total_Amount > 100节点。

HTML HTML

<style>
    .links line {
        stroke: #999;
        stroke-opacity: 0.6;
    }

    .nodes circle {
        stroke: #fff;
        stroke-width: 1.5px;
    }

    .nodes circle {
        stroke: #fff;
        stroke-width: 1.5px;
    }

    div.tooltip {
        position: absolute;
        background-color: white;
        max-width: 200px;
        height: auto;
        padding: 1px;
        border-style: solid;
        border-radius: 4px;
        border-width: 1px;
        box-shadow: 3px 3px 10px rgba(0, 0, 0, .5);
        pointer-events: none;
    }
</style>
<button type="button" value="Complete">Complete_Data</button>
<button type="button" value="High_Txn">High_Txn</button>

JSON 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"],..])

I parse through this dynamic JSON data and make it in the format necessary for d3.js as follows: 我解析这个动态JSON数据并以d3.js所需的格式进行解析,如下所示:

$(document).ready(function() {

    console.log(IDData);
    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, depth, PayTime, TXN_COUNT, Total_Amt, SendTime);
    makeGraph("#Network_graph", final_data);

});

Using this I have made a force directed graph inspired from d3.js library 使用这个我已经从d3.js库中创建了一个力导向图

See Jsfiddle for complete code and a working graph. 有关完整代码和工作图,请参阅Jsfiddle

Now I am trying to add a filter function that will filter the data on the button click: 现在我正在尝试添加一个过滤器功能,该功能将过滤按钮单击上的数据:

function filterNetwork() { //not sure if this is the right way to filter , so open to other ideas
    force.stop()
    originalNodes = force.nodes();
    originalLinks = force.links();
    influentialNodes = originalNodes.filter(function(d) {
        return d.Total_Amount > 100
    });
    influentialLinks = originalLinks.filter(function(d) {
        return influentialNodes.indexOf(d.source) > -1 && influentialNodes.indexOf(d.target) > -1
    });

    d3.selectAll("g.node")
        .data(influentialNodes, function(d) {
            return d.id
        })
        .exit()
        .transition()
        .duration(12000)
        .style("opacity", 0)
        .remove();

    d3.selectAll("line.link")
        .data(influentialLinks, function(d) {
            return d.source.id + "-" + d.target.id
        })
        .exit()
        .transition()
        .duration(9000)
        .style("opacity", 0)
        .remove();

    force
        .nodes(influentialNodes)
        .links(influentialLinks)

    force.start()
}

Also , how to connect the above filter function to a button click in html? 另外,如何将上述过滤功能连接到html中的按钮单击? I don't have much expertise in javascript to pull something like this off. 我没有太多的javascript专业知识来拉这样的东西。 So , looking forward for some help 所以,期待一些帮助

OK here's the fiddle: https://jsfiddle.net/t6ycuoyo/54/ 好的,这是小提琴: https//jsfiddle.net/t6ycuoyo/54/

I've made a button and added an eventListener to it so that when it is clicked it will filter the links and nodes and re-render your graph: 我已经创建了一个按钮,并为其添加了一个eventListener,这样当它被单击时,它将过滤链接和节点并重新渲染图形:

function isUnique(id, nodes){
    for(var i = 0; i < nodes.length; i++){
        if(nodes[i].id == id){
            return false;
        }
    }
    return true;
}

myBtn.addEventListener("click",function(){
  var nodes = [];
  var links = [];
  d3.selectAll("line").filter(function(d,i){
     if(d.total_amt>100){
       if(isUnique(d.source.id, nodes)){
            nodes.push(d.source);
       }

       if(isUnique(d.target.id, nodes)){
            nodes.push(d.target);
       }
       links.push(d);
     }
  });
  filtered_data.links = links;
  filtered_data.nodes = nodes;
  filtered_data.nodetype = final_data.nodetype;

  d3.select('#Network_graph').selectAll("*").remove();
  makeGraph("#Network_graph", filtered_data);
});

fullBtn.addEventListener("click",function(){
  d3.select('#Network_graph').selectAll("*").remove();
  makeGraph("#Network_graph", final_data);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM