我在D3中使用标记为图形布局的力,我的项目要求之一是与每个节点关联的文本应显示在div / p元素中,该元素占据网页上的固定位置而不是显示直接与相关节点相邻(当前它在鼠标悬停时激活)。因此,每当用户在任何节点上盘旋时,相应的文本都应显示在div标签中,而不是显示在图表中的节点旁边。
以下代码段显示了我目前如何处理节点和标签:
var node = vis.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.call(force.drag);
node.append("text")
.text("");
force.on("tick", function() {
nodes[0].x = w / 2;
nodes[0].y = h / 2;
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.on("mouseover", function(d){
node.classed("node-active", function(o) {
thisOpacity = isConnected(d, o) ? true : false;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
link.classed("link-active", function(o) {
return o.source === d || o.target === d ? true : false;
});
d3.select(this).classed("node-active", true);
d3.select(this).select("circle").transition()
.duration(500)
.attr("r", 20);
d3.select(this).select("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.label; });
d3.select(this).select("circle")
.on("click", function(d){
var win = window.open(d.label, '_blank');
win.focus();
});
})
.on("mouseout", function(d){
node.classed("node-active", false);
link.classed("link-active", false);
d3.select(this).select("circle").transition()
.duration(750)
.attr("r", 10);
d3.select(this).select("text")
.text("");
});
我有一个id ='nodeLabel'的div标签,用于打印节点的标签。我希望附加的代码有所帮助。我尝试使用document.getElementById('nodeLabel')设置它的值,但我不确定这是正确的方法还是这行代码会去哪里?
如何达到预期效果?
答案 0 :(得分:1)
在鼠标悬停处理程序中,只需添加如下内容:
$("#nodeLabel").text(d.label);
以您的代码为基础,这将导致:
node.on("mouseover", function(d){
node.classed("node-active", function(o) {
thisOpacity = isConnected(d, o) ? true : false;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
link.classed("link-active", function(o) {
return o.source === d || o.target === d ? true : false;
});
d3.select(this).classed("node-active", true);
d3.select(this).select("circle").transition()
.duration(500)
.attr("r", 20);
d3.select(this).select("circle")
.on("click", function(d){
var win = window.open(d.label, '_blank');
win.focus();
});
$("#nodeLabel").text(d.label);
})
答案 1 :(得分:0)
我可能会通过
来解决这个问题.each()
并向其传递一个函数,该函数将每个节点的成员变量设置为您要显示的值。onClick
处理程序中,您可以通过d3.select(this)
获取发生事件的元素,因此我将从中获取您在步骤1中存储的值并设置div'相应的文字。这将是d3.select("#nodeLabel").text(nodeText)
答案 2 :(得分:0)
好的,我找到了办法。
我将d.label的值存储到变量中,然后简单地设置' p'的内部HTML。 mouseOver句柄中的标记。
这是更新的代码段:
node.on("mouseover", function(d){
node.classed("node-active", function(o) {
thisOpacity = isConnected(d, o) ? true : false;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
link.classed("link-active", function(o) {
return o.source === d || o.target === d ? true : false;
});
var nodeText;
d3.select(this).classed("node-active", true);
d3.select(this).select("circle").transition()
.duration(500)
.attr("r", 20);
d3.select(this).select("text")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { nodeText = d.label; return d.label; });
d3.select("#nodeLabel").text(nodeText)
d3.select(this).select("circle")
.on("click", function(d){
var win = window.open(d.label, '_blank');
win.focus();
});
console.log(nodeText);
document.getElementById('nodeLabel').innerHTML = "Node selected: "+nodeText;
})
如果有更简单/更好的解决方案,我肯定还是希望听到它并学习!