繁体   English   中英

如何根据属性条件过滤JavaScript对象?

[英]How to filter JavaScript object based on property condition?

我正在d3可视化上创建森伯斯特。 我还添加了搜索特定弧的功能,以便旭日形仅显示带有搜索标签的弧。 如果初始对象是:

{
    "name": "root",
    "children": [
        {
            "name": "A",
            "color": "red",
            "children": [
                {
                    "name": "B",
                    "color": "red"
                }
            ]
        },
        {
            "name": "C",
            "color": "red",
            "children": [
                {
                    "name": "D",
                    "color": "red"
                }
            ]
        },
        {
            "name": "E",
            "color": "red",
            "children": [
                {
                    "name": "B",
                    "color": "red"
                }
            ]
        }
    ]
}

我想对此进行过滤,以使其返回整个层次结构,其中包含层次结构中任何位置的搜索名称。 以下是搜索“名称”:“ B”时所需的示例输出

{
    "name": "root",
    "children": [
        {
            "name": "A",
            "color": "red",
            "children": [
                {
                    "name": "B",
                    "color": "red"
                }
            ]
        },
        {
            "name": "E",
            "color": "red",
            "children": [
                {
                    "name": "B",
                    "color": "red"
                }
            ]
        }
    ]
}

请告诉我是否还有其他需要。 谢谢。

我如何过滤的代码段。

var path = svg.selectAll("path")
           .data(partition.nodes(root))
           .enter()
           .append("path")
           .filter(function(d){ 
               return (d.name=="B");
           })
           .attr("d", arc)
           .style("fill", function(d) {
               console.log(d.name);
               return color((d.children ? d : d.parent).name); 
           })

这仅返回“名称”:“ B”弧,而不返回层次结构。

如果要使用.filter()方法,则必须将JSON数据展平以应用过滤器,然后再取消展平。 如果有兴趣,可以检查展平和展平。 我个人更喜欢深度优先搜索(或者bfs也可以)和修剪(如果需要)的方法。 假设您的json数据存在于mydata javascript var中:

d3.json("jsonData.json",function(error,jsonData){
  if(error)
    return console.warn(error);
  var mydata = jsonData;
  dfs(mydata,'B');
});

现在,您的dfs()函数将如下所示:

function dfs(data,label){
  if(!('children' in data))
    return data.name==label;
  for(var i=0;i<data.children.length;++i)
    if(dfs(data.children[i],label)==flase)
      data.children.splice(i--,1);
  return data.children.length > 0 || data.name==label;
}

这里发生的是我们正在对JSON数据进行深度优先搜索。 第一个IF条件检查我们是否在叶节点级别,如果'name'属性不是'B',则返回false。 接下来,我们遍历当前节点的所有子节点,为每个子节点调用dfs()并修剪该子节点(如果它返回false)。 最后,如果当前节点的所有子节点都已被修剪并且当前节点的'name'属性不是'B'(非叶子节点也必须从层次结构中修剪的条件),则我们返回false。 希望这可以帮助。 让我知道我是否错过了什么。

我的直觉是您想在旭日中为搜索节点及其父节点着色。

为此,我制作了一个函数,可以像这样递归地为节点的父节点着色:

function colorGraph(node){

    var sel = svg.selectAll("path").filter(function (d) {
        return (node==d);
    });
    sel.style("opacity", 1);
    //if parent present change its opacity
    if(node.parent){
        colorGraph(node.parent)
    }
}

完整的工作代码在这里

您将需要预先过滤,而不是在D3管道中进行过滤。

定义一个过滤器函数,我们将调用hasName ,该函数检查特定对象是否具有所需名称,或者递归检查其子hasName是否具有所需名称:

// Does the object contain a specified name, however many levels down?
function hasName(obj, name) {
  return function _hasName(o) {
    return o.name === name || (o.children || []).some(_hasName);
  }(obj);

}

现在过滤:

data.children = data.children.filter(function(child) { return hasName(child, 'B'); });

暂无
暂无

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

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