Силовой направленный граф D3 - узлы фильтра и связанные ссылки

У меня возникли проблемы с фильтром, который я пытаюсь использовать в своем форсированном графе. Я могу отфильтровать узлы, но не могу удалить связанные ссылки. Мои знания JavaScript довольно ограничены, но я предполагаю, что логика должна быть следующей: если узел скрыт, то скрыть связанные ссылки. Я на правильном пути? Если бы кто-то мог помочь мне с этим, это было бы очень ценно!

Формат данных:

{
  "nodes": [
{"name":"AA1","group":"Group1","type":"a"},
{"name":"AA2","group":"Group2","type":"b"},
{"name":"AA3","group":"Group3","type":"c"},
{"name":"AA4","group":"Group4","type":"a"},
{"name":"AA5","group":"Group2","type":"b"},
{"name":"AA6","group":"Group4","type":"c"},...
],
  "links": [
{"source":1,"target":59,"value":1},
{"source":1,"target":88,"value":1},
{"source":3,"target":12,"value":1},
{"source":3,"target":16,"value":1},
{"source":3,"target":87,"value":1},
{"source":5,"target":3,"value":1},
{"source":5,"target":16,"value":1},
{"source":5,"target":114,"value":1},...  ]

КОД ФИЛЬТРА:

 // call method to create filter
createFilter();
// method to create filter
function createFilter()
{
    d3.select(".filterContainer").selectAll("div")
      .data(["a", "b", "c"])
      .enter()
      .append("div")
          .attr("class", "checkbox-container")
      .append("label")
      .each(function(d) {
         // create checkbox for each data
      d3.select(this).append("input")
        .attr("type", "checkbox")
        .attr("id", function(d) {return "chk_" + d;})
        .attr("checked", true)
        .on("click", function(d, i) {
            // register on click event
            var lVisibility = this.checked? "visible":"hidden";
            filterGraph(d, lVisibility);
        })
        d3.select(this).append("span")
          .text(function(d){return d;});
      });

      $("#sidebar").show();  // show sidebar
}

 // Method to filter graph
function filterGraph(aType, aVisibility)
{   
 // change the visibility of the node

    node.style("visibility", function(o) {
    var lOriginalVisibility = $(this).css("visibility");
    return o.type === aType ? aVisibility : lOriginalVisibility;
    }); 

/////////////////////////////////////// НЕОБХОДИМЫЙ КОД ДЛЯ СКРЫТЫХ ССЫЛК ////// ////////////////////////////////

}

1 ответ

Решение

Вам необходимо скрыть ссылку, проверив, не выбран ли ее источник или цель. Итак, в вашей части filterGraph добавьте что-то вроде (предположим, что ваши ссылки имеют class="link"):

positive = ["Dahlia", "Tholomyes"];
link.attr("display", function (o) {

////Here the structure of the the link can vary, sometimes it is o["source"]["name"], sometimes it is o["source"]["name"], check it out before you fill in.
var source_name = o["source"]["id"];
var target_name = o["target"]["id"];

var result = positive.indexOf(source_name) != -1 && positive.indexOf(target_name) != -1 ? "auto" : "none"

return result;

});

Взять, к примеру, несчастного Майка Бостока. Я использовал приведенный выше код, чтобы отфильтровать все остальные, кроме того, который соединяет "Георгин" и "Толомис".

введите описание изображения здесь

Вот фрагмент для вашего примера jsfiddle:

var hidden_nodes =[];
 // Method to filter graph
function filterGraph(aType, aVisibility)
{   
 // change the visibility of the node
 // if all the links with that node are invisibile, the node should also be invisible
// otherwise if any link related to that node is visibile, the node should be visible
// change the visibility of the connection link


    node.style("visibility", function(o) {
        var lOriginalVisibility = $(this).css("visibility");
        if (o.type == aType) {
            if (aVisibility == "hidden")
                {
                    hidden_nodes.push(o.name);
                }
            else
                {
                    index = hidden_nodes.indexOf(o.name);
                    if (index > -1) 
                    {
                        hidden_nodes.splice(index, 1);
                    }
                }
        }
        return o.type === aType ? aVisibility : lOriginalVisibility;

    }); 


    link.attr("display", function (o) {
    ////Here the structure of the the link can vary, sometimes it is o["source"]["name"], sometimes it is o["source"]["name"], check it out before you fill in.
    var source_name = o["source"]["name"];
    var target_name = o["target"]["name"];


    var result = hidden_nodes.indexOf(source_name) != -1 || hidden_nodes.indexOf(target_name) != -1 ? "none" : "auto"

    return result;

    });
}
Другие вопросы по тегам