作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经制作了一个图表,现在我想添加定向链接。
我有一个问题,因为我想要这样的功能:当我将鼠标移到链接上时,它会变大,当我单击节点时,它会变大,这两个函数会弄乱链接上的箭头。
我已经尝试了在 stackoverflow 上找到的许多解决方案,但没有任何对我有用......有人可以帮助我吗?谢谢
这是我的代码:
<!DOCTYPE html>
<meta charset="utf-8">
<title>Modifying a force layout v4</title>
<style>
.link {
stroke: #3B3B3B;
/*stroke-width: 1px;*/
}
.node {
stroke: #000;
stroke-width: 1.5px;
}
.svg {
border:3px solid black;
border-radius:12px;
margin:auto;
}
#arrow {
fill:green;
}
</style>
<body>
Node:
<div id="log"></div>
Link:
<div id="log2"></div>
<script src="//d3js.org/d3.v4.js"></script>
<script>
var width = 960,
height = 500;
radius = 17;
var expnsed = false;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var nodes = [],
links = [];
var charge = d3.forceManyBody().strength(-150);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(130).strength(.7))
.force("charge", charge)
// use forceX and forceY instead to change the relative positioning
// .force("centering", d3.forceCenter(width/2, height/2))
.force("x", d3.forceX(width/2))
.force("y", d3.forceY(height/2))
.on("tick", tick);
var svg = d3.select("body").append("svg").attr("class","svg")
.attr("width", width)
.attr("height", height);
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", 0)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
//.attr("fill","red")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
var url = "https://api.myjson.com/bins/lj6ob";
d3.json(url, function(error, graph) {
if (error) throw error;
nodes = graph.nodes;
links=graph.links;
console.log("graph.links.length: "+links.length)
for (var i = 0; i < links.length; i++){
links[i].source = find(links[i].source);
links[i].target = find(links[i].target);
}
console.log("Link source: " + links[0].target)
start();
})
function find(name){
for(var i = 0; i < nodes.length; i++){
if (name == nodes[i].id){
console.log("name: " + name)
console.log("id: " + nodes[i].id)
return i;
}
}
}
function start() {
var nodeElements = svg.selectAll(".node").data(nodes, function(d){return d.id});
var linkElements = svg.selectAll(".line").data(links).attr("class","links");
//console.log(nodes)
nodeElements.enter().append("circle").attr("class", function(d) {return "node " + d.index; }).attr("r", 17).attr("fill", function(d) { return color(d.group); });
linkElements.enter().insert("line", ".node").attr("class", "link").attr("stroke-width", function(d) { return Math.sqrt(d.value)*2;});
d3.selectAll("line").attr("marker-end", "url(#arrow)");
nodeElements.exit().remove();
linkElements.exit().remove();
simulation.nodes(nodes)
simulation.force("link").links(links)
// NOTE: Very important to call both alphaTarget AND restart in conjunction
// Restart by itself will reset alpha (cooling of simulation)
// but won't reset the velocities of the nodes (inertia)
//remove alpha for slow incoming!!
//.alpha(1)
simulation.alpha(1).restart();
}
function tick() {
var nodeElements = svg.selectAll(".node");
var linkElements = svg.selectAll(".link");
linkElements.append("title")
.text(function(d) { return "value link: " + d.value; });
linkElements.on("mouseover", function(d) {
var g = d3.select(this); // The node
document.getElementById('log2').innerHTML = '<br> '+d.value;
g.attr("stroke-width", function(d) { return Math.sqrt(d.value)*4; })
});
linkElements.on("mouseout", function(d) {
var g = d3.select(this); // The node
g.attr("stroke-width", function(d) { return Math.sqrt(d.value)*2; })
});
nodeElements.append("title")
.text(function(d) {
return "node name: "+d.id + ", node group: "+d.group;
});
nodeElements.on("mouseout", function(d) {
var g = d3.select(this); // The node
g.attr("fill", function(d) { return color(d.group); })
})
.on("mouseover", function(d) {
document.getElementById('log').innerHTML = '<br> '+d.id;
var g = d3.select(this); // The node
g.attr("fill", "red")
});
nodeElements.on("click",click);
nodeElements.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
/*nodeElements.attr("cx", function(d,i) {return d.x; })
.attr("cy", function(d) { return d.y; })*/
nodeElements.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
linkElements
.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;});
}
function click(d) {
d3.select(this).attr("r",
function(d){if (d3.select(this).attr("r")==17) {radius = 23;return "23"}else{radius = 17; return "17"}}
);
//expand();
var E = "E";
if(d.id == E && expand){
expand=false;
//expand_2();
}
};
function expand(){
console.log("expand")
b = createNode("A")
nodes.push(b);
start();
}
function expand_2(){
d3.json("nodes_2.json", function(error, graph) {
for(var i = 0; i < graph.nodes.length; i++){
var n = graph.nodes[i];
nodes.push(n);
}
for(var i = 0; i < graph.links.length; i++){
graph.links[i].source = find(graph.links[i].source)
graph.links[i].target = find(graph.links[i].target)
var l = graph.links[i];
links.push(l);
}
start();
})
}
function zoomed() {
g.attr("transform", d3.event.transform);
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function createNode(id) {
return {id: id, x: width/2, y:height/2}
}
</script>
最佳答案
如果定义markerUnits="userSpaceOnUse"
,则可以为箭头指定固定大小。要重新创建当前尺寸:
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", 0)
.attr("markerUnits", "userSpaceOnUse")
.attr("markerWidth", 30)
.attr("markerHeight", 30)
.attr("orient", "auto")
如果您想在悬停时调整标记的大小,最好的解决方案可能是使用更大的第二个标记元素 arrow-hover
并通过 CSS 临时交换:
line {
marker-end: url(#arrow);
}
line:hover {
marker-end: url(#arrow-hover);
}
关于javascript - 在 d3.js 中控制力导向布局上的箭头尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44563125/
有没有办法根据存储的 res 值在 list 中定义屏幕方向? 例如: port * resource qualifier. */ public static final int ORIENTATI
我是一名优秀的程序员,十分优秀!