D3.js 如何控制d3节点的坐标

D3.js 如何控制d3节点的坐标,d3.js,force-layout,D3.js,Force Layout,我已经创建了一个D3Force布局,它运行得非常好。现在,我将向图表中添加一组数据。我希望我能控制新节点的中心。例如,假设中心是(100100),我希望新节点作为一个整体布置成[(50,50)到(150150)]这样的矩形区域 var width = 500, height = 500; var nodes = [{id:0, n:'Tom'}, {id:1, n:'Join'}, {id:2, n:'John'}, {id:3, n:'Bob'}, {id:4, n:'4'}, {i

我已经创建了一个D3Force布局,它运行得非常好。现在,我将向图表中添加一组数据。我希望我能控制新节点的中心。例如,假设中心是(100100),我希望新节点作为一个整体布置成[(50,50)到(150150)]这样的矩形区域

var width = 500,
    height = 500;

var nodes = [{id:0, n:'Tom'}, {id:1, n:'Join'}, {id:2, n:'John'}, {id:3, n:'Bob'}, {id:4, n:'4'}, {id:5, n:'5'}, {id:6, n:'6'}];
var links = [{source:0,target:1},{source:0,target:2},{source:0,target:3},{source:0,target:4},{source:0,target:5},{source:1,target:5},{source:1,target:6}];

// init force 
var force = d3.layout.force()
    .charge(-120)
    .linkDistance(120)
    .size([width, height]);
// init svg 
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height); 
// set tick function
force.on("tick", function () {
    d3.selectAll(".link").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;
    });

    // controll the coordinates here
    d3.selectAll(".node").attr("transform", function(d){
            if(d.flag == 1){
          d.x = Math.max(50, Math.min(150, d.x));
          d.y = Math.max(50, Math.min(150, d.y));
        }
            return "translate("+d.x+","+d.y+")";
    });



}).on('end', function(){
        svg.selectAll(".node").each(function(d){d.fixed=true;});
});




function setData(ns, ls){
  var update = svg.selectAll(".link").data(ls);
  update.enter().append("line")
      .attr("class", "link")
      .style("stroke-width", 1);
  update.exit().remove();

  update = svg.selectAll(".node").data(ns);
  update.enter().append("g")
      .attr("class", "node")
      .attr("id", function(d){return d.id})
      .call(force.drag)
      .call(function(p){
          p.append("image")
              .attr("class", "nodeimage")
              .attr("width", "30px")
              .attr("height", "30px")
              .attr("x", "-15px")
              .attr("y", "-15px");
          p.append("text")
              .attr("class", "nodetext")
              .attr("dx", "-10px")
              .attr("dy", "20px")
              .style("font-size", "15px")
              .text(function(d){return d.n});
      });
  update.exit().remove();
  update.selectAll(".nodeimage") 
        .each(function() {
         d3.select(this).datum(d3.select(this.parentNode).datum());
        }) 
              .attr("xlink:href", function(d){
                var img;
            if(d.flag == 1){
                img = "http://www.gravatar.com/avatar/1eccef322f0beef11e0e47ed7963189b/?default=&s=80"
            }else{
                img = "http://www.gravatar.com/avatar/a1338368fe0b4f3d301398a79c171987/?default=&s=80";
            }
            return img;
              });
  force.nodes(ns)
      .links(ls)
      .start();
}
//init 
setData(nodes, links);
setTimeout(function(){
        //generate new data and merge to old data
        nodes = nodes.concat(generateNewData());
        setData(nodes, links);
    //how do i control the coordinate of new nodes?
}, 3000);


function generateNewData(){
        var ns = [];
        for(var i = 0; i < 10; i++){
            ns.push({id:i+100,n:'n'+i,flag:1});
    }
    return ns;
}

var宽度=500,
高度=500;
var节点=[{id:0,n:'Tom'},{id:1,n:'Join'},{id:2,n:'John'},{id:3,n:'Bob'},{id:4,n:'4'},{id:5,n:'5'},{id:6,n:'6'}];
var links=[{source:0,target:1},{source:0,target:2},{source:0,target:3},{source:0,target:4},{source:0,target:5},{source:1,target:5},{source:1,target:6}];
//初始力
var-force=d3.layout.force()
。收费(-120)
.linkDistance(120)
.尺寸([宽度、高度]);
//初始化svg
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
//设置勾号功能
强制打开(“勾号”,函数(){
d3.选择全部(“.link”).attr(“x1”,函数(d){
返回d.source.x;
})
.attr(“y1”,函数(d){
返回d.source.y;
})
.attr(“x2”,函数(d){
返回d.target.x;
})
.attr(“y2”,功能(d){
返回d.target.y;
});
//控制这里的坐标
d3.选择全部(“.node”).attr(“转换”,函数(d){
如果(d.flag==1){
d、 x=数学最大值(50,数学最小值(150,d.x));
d、 y=数学最大值(50,数学最小值(150,d.y));
}
返回“translate”(“+d.x+”,“+d.y+”);
});
}).on('end',function(){
selectAll(“.node”).each(函数(d){d.fixed=true;});
});
函数设置数据(ns、ls){
var update=svg.selectAll(“.link”).data(ls);
update.enter().append(“行”)
.attr(“类”、“链接”)
.样式(“笔划宽度”,1);
update.exit().remove();
update=svg.selectAll(“.node”).data(ns);
update.enter().append(“g”)
.attr(“类”、“节点”)
.attr(“id”,函数(d){return d.id})
.call(强制拖动)
.调用(函数(p){
p、 附加(“图像”)
.attr(“类”、“节点年龄”)
.attr(“宽度”,“30px”)
.attr(“高度”,“30px”)
.attr(“x”,“-15px”)
.attr(“y”,“-15px”);
p、 附加(“文本”)
.attr(“类”、“节点文本”)
.attr(“dx”、“-10px”)
.attr(“dy”,“20px”)
.style(“字体大小”,“15px”)
.text(函数(d){return d.n});
});
update.exit().remove();
update.selectAll(“.nodeimage”)
.each(函数({
d3.select(this.datum)(d3.select(this.parentNode.datum());
}) 
.attr(“xlink:href”,函数(d){
var-img;
如果(d.flag==1){
img=”http://www.gravatar.com/avatar/1eccef322f0beef11e0e47ed7963189b/?default=&s=80"
}否则{
img=”http://www.gravatar.com/avatar/a1338368fe0b4f3d301398a79c171987/?default=&s=80";
}
返回img;
});
强制节点(ns)
.链接(ls)
.start();
}
//初始化
setData(节点、链接);
setTimeout(函数(){
//生成新数据并合并到旧数据
nodes=nodes.concat(generateNewData());
setData(节点、链接);
//如何控制新节点的坐标?
}, 3000);
函数generateNewData(){
var ns=[];
对于(变量i=0;i<10;i++){
推送({id:i+100,n:'n'+i,标志:1});
}
返回ns;
}
下面是我的JSFIDLE演示:

最新的演示显示,节点可以显示在矩形中,但是,它们的坐标是相同的。我希望这是一个可用的部队布局。

var宽度=500,
高度=500;
var节点=[{id:0,n:'Tom'},{id:1,n:'Join'},{id:2,n:'John'},{id:3,n:'Bob'},{id:4,n:'4'},{id:5,n:'5'},{id:6,n:'6'}];
var links=[{source:0,target:1},{source:0,target:2},{source:0,target:3},{source:0,target:4},{source:0,target:5},{source:1,target:5},{source:1,target:6}];
//初始力
var-force=d3.layout.force()
。收费(-500)
.linkDistance(120)
.重力(0.1)
.尺寸([宽度、高度]);
//初始化svg
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
//设置勾号功能
强制打开(“勾号”,函数(){
d3.选择全部(“.link”).attr(“x1”,函数(d){
返回d.source.x;
})
.attr(“y1”,函数(d){
返回d.source.y;
})
.attr(“x2”,函数(d){
返回d.target.x;
})
.attr(“y2”,功能(d){
返回d.target.y;
});
//控制这里的坐标
d3.选择全部(“.node”).attr(“转换”,函数(d){
如果(d.flag==1){
d、 x=数学最大值(50,数学最小值(150,d.x));
d、 y=数学最大值(50,数学最小值(150,d.y));
}
返回“translate”(“+d.x+”,“+d.y+”);
});
}).on('end',function(){
selectAll(“.node”).each(函数(d){d.fixed=true;});
});
函数设置数据(ns、ls){
var update=svg.selectAll(“.link”).data(ls);
update.enter().append(“行”)
.attr(“类”、“链接”)
.样式(“笔划宽度”,1);
update.exit().remove();
update=svg.selectAll(“.node”).data(ns);
update.enter().append(“g”)
.attr(“类”、“节点”)
.attr(“id”,函数(d){return d.id})
.call(强制拖动)
.调用(函数(p){
p、 附加(“图像”)
.attr(“类”、“节点年龄”)
.attr(“宽度”,“30px”)
.attr(“高度”,“30px”)
.attr(“x”,“-15px”)
.attr(“y”,“-15px”);
p、 附加(“文本”)
.attr(“类”、“节点文本”)
.attr(“dx”、“-10px”)
.attr(“dy”,“20px”)
.style(“字体大小”,“15px”)
.text(函数(d){return d.n});
});
update.exit().remove();
update.selectAll(“.nodeimage”)
.each(函数({
d3.select(this.datum)(d3.select(this.parentNode.datum());