gpt4 book ai didi

javascript - 在 d3.js 中控制力导向布局上的箭头尺寸

转载 作者:行者123 更新时间:2023-12-01 03:30:34 25 4
gpt4 key购买 nike

我已经制作了一个图表,现​​在我想添加定向链接。

我有一个问题,因为我想要这样的功能:当我将鼠标移到链接上时,它会变大,当我单击节点时,它会变大,这两个函数会弄乱链接上的箭头。

我已经尝试了在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com