Javascript 与D3.js的交互作用力

Javascript 与D3.js的交互作用力,javascript,d3.js,physics,gravity,force-layout,Javascript,D3.js,Physics,Gravity,Force Layout,我试图“模拟”粒子向“焦点”移动时的引力。实际上,我正在尝试修改以下代码,以便粒子在到达蓝色节点的过程中被橙色节点稍微偏离路线。我的问题是,我在使用D3.js强制导向布局的概念化上遇到了困难。我意识到这是一个相当模糊的问题,但任何帮助都是非常感谢的!图片和代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=

我试图“模拟”粒子向“焦点”移动时的引力。实际上,我正在尝试修改以下代码,以便粒子在到达蓝色节点的过程中被橙色节点稍微偏离路线。我的问题是,我在使用D3.js强制导向布局的概念化上遇到了困难。我意识到这是一个相当模糊的问题,但任何帮助都是非常感谢的!图片和代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <title>Force Layouts - Quantitative Foci</title>
    <script type="text/javascript" src="http://d3js.org/d3.v2.min.js?2.8.1"></script>
    <style type="text/css">

circle {
  stroke: #fff;
}

svg {
  fill: #fff;
  stroke: #000;
}

    </style>
  </head>
  <body>
    <div id="body">
      <div id="chart"></div>
    </div>
    <script type="text/javascript">

var w = 1280,
    h = 800,
    color = d3.scale.category10();

var force = d3.layout.force()
    .gravity(0)
    .charge(-5)
    .linkStrength(0)
    .size([w, h]);

var links = force.links(),
    nodes = force.nodes(),
    centers = [
      {type: 0, x: 3 * w / 6, y: 2 * h / 6, fixed: true},
      {type: 1, x: 4 * w / 6, y: 4 * h / 6, fixed: true}
    ];

var svg = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

svg.append("svg:rect")
    .attr("width", w)
    .attr("height", h);

svg.selectAll("circle")
    .data(centers)
  .enter().append("svg:circle")
    .attr("r", 12)
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .style("fill", fill)
    .call(force.drag);

force.on("tick", function(e) {
  var k = e.alpha * .1;
  nodes.forEach(function(node) {
    var center = centers[node.type];
    node.x += (center.x - node.x) * k;
    node.y += (center.y - node.y) * k;
  });

  svg.selectAll("circle")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });

  svg.selectAll("line")
      .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; });
});

var p0;

svg.on("mousemove", function() {
  var p1 = d3.svg.mouse(this),
      a = {type: 0, x: p1[0], y: p1[1], px: (p0 || (p0 = p1))[0], py: p0[1]},
      b = {type: 1, x: centers[1].x, y: centers[1].y, fixed:true},
      link = {source: a, target: b};

  p0 = p1;

  svg.selectAll()
      .data([a, b])
    .enter().append("svg:circle")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r", 4.5)
      .style("fill", fill)
    .transition()
      .delay(3000)
      .attr("r", 1e-6)
      .remove();

  svg.insert("svg:line", "circle")
      .data([link])
    .transition()
      .delay(3000)
      .each("end", function() {
        nodes.splice(nodes.indexOf(a), 1);
        nodes.splice(nodes.indexOf(b), 1);
        links.splice(links.indexOf(link), 1);
      })
      .remove();

  nodes.push(a, b);
  links.push(link);
  force.start();
});

function fill(d) {
  return color(d.type);
}

    </script>
  </body>
</html>


部队布局-定量重点
圈{
冲程:#fff;
}
svg{
填充:#fff;
行程:#000;
}
var w=1280,
h=800,
颜色=d3.scale.category10();
var-force=d3.layout.force()
.重力(0)
。收费(-5)
.linkStrength(0)
.尺寸([w,h]);
var links=force.links(),
nodes=force.nodes(),
中心=[
{type:0,x:3*w/6,y:2*h/6,fixed:true},
{type:1,x:4*w/6,y:4*h/6,fixed:true}
];
var svg=d3.选择(#图表”).追加(“svg:svg”)
.attr(“宽度”,w)
.attr(“高度”,h);
append(“svg:rect”)
.attr(“宽度”,w)
.attr(“高度”,h);
svg.selectAll(“圆圈”)
.数据中心
.enter().append(“svg:circle”)
.attr(“r”,12)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;})
.样式(“填充”,填充)
.呼叫(强制拖动);
强制开启(“勾选”),功能(e){
var k=e.alpha*.1;
forEach(函数(节点){
var center=centers[node.type];
node.x+=(center.x-node.x)*k;
node.y+=(center.y-node.y)*k;
});
svg.selectAll(“圆圈”)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
svg.selectAll(“行”)
.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
});
var-p0;
on(“mousemove”,function()){
var p1=d3.svg.mouse(此),
a={type:0,x:p1[0],y:p1[1],px:(p0 | |(p0=p1))[0],py:p0[1]},
b={type:1,x:centers[1].x,y:centers[1].y,fixed:true},
link={源:a,目标:b};
p0=p1;
svg.selectAll()
.数据([a,b])
.enter().append(“svg:circle”)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;})
.attr(“r”,4.5)
.样式(“填充”,填充)
.transition()
.延迟(3000)
.attr(“r”,1e-6)
.remove();
插入(“svg:line”,“circle”)
.数据([链接])
.transition()
.延迟(3000)
.每个(“结束”,函数(){
节点.拼接(节点.索引f(a),1);
节点.拼接(节点.索引f(b),1);
链节.拼接(链节.索引of(链节),1);
})
.remove();
节点推送(a,b);
链接。推(链接);
force.start();
});
功能填充(d){
返回颜色(d型);
}
”“以前


[2] --在Lephix的提议之后。

首先,你的问题很有趣:)。
用以下代码替换force.on(“tick”,函数(e){…})。实际上,我只是在函数中添加了一个变量和10行代码。
fr表示圆形区域的半径,粒子应偏离橙色节点

var fr = 100;
force.on("tick", function(e) {
  var k = e.alpha * .1;
  nodes.forEach(function(node) {
  var center = centers[node.type];
  node.x += (center.x - node.x) * k;
  node.y += (center.y - node.y) * k;

if (node.type == 0) {
    center = centers[1];
    while (Math.abs(node.x - center.x) < fr && Math.abs(node.y - center.y) < fr) {
        if (Math.abs(node.x - center.x) >= Math.abs(node.y - center.y)) {
            node.x += (node.x - center.x)/Math.abs(node.x - center.x);
        } else {
            node.y += (node.y - center.y)/Math.abs(node.y - center.y);
        }
    }
}
});

svg.selectAll("circle")
  .attr("cx", function(d) { return d.x; })
  .attr("cy", function(d) { return d.y; });

svg.selectAll("line")
  .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; });
});
var-fr=100;
强制开启(“勾选”),功能(e){
var k=e.alpha*.1;
forEach(函数(节点){
var center=centers[node.type];
node.x+=(center.x-node.x)*k;
node.y+=(center.y-node.y)*k;
if(node.type==0){
中心=中心[1];
while(Math.abs(node.x-center.x)=Math.abs(node.y-center.y)){
node.x+=(node.x-center.x)/Math.abs(node.x-center.x);
}否则{
node.y+=(node.y-center.y)/Math.abs(node.y-center.y);
}
}
}
});
svg.selectAll(“圆圈”)
.attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
svg.selectAll(“行”)
.attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
});