2016-11-15 2 views
1

У меня есть диаграмма направленности с полной рабочей силой. Следующий этап - добавить кнопки в основные html-данные для дальнейшего фильтрации. Мне до сих пор не повезло в том, чтобы заставить его работать. По достоинству оценят любые входы. Нажатие «High_Txn» должно отображать только те узлы, чьи ссылки имеют значение d.Total_Amount > 100.Фильтрация узлов и ссылок на вынужденный ориентированный граф на основе нажатия кнопки

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

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 и сделать его в формате, необходимом для 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); 

}); 

С помощью этого я сделал силы ориентированный граф, вдохновленный от d3.js library

См Jsfiddle для полного кода и рабочего графика.

Теперь я пытаюсь добавить функцию фильтра, который будет фильтровать данные по нажатию кнопки:

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() 
} 

Кроме того, как подключить выше фильтр функцию нажатием кнопки в HTML? У меня нет большого опыта в javascript, чтобы вытащить что-то вроде этого. Так, глядя вперед за помощью

+0

скрипка не работает – echonax

+0

@echonax предоставил пример рабочей скрипки сейчас. –

ответ

0

OK вот скрипку: https://jsfiddle.net/t6ycuoyo/54/

Я сделал кнопку и добавил 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); 
}); 
+0

Я замечаю, что количество узлов и ссылок увеличивается после нажатия кнопки «clicky». –

+1

Хорошо теперь имеет смысл .. никогда не думает .. Thanks ton. –

+0

@optimus_prime Я забыл очистить svg перед повторным рендерингом. Поэтому я думаю, что он добавил узлы и ссылки :) просто очистите svg перед повторной рендерингом. – echonax