单节点图对forceCenter没有反应? [英] Single node graph not reacting to forceCenter?

查看:173
本文介绍了单节点图对forceCenter没有反应?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从一个节点开始一个图形项目.当我将其拖动到某处时,我希望它可以平滑地返回到svg的中心,但相反,它会毛刺回到中心.

I'm starting a graph project with a single node. When I'm dragging it somewhere, I expect it to smoothly go back to the center of the svg but instead of that, it glitches back to the center.

var simulation = d3.forceSimulation()
  .force("center", d3.forceCenter(svgWidth/2, svgHeight/2));

Codepen完整示例

我认为我可能没有正确配置forceCenter(),或者因为没有其他节点,所以没有其他主体可以与之交互,所以这就是D3的工作方式.

I think I might not be configuring forceCenter() properly or maybe since there is no other node, there is no other body to interact with so this is how D3 would work.

推荐答案

...也许因为没有其他节点,所以没有其他物体可以与之交互,所以这就是D3的工作方式.

...maybe since there is no other node, there is no other body to interact with so this is how D3 would work.

是的,您的直觉在这里是(部分)正确的,这种力模拟没有错.我认为这里的问题来自对forceCenter的目的的误解:forceCenter不能使节点平稳地到达指定位置(更多内容请参见下文).实际上,如果在该模拟中有另一个节点,则可以看到,通过拖动一个节点,另一个节点也将移动,因此质心保持在同一位置.

Yes, your intuition is (partially) correct here, there is nothing wrong with this force simulation. I reckon that the problem here comes from a misunderstanding of the purpose of forceCenter: forceCenter does not make the node going smoothly to the specified position (more on that below). Actually, if you had another node in that simulation, you'd see that, by dragging one node, the other one would also move, so the center of mass stays at the same place.

话虽如此,您可以看到它可以按预期运行-—也就是说,节点会平滑地回到中心位置-mdash;如果您使用的是forceXforceY ...

That being said, you can see that it works as you expect — that is, the node smoothly going back to the center — if, instead of forceCenter, you used forceX and forceY...

var simulation = d3.forceSimulation()
    .force("x", d3.forceX(svgWidth / 2))
    .force("y", d3.forceY(svgHeight / 2));

...无需更改任何alphaalphaTargetvelocityDecay等...

... without changing any alpha, alphaTarget, velocityDecay etc...

这是仅具有此更改的代码:

Here is the code with that change only:

////////////////////////////////////////////////////
// SVG setup
////////////////////////////////////////////////////
var svgWidth = 400,
    svgHeight = 400;

var svgRef = d3.select("body").append("svg")
  .attr("width",svgWidth)
  .attr("height",svgHeight);

svgRef.append("rect")
  .attr("width", svgWidth)
  .attr("height", svgHeight);

////////////////////////////////////////////////////
// Data
////////////////////////////////////////////////////
var nodes_data = [{id: "0"}];
var links_data = [];

////////////////////////////////////////////////////
// Links and nodes setup
////////////////////////////////////////////////////
var linksRef = svgRef.selectAll(".link")			
.data(links_data).enter()
.append("line")
.attr("class", "link");

var nodesRef = svgRef
.selectAll(".node")
.data(nodes_data).enter()
.append("g").attr("class", "node")
.append("circle")
  .attr("r", 10)
.call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

////////////////////////////////////////////////////
// Simulation setup
////////////////////////////////////////////////////
var simulation = d3.forceSimulation()
  .force("x", d3.forceX(svgWidth / 2))
.force("y", d3.forceY(svgHeight / 2));

simulation.nodes(nodes_data).on("tick", ticked);
simulation.force("link").links(links_data);

function ticked() {
  nodesRef.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")";})

  linksRef.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; });
}

////////////////////////////////////////////////////
// Dragging
////////////////////////////////////////////////////
function dragstarted (d) {
  if (!d3.event.active) simulation.alphaTarget(1).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;
}

.link {
	  stroke: #000;
	  stroke-width: 2px;
	}

	.node {
	  fill: #CCC;
	  stroke: #000;
	  stroke-width: 1px;
	}

	rect {
	  fill: none;
	  stroke: #000;
	  stroke-width: 2px;
	  pointer-events: all;
	}

<script src="https://d3js.org/d3.v5.min.js"></script>

这篇关于单节点图对forceCenter没有反应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆