我想在节点和链接上的文本上创建一个永久可见文本的力图。
此snippet在节点上提供标签。
答案为Show tool-tip on links of force directed graph in d3js的第二个片段在链接和节点上提供鼠标悬停标签。
我正在尝试扩展第二个以使鼠标悬停节点标签永久化。
var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;
var graph = { "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);
function drawGraph(graph) {
var svg = d3.select("#force").append("svg")
.attr("width", width)
.attr("height", height);
// create an area within svg for plotting graph
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + pad + ", " + pad + ")");
var layout = d3.layout.force()
.size([width - margin, height - margin])
.charge(-120)
.nodes(graph.nodes)
.start();
drawNodes(graph.nodes);
// add ability to drag and update layout
d3.selectAll(".node").call(layout.drag);
layout.on("tick", function() {
d3.selectAll(".node")
.attr("cx", d => { return d.x; })
.attr("cy", d => { return d.y; });
});
}
// Draws nodes on plot
function drawNodes(nodes) {
d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", (d, i) => { return d.name; })
.attr("cx", (d, i) => { return d.x; })
.attr("cy", (d, i) => { return d.y; })
.attr("r", 4)
.style("fill", "#EE77b4")
.on("mouseover", function(d, i) {
var x = d3.mouse(this)[0];
var y = d3.mouse(this)[1];
var tooltip = d3.select("#plot")
.append("text")
.text(d.name)
.attr("x", x)
.attr("y", y)
.attr("id", "tooltip");
})
.on("mouseout", function(d, i) {
d3.select("#tooltip").remove();
});
}
body {
font-family: 'Source Sans Pro', sans-serif;
font-weight: 300;
}
b {
font-weight: 900;
}
.outline {
fill: none;
stroke: #888888;
stroke-width: 1px;
}
#tooltip {
font-size: 10pt;
font-weight: 900;
fill: #000000;
stroke: #ffffff;
stroke-width: 0.25px;
}
.node {
stroke: #ffffff;
stroke-weight: 1px;
}
.highlight {
stroke: red;
stroke-weight: 4px;
stroke-opacity: 1.0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div align="center" id="force"></div>
我尝试用:
替换鼠标悬停功能.each( function(d, i) {
var x = d.x; //d3.mouse(this)[0];
var y = d.y; //d3.mouse(this)[1];
var tooltip = d3.select("#plot")
.append("text")
.text(d.name)
.attr("x", x)
.attr("y", y)
.attr("id", "tooltip");
})
但是现在标签没有移动所以我添加了
d3.selectAll("text").attr( "x", d => { return d.x; })
.attr( "y", d => { return d.y; });
layout.on("tick", function() ...
中的
但现在一切都在一个地方不动,我得到TypeError: d is undefined
答案 0 :(得分:2)
以这种方式重写代码(注意评论):
layout.on("tick", function() {
tooltips // here we set new position for tooltips on every tick
.attr("x", (d, i) => { return d.x; })
.attr("y", (d, i) => { return d.y; });
d3.selectAll(".node")
.attr("cx", d => { return d.x; })
.attr("cy", d => { return d.y; });
});
...
function drawNodes(nodes) {
tooltips = d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", (d, i) => { return d.name; })
.attr("cx", (d, i) => { return d.x; })
.attr("cy", (d, i) => { return d.y; })
.attr("r", 4)
.style("fill", "#EE77b4")
.select(function() { return this.parentNode }) // returns to parent node
.append('text') // append svg-text elements for tooltip
.data(nodes)
.text(function(d) { return d.name; }) // set text
.attr("x", (d, i) => { return d.x; }) // set initial x position
.attr("y", (d, i) => { return d.y; }) // set initial y position
.attr("id", function(d,i) { return "tooltip-" + i; }) // set unique id
.attr("class", "d3-tooltip");
}
工作演示:
var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;
var tooltips = null;
var graph = { "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);
function drawGraph(graph) {
var svg = d3.select("#force").append("svg")
.attr("width", width)
.attr("height", height);
// create an area within svg for plotting graph
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + pad + ", " + pad + ")");
var layout = d3.layout.force()
.size([width - margin, height - margin])
.charge(-120)
.nodes(graph.nodes)
.start();
drawNodes(graph.nodes);
// add ability to drag and update layout
d3.selectAll(".node").call(layout.drag);
layout.on("tick", function() {
tooltips
.attr("x", (d, i) => { return d.x; })
.attr("y", (d, i) => { return d.y; });
d3.selectAll(".node")
.attr("cx", d => { return d.x; })
.attr("cy", d => { return d.y; });
});
}
// Draws nodes on plot
function drawNodes(nodes) {
tooltips = d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", (d, i) => { return d.name; })
.attr("cx", (d, i) => { return d.x; })
.attr("cy", (d, i) => { return d.y; })
.attr("r", 4)
.style("fill", "#EE77b4")
.select(function() { return this.parentNode })
.append('text')
.data(nodes)
.text(function(d) { return d.name; })
.attr("x", (d, i) => { return d.x; })
.attr("y", (d, i) => { return d.y; })
.attr("class", "d3-tooltip")
.attr("id", function(d,i) { return "tooltip-" + i; });
}
body {
font-family: 'Source Sans Pro', sans-serif;
font-weight: 300;
}
b {
font-weight: 900;
}
.outline {
fill: none;
stroke: #888888;
stroke-width: 1px;
}
.d3-tooltip {
font-size: 20pt;
font-family: 'Comic Sans MS';
font-weight: 900;
fill: #000000;
stroke: #ffffff;
stroke-width: 0.25px;
}
.node {
stroke: #ffffff;
stroke-weight: 1px;
}
.highlight {
stroke: red;
stroke-weight: 4px;
stroke-opacity: 1.0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div align="center" id="force"></div>