d3.js力有向图:如何使节点大小取决于链接的值?
d3.js force directed graph: How to make node size depends on the value of the links?
我有这样的数据:
var nodes = [
{
"id": "A",
"label": "Data A",
"group": "0",
"level": "0"
}, {
"id": "B",
"label": "Data B",
"group": "1",
"level": "1"
},
// etc //
]
var links = [
{
"source": "A",
"target": "B",
"strength": "0.5",
"value": "276"
}, {
"source": "A",
"target": "C",
"strength": "0.5",
"value": "866"
},
// etc //
]
我一直在尝试根据 link 中的 value
设置节点半径大小,这些 link 将节点作为其 target
。
因此,例如,节点 B 的大小应根据值 276(以节点 B 为目标的 link)。
这是我用的:
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", function(node,link){
var radius = 12;
if (node.level == 0) radius = radius * 2; // Setting up the main node as bigger than others
node.weight = link.filter(function(link) {
if (link.target.index == node.index){
var linkValue = link.value;
if (linkValue > 500) ? (radius = 12) : (radius = 6);
}
});
return radius;
})
.attr("fill", getNodeColor)
.attr("stroke", "#fff")
.attr('stroke-width', 2)
.on('mouseover', selectNode)
虽然这似乎不起作用。说它无法识别 link.filter
,某些东西 。我正在使用 d3.js v4.
尝试查找线索,但仍然没有任何提示。有什么想法吗?
有几处需要更改,但首先您应该了解您不会自动将 links
添加到节点的数据。
所以filter语句的目的似乎是根据索引在那个数组中找到对应的link。
没有 link
变量传递到外部函数,但您应该搜索上面定义的 links
数组,寻找一个 link 具有节点 ID 的目标。
如果您只需要一个 link,而不是全部,请使用 Array.prototype.find。但 filter
和 find
的工作方式相同 - 定义的匿名函数在数组中的每个项目上调用。 find
在第一个找到的对象处停止,而 filter
returns 所有匹配项。
.attr("r", function(dat, index, n) {
var linkItem = links.find(function(link) {
return link.target == dat.id;
});
var radius = 12;
// linkItem would be undefined if the item was not found in the links
if (linkItem && linkItem.value > 500) {
radius = 12;
} else {
radius = 6;
}
// you should double the radius towards the end,
// so that radius doesn't get overwritten
if (dat.level === 0) {
radius = 2 * radius;
}
return radius;
})
我有这样的数据:
var nodes = [
{
"id": "A",
"label": "Data A",
"group": "0",
"level": "0"
}, {
"id": "B",
"label": "Data B",
"group": "1",
"level": "1"
},
// etc //
]
var links = [
{
"source": "A",
"target": "B",
"strength": "0.5",
"value": "276"
}, {
"source": "A",
"target": "C",
"strength": "0.5",
"value": "866"
},
// etc //
]
我一直在尝试根据 link 中的 value
设置节点半径大小,这些 link 将节点作为其 target
。
因此,例如,节点 B 的大小应根据值 276(以节点 B 为目标的 link)。
这是我用的:
var nodeElements = g.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", function(node,link){
var radius = 12;
if (node.level == 0) radius = radius * 2; // Setting up the main node as bigger than others
node.weight = link.filter(function(link) {
if (link.target.index == node.index){
var linkValue = link.value;
if (linkValue > 500) ? (radius = 12) : (radius = 6);
}
});
return radius;
})
.attr("fill", getNodeColor)
.attr("stroke", "#fff")
.attr('stroke-width', 2)
.on('mouseover', selectNode)
虽然这似乎不起作用。说它无法识别 link.filter
,某些东西
尝试查找线索,但仍然没有任何提示。有什么想法吗?
有几处需要更改,但首先您应该了解您不会自动将 links
添加到节点的数据。
所以filter语句的目的似乎是根据索引在那个数组中找到对应的link。
没有 link
变量传递到外部函数,但您应该搜索上面定义的 links
数组,寻找一个 link 具有节点 ID 的目标。
如果您只需要一个 link,而不是全部,请使用 Array.prototype.find。但 filter
和 find
的工作方式相同 - 定义的匿名函数在数组中的每个项目上调用。 find
在第一个找到的对象处停止,而 filter
returns 所有匹配项。
.attr("r", function(dat, index, n) {
var linkItem = links.find(function(link) {
return link.target == dat.id;
});
var radius = 12;
// linkItem would be undefined if the item was not found in the links
if (linkItem && linkItem.value > 500) {
radius = 12;
} else {
radius = 6;
}
// you should double the radius towards the end,
// so that radius doesn't get overwritten
if (dat.level === 0) {
radius = 2 * radius;
}
return radius;
})