Search for an element in D3 - force layout or tree

不问归期 提交于 2019-12-09 12:56:09

问题


Is there an example of searching for an element in a d3js layout (force directed or tree) and highlighting that element?

I am thinking that there would be a text field where user enters values to search.


回答1:


I wrote a tool that allows browsing biological regulatory networks, showing two SVG panels side-by-side. Each panel contains a force-layout network of transcription factors (the nodes), as drawn by the d3.js API. You can type in the name of a transcription factor and it will highlight it using the same code as is used when a mouseover event occurs. Exploring the code might give you some insight into how it's done.




回答2:


I have coded a solution with a search widget based on a select2.
You get found nodes with their paths expanded styled in red.
The tree is fully explored and multiple answers can be found.

Collapsible Tree Search
https://gist.github.com/PBrockmann/0f22818096428b12ea23

Hope that will help
Patrick




回答3:


Here's a gist I made, perhaps relevant?

I broke my implementation into 3 steps:

1) On selection of a leaf node name in the select2 box, searchTree.

$("#search").on("select2-selecting", function(e) {
    var paths = searchTree(root,e.object.text,[]);
    if(typeof(paths) !== "undefined"){
        openPaths(paths);
    }
    else{
        alert(e.object.text+" not found!");
    }
})

2) searchTree returns an array of nodes in order of distance from the root node (the path)

function searchTree(obj,search,path){
    if(obj.name === search){ //if search is found return, add the object to the path and return it
        path.push(obj);
        return path;
    }
    else if(obj.children || obj._children){ //if children are collapsed d3 object will have them instantiated as _children
       var children = (obj.children) ? obj.children : obj._children;
       for(var i=0;i<children.length;i++){
            path.push(obj);// we assume this path is the right one
            var found = searchTree(children[i],search,path);
            if(found){// we were right, this should return the bubbled-up path from the first if statement
                return found;
            }
            else{//we were wrong, remove this parent from the path and continue iterating
                path.pop();
            }
        }
    }
    else{//not the right object, return false so it will continue to iterate in the loop
        return false;
    }
}

3) open the path by replacing "._children" with ".children" and add the class "found" to color everything red. (see link and node instantiations)

function openPaths(paths){
    for(var i=0;i<paths.length;i++){
        if(paths[i].id !== "1"){//i.e. not root
            paths[i].class = 'found';
            if(paths[i]._children){ //if children are hidden: open them, otherwise: don't do anything
                paths[i].children = paths[i]._children;
                paths[i]._children = null;
            }
            update(paths[i]);
        }
     }
}

I realize this may not be the most optimal way to do this but hey, gets the job done :)




回答4:


Aren't you asking for a d3.selectAll ?

https://github.com/mbostock/d3/wiki/Selections#wiki-d3_selectAll

  1. Use an text field with a search button.
  2. Translate the search into a D3/CSS3 selector in your nodes.
  3. d3.selectAll
  4. Apply new styles to the nodes that match / don't make your query.


来源:https://stackoverflow.com/questions/13715127/search-for-an-element-in-d3-force-layout-or-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!