在d3js的力有向图的链接上显示工具提示
Show tool-tip on links of force directed graph in d3js
我正在制作一个简单的力有向图,如此链接所示。它工作得很好,但我想在边缘上显示工具提示,就像在节点上显示一样。每当我在边缘上移动鼠标时,它就会在链接上显示一些工具提示(数据可以从JSON文件中检索)。是否有一个内置的方法,或者我必须在鼠标悬停时显示div(在这种情况下如何获得鼠标的位置,div将显示在哪里)
- 是否有内置方法?
和:是的。这是一种固有的方式。大多数HTML元素都支持title属性。当您将鼠标指针移动到该元素上时,会在一段时间内显示一个小工具提示,或者直到您离开该元素为止。
演示:var w = 500,
h = 200
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
var graph = {
nodes: [{
name: 'A'
}, {
name: 'B'
}],
links: [{
source: 0,
target: 1
}]
};
var force = d3.layout.force()
.nodes(graph.nodes)
.links(graph.links)
.gravity(.05)
.distance(100)
.charge(-100)
.size([w, h])
.start();
var link = vis.selectAll("line.link")
.data(graph.links)
.enter().append("svg:line")
.attr("class", "link");
link.append("title").text(function(d) {
return d.source.name + " -> " + d.target.name
});
var node = vis.selectAll("g.node")
.data(graph.nodes)
.enter().append("svg:g")
.attr("class", "node")
.call(force.drag);
node.append("circle").attr("r", 5);
node.append("title").text(function(d) {
return d.name
});
force.on("tick", function() {
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 + ")";
});
});
line {
stroke: red;
stroke-width: 3;
}
cicrle {
fill: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
- 或者我必须在鼠标悬停时显示div ?如何获取鼠标的位置?div将显示在哪里?
答:
如果你想显示一个html内容的工具提示,你可以在鼠标悬停时显示一个div。您可以使用d3.mouse
方法获得鼠标位置。
var width = 960;
var height = 500;
var margin = 20;
var pad = margin / 2;
var color = d3.scale.category20();
var graph = {
"nodes": [{
"name": "Myriel",
"group": 1
}, {
"name": "Napoleon",
"group": 1
}, {
"name": "Mlle.Baptistine",
"group": 1
}, {
"name": "Mme.Magloire",
"group": 1
}, {
"name": "CountessdeLo",
"group": 1
}, {
"name": "Geborand",
"group": 1
}, {
"name": "Champtercier",
"group": 1
}, {
"name": "Cravatte",
"group": 1
}, {
"name": "Count",
"group": 1
}, {
"name": "OldMan",
"group": 1
}, {
"name": "Labarre",
"group": 2
}, {
"name": "Valjean",
"group": 2
}, {
"name": "Marguerite",
"group": 3
}, {
"name": "Mme.deR",
"group": 2
}, {
"name": "Isabeau",
"group": 2
}, {
"name": "Gervais",
"group": 2
}, {
"name": "Tholomyes",
"group": 3
}, {
"name": "Listolier",
"group": 3
}, {
"name": "Fameuil",
"group": 3
}, {
"name": "Blacheville",
"group": 3
}, {
"name": "Favourite",
"group": 3
}, {
"name": "Dahlia",
"group": 3
}, {
"name": "Zephine",
"group": 3
}, {
"name": "Fantine",
"group": 3
}, {
"name": "Mme.Thenardier",
"group": 4
}, {
"name": "Thenardier",
"group": 4
}, ],
"links": [{
"source": 1,
"target": 0,
"value": 1
}, {
"source": 2,
"target": 0,
"value": 8
}, {
"source": 3,
"target": 0,
"value": 10
}, {
"source": 3,
"target": 2,
"value": 6
}, {
"source": 4,
"target": 0,
"value": 1
}, {
"source": 5,
"target": 0,
"value": 1
}, {
"source": 6,
"target": 0,
"value": 1
}]
};
drawGraph(graph);
function drawGraph(graph) {
var svg = d3.select("#force").append("svg")
.attr("width", width)
.attr("height", height);
// draw plot background
svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "#eeeeee");
// create an area within svg for plotting graph
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + pad + ", " + pad + ")");
// https://github.com/mbostock/d3/wiki/Force-Layout#wiki-force
var layout = d3.layout.force()
.size([width - margin, height - margin])
.charge(-120)
.linkDistance(function(d, i) {
return (d.source.group == d.target.group) ? 50 : 100;
})
.nodes(graph.nodes)
.links(graph.links)
.start();
drawLinks(graph.links);
drawNodes(graph.nodes);
// add ability to drag and update layout
// https://github.com/mbostock/d3/wiki/Force-Layout#wiki-drag
d3.selectAll(".node").call(layout.drag);
// https://github.com/mbostock/d3/wiki/Force-Layout#wiki-on
layout.on("tick", function() {
d3.selectAll(".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;
});
d3.selectAll(".node")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
}
// Draws nodes on plot
function drawNodes(nodes) {
// used to assign nodes color by group
var color = d3.scale.category20();
// https://github.com/mbostock/d3/wiki/Force-Layout#wiki-nodes
d3.select("#plot").selectAll(".node")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("id", function(d, i) {
return d.name;
})
.attr("cx", function(d, i) {
return d.x;
})
.attr("cy", function(d, i) {
return d.y;
})
.attr("r", function(d, i) {
return 4;
})
.style("fill", function(d, i) {
return color(d.group);
})
.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("dy", -r * 2)
.attr("id", "tooltip");
})
.on("mouseout", function(d, i) {
d3.select("#tooltip").remove();
});
}
// Draws edges between nodes
function drawLinks(links) {
var scale = d3.scale.linear()
.domain(d3.extent(links, function(d, i) {
return d.value;
}))
.range([1, 6]);
// https://github.com/mbostock/d3/wiki/Force-Layout#wiki-links
d3.select("#plot").selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class", "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;
})
.style("stroke-width", function(d, i) {
return scale(d.value) + "px";
})
.style("stroke-dasharray", function(d, i) {
return (d.value <= 1) ? "2, 2" : "none";
}).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.source.name + " -> " + d.target.name)
.attr("x", x)
.attr("y", y)
//.attr("dy", -r * 2)
.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;
}
.link {
fill: none;
stroke: #888888;
stroke-weight: 1px;
stroke-opacity: 0.5;
}
.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>
您可以对line
元素使用<title>
元素,就像链接的演示对circle
元素所做的一样。例如,
link.append("title")
.text(function(d) { return "This is my title"; });
将在演示链接中创建这样的工具提示。注意,根据规范,您应该确保title元素是父元素的第一个子元素。
还要注意,这可能不是与用户沟通的有效方式;悬停在一条线上是相当困难的,尤其是在移动的图形中。一种可能的解决方案是,在一个更大的组中使用更宽的不可见行来换行,并将title添加为该组的第一个子元素,因为title元素也可以很好地与<g>
元素一起工作。
相关文章:
- Jquery在初始页面加载时选中复选框时显示链接的代码
- 当主导航链接悬停时,在侧菜单中显示链接
- 悬停时无法单击锚标记,但其显示链接
- 如何通过mailto在电子邮件中突出显示链接
- 如何在第一次点击时突出显示链接;并在第二次单击时跟随它,除非在其他地方单击,然后重新初始化未高亮显示的状态
- 希望仅为已登录的用户显示链接,否则它显示该链接在AngularJS和NodeJS中被隐藏或禁用
- 点击提交按钮后如何显示链接
- 如何使用 JavaScript 在共享按钮中显示链接
- 如何制作一个按钮,当悬停在上面时,会滑动并显示链接 (JS)
- 有条件地以角度显示链接.js
- JavaScript 函数不显示链接地址
- 显示链接的内容
- 在UI中显示链接函数angularJs的数据
- J汤html解析样式=“;显示:无;不要显示链接
- 将逻辑与幻灯片和隐藏/显示链接起来
- 可以在我的网站的另一个网站的地址栏中显示链接吗
- 如果低于特定的浏览器宽度,请不要显示链接
- 使用javascript在if条件内显示链接
- 如何在文本框中显示链接,并让按钮将其保存到数据库中
- 当用户单击“显示链接”时,显示密码,再次单击时将其隐藏