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