目前我在FCC的项目
National Contiguity工作
本质上我能够弄清楚如何渲染标志精灵并连接节点及其链接.
我唯一遇到的问题是实现的是如何表现得与FCC的example类似.具体来说,我正在尝试让节点像示例中那样排斥边界.
但是,我的行为并不那样(事实上,它是非常集群的,但我不确切知道d3.js Force Documents V4中我应该研究哪些属性).相反,似乎虽然节点和链接在边界附近停止,但它在那个点停止
const width = w - (margin.left + margin.right); const height = h - (margin.top + margin.bottom); let flagNodes = d3.select("#canvas") .append("div") .classed("flag-nodes",true) let svg = d3.select("#canvas") .append("svg") .attr("id","chart") .attr("width",w) .attr("height",h) let chart = svg.append("g") .classed("display",true) .attr("transform","translate(" + margin.left + "," + margin.top + ")"); let simulation = d3.forceSimulation() .force("link",d3.forceLink().id(function(d,i) { return i; })) .force("charge",d3.forceManyBody().strength(-60).distanceMax(50).distanceMin(5)) .force("center",d3.forceCenter(width/2,height/2)) .force("collide",d3.forceCollide().radius(35)) // .force("centering",d3.forceCenter(,height)) // .force("position",d3.forceX(0).strength(.01)) // .force("position",d3.forceY(-18)) let link = chart.append("g") .classed("links",true) .selectAll("line") .data(data.links) .enter() .append("line") simulation .nodes(data.nodes) .on("tick",ticked); simulation .force("link") .links(data.links); let node = flagNodes.selectAll(".flag-nodes") .data(data.nodes) .enter() .append("div") .attr("class",function(d,i){ return `flag flag-${d.code}` }) .call(d3.drag() .on("start",dragstarted) .on("drag",dragged) .on("end",dragended) ) node.append("title") .text(function(d) { return d.country; }); d3.forceX(width) //functions provided by D3.js // function ticked() { node .style("left",function(d) { let xlimit = Math.max(radius,Math.min(width - radius,d.x)) return (xlimit) + 'px' }) .style("top",function(d) { let ylimit = Math.max(radius,Math.min(height - radius,d.y)) return (ylimit - 2) + 'px' }); link .attr("x1",function(d) { let x1 = Math.max(radius,d.source.x)) return x1; }) .attr("y1",function(d) { let y1 = Math.max(radius,d.source.y)) return y1 }) .attr("x2",function(d) { let x2 = Math.max(radius,d.target.x)) return x2; }) .attr("y2",function(d) { let y2 = Math.max(radius,d.target.y)) return y2 }); } 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; }
解决方法
在每个tick上,在模拟节点上运行此函数:
fixBounds() { const graphNodes = this.forceSimulation.nodes(); graphNodes.forEach((node) => { if (node.x - this.nodeRadius < 0) { node.x = this.nodeRadius; node.vx = 0; } if (node.y - this.nodeRadius < 0) { node.y = this.nodeRadius; node.vy = 0; } if (this.width && node.x + this.nodeRadius > this.width) { node.x = this.width - this.nodeRadius; node.vx = 0; } if (this.height && node.y + this.nodeRadius > this.height) { node.y = this.height - this.nodeRadius; node.yx = 0; } }) }
这将导致节点卡在边界上,节点之间的力将使它们远离边界.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。