美好的一天,
我之前关于这个项目的问题是:
D3.js: Dynamically generate source and target based on identical json values
我是d3.js的新手,特别是在数据操作和节点图区域。我想问几个关于创建节点图的数据操作问题。在执行我的项目时,我遇到了几个问题,导致了几个问题:
1)源和目标值必须具有独特性吗?
如果源/目标值不唯一,链接是否会起作用?
2)突出显示/更改连接到当前所选节点的链接属性的方法
到目前为止,我只能使用以下方法更改当前节点的属性:
var simulation = d3.forceSimulation(graphData)
.force("charge", d3.forceManyBody().strength(-300))
.force("link", d3.forceLink().id(function(d) { return d[idSel]; }).distance(70))
.force("x", d3.forceX(width/2))
.force("y", d3.forceY(height/2))
.on("tick", ticked);
var g = svg.append("g"),
link = g.append("g").attr("stroke-width", 1.5).selectAll(".link"),
node = g.append("g").attr("stroke-width", 1.5).selectAll(".node");
simulation.nodes(graphData);
simulation.force("link").links(links);
link = link
.data(links)
.enter().append("line")
.attr("class", "link");
node = node
.data(graphData)
.enter().append("circle")
.attr("class", "node")
.attr("r", 6)
.style("fill", function(d, i) { return colors(d[idSel]); })
.on("click", function (d, i, l) {
//Node Effect - Change only selected node's size
d3.selectAll(".node").attr("r", 6);
d3.select(this).attr("r", 12);
//Link Effect - Highlight adjacent Links
... Need help here ...
});
function ticked()
{
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
我从http://bl.ocks.org/mbostock/1095795得到了模拟示例 但是,我确实理解这也是效率低下的,但鉴于我对d3的了解有限,我无其他办法。
此外,我发现我必须使用:
function restart() { 。node.exit()除去(); 。link.exit()除去(); simulation.nodes(节点); simulation.force("连结&#34)。链接(链接); simulation.alpha(1).restart(); }
要重新启动模拟,否则任何错误都将导致程序无法计算x / y值。但是,当我将此代码实现为重启函数时,新创建的节点不再具有x / y值。我做错了什么?
对于这个模糊的问题感到抱歉..非常感谢任何指导。谢谢SO社区! :)
答案 0 :(得分:1)
仅回答有关如何突出显示链接的问题(因为您没有提供links
数组,以下是基于您previous code的答案):
node.on("click", function(d) {
var thisNode = d.id
d3.selectAll(".circleNode").attr("r", 6);
d3.select(this).attr("r", 12);
link.attr("opacity", function(d) {
return (d.source.id == thisNode || d.target.id == thisNode) ? 1 : 0.1
});
});
此代码的作用是什么?
首先,我们获取所点击节点的ID:
var thisNode = d.id
然后,我们扫描链接以查看源或目标是否具有相同的ID:
(d.source.id == thisNode || d.target.id == thisNode)
如果确实如此,我们使用三元运算符设置不透明度:
(condition) ? 1 : 0.1
这是演示,点击节点:
var nodes = [{
"id": "red",
"value": "1"
}, {
"id": "orange",
"value": "2"
}, {
"id": "yellow",
"value": "3"
}, {
"id": "green",
"value": "1"
}, {
"id": "blue",
"value": "1"
}, {
"id": "violet",
"value": "3"
},{
"id": "white",
"value": "1"
},{
"id": "gray",
"value": "1"
},{
"id": "teal",
"value": "3"
}
];
var links = [];
for (var i = 0; i < nodes.length; i++) {
for (var j = i + 1; j < nodes.length; j++) {
if (nodes[i].value === nodes[j].value) {
links.push({
source: nodes[i].id,
target: nodes[j].id
});
}
}
};
var width = 300,
height = 300;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}).distance(50))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links)
.enter().append("line")
.attr("stroke-width", 1)
.attr("stroke", "gray")
.attr("fill", "none");
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", 6)
.attr("class", "circleNode")
.attr("stroke", "gray")
.attr("fill", function(d) {
return d.id;
});
node.on("click", function(d) {
var thisNode = d.id
d3.selectAll(".circleNode").attr("r", 6);
d3.select(this).attr("r", 12);
link.attr("opacity", function(d) {
return (d.source.id == thisNode || d.target.id == thisNode) ? 1 : 0.1
});
});
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;