![](/img/trans.png)
[英]how to add property to property to an object based on the condition in 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.