首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >搜索d3树-搜索后重置

搜索d3树-搜索后重置
EN

Stack Overflow用户
提问于 2015-03-23 21:49:07
回答 1查看 607关注 0票数 0

我编写了一个搜索函数来运行一个可能相当大的d3树,并且只过滤出匹配搜索模式的节点。

该搜索功能工作良好,速度也相当快。

但是,由于服务器上的数据量和计算数据的时间,如果用户清除搜索或输入另一个搜索,而不进行另一个查询,我希望能够将树重置为其初始内容。这不管用。

,这就是我尝试过的:

1-克隆d3节点

首先,我看了一下,他们有几个建议。从茉莉花身上跑出来,我的克隆技术似乎奏效了(不知道为什么)。

在我的应用程序中运行代码,我会得到一个即时的错误。准确的错误取决于我使用的代码- jquery.extend或JSON.parse of JSON.stringify。

我怀疑这是因为每个节点d都有一个d.parent属性和一个d.children属性,所以只要您想递归地克隆它的子节点,它就会进入一个循环。

2-设置d3.layout.tree.children以过滤数据。

然后我注意到有一个d3.layout.tree.children函数,我可以用它来操作树。因此,我这样做而不是复制json数据,并且只返回d.visible为真的节点。我的想法是,我不需要做任何事,当我想要重置,我只是回到基地,不过滤,孩子们。

这也不起作用--不匹配搜索的子节点现在已经从数据中消失了,而不仅仅是图表。

更新:我删除了我的初始示例代码,它没有工作,我自己给出了一个对我有用的初步答案.

EN

回答 1

Stack Overflow用户

发布于 2015-03-25 17:19:09

不确定这是否是最优雅的方法,但它对我有效。

基本上,在进行搜索之前,我只需将引用复制到现有的_nodes。搜索通过匹配搜索模式的树和克隆节点进行递归。以及具有匹配搜索模式的子节点的任何节点。因此克隆体的体积受匹配量的限制。克隆代码本身是相当天真的-它只处理原始值,但这是我现在所需要的。

注意:_nodes基本上是您在任何在线d3示例中看到的传入json数据。

代码语言:javascript
复制
//support an array of possible attributes for string matches...
var li_tosearch = ["label"];

//a "set" of node attributes that should not be copied    
s_skip = Object.create(null);
s_skip.parent = 1;
s_skip.children = 1;
s_skip._children = 1;
s_skip._unfiltered_children = 1;


function clone_n_filter(pattern, d) {
    /* recursive search by node 
       - a node is visible if one of its searchable attributes
       matches the pattern or if one of its children/_children is
       visible.
       - only visible nodes get cloned 
    */

    if (!d  || !pattern){
        return;
    }

    var visible_child, clone, v, s;
    var visible = false;


    //support an array of possible attributes for string matches...
    for (var i = 0; i < li_tosearch.length; ++i){
        s = d[li_tosearch[i]];
        if (s){
            if (s.match(pattern)){
                visible = true;
                break;
            }
        }
    }


    var children = [], _children = [];

    //if any of the children are visible then the current is visible too
    if (d.children) {
        for (var index = 0; index < d.children.length; ++index) {
            visible_child = clone_n_filter(pattern, d.children[index]);
            if (visible_child) {
                children.push(visible_child);
                visible = true;
            }
        }
    }


    if (d._children) {
        for (var index2 = 0; index2 < d._children.length; ++index2) {
            visible_child = clone_n_filter(pattern, d._children[index2]);
            if (visible_child) {
                _children.push(visible_child);
                visible = true;
            }
        }
    }

    //not being used, but keeps track of all original children
    //this is just a reference, so memory cost is low
    //possible use case:  expand a non-leaf node that has
    //no visible children
    d._unfiltered_children = d.children || d._children;

    if (visible){
        clone = d.constructor(); // changed

        for(var key in d) {
            if (key in s_skip){
                continue;
            }

            if(d.hasOwnProperty(key)) {
                v = d[key];

                //given the domain, only expecting primitives...
                //will address when that breaks
                if (typeof(v) === 'object'){
                    throw("unexpected complex object:[" + typeof(v) + " " + key + "]");
                }

                clone[key] = v;
            }
            else{
                //keeping track of attributes we won't be copying
                s_skip[key] = 1;
            }
        }
        clone.children = children;
        clone._children = _children;

    }

    return clone;

}

整件事的入口点。重置非常快-它只是将_nodes设置为原始保存的引用。

代码语言:javascript
复制
_chart.search = function(pattern){
  /* external entry point for calling the search*/

    if (!_nodes){
        return;
    }

    if (!pattern){
        //no search pattern
        if  (_o_nodes){
            //restore unfiltered
            _nodes = _o_nodes;            
        }
        chart.render();
        return;
    }

    if (!_o_nodes){
        //no need to clone the _nodes, just copy reference
        _o_nodes = _nodes;        
    }

    var patre = new RegExp(pattern,"gi");
    _nodes = clone_n_filter(patre, _o_nodes);

    chart.render();
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29221075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档