Javascript d3.js将节点和标签一起移动
在我们的项目中,我想在单击addnode按钮时动态添加cicrles,并用箭头链接这些圆。但是当我链接圆圈时,圆圈的标签不会与圆圈一起移动。代码如下 JS Fiddle链接: 我怎样才能解决这个问题 提前谢谢Javascript d3.js将节点和标签一起移动,javascript,graph,svg,d3.js,Javascript,Graph,Svg,D3.js,在我们的项目中,我想在单击addnode按钮时动态添加cicrles,并用箭头链接这些圆。但是当我链接圆圈时,圆圈的标签不会与圆圈一起移动。代码如下 JS Fiddle链接: 我怎样才能解决这个问题 提前谢谢 <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich" template="layout/template.xhtml">
<ui:define name="body">
<a4j:commandButton value="Add Node" onclick="mousedown();">
</a4j:commandButton>
<div id="activationGraphDiv" style="width: 960px; height: 500px">
</div>
<rich:popupPanel id="addnode" width="100" height="100">
<h:form>
<h:outputLabel value="http://add.mode.deneme#relation" />
<a4j:commandButton value="OK"
onclick="#{rich:component('addnode')}.hide()">
</a4j:commandButton>
</h:form>
</rich:popupPanel>
<style type="text/css">
rect {
fill: none;
pointer-events: all;
}
.node {
fill: white;
stroke: pink;
stroke-width: 2;
color: black;
}
.cursor {
fill: none;
pointer-events: none;
}
.link {
stroke: #999;
}
path,line {
stroke: silver;
stroke-width: 2;
fill: none;
}
</style>
<script src="jquery.pack.js"></script>
<script type="text/javascript">
var width = 960,
height = 500;
var sourceNode,targetNode;
var fill = d3.scale.category20();
var force = d3.layout.force()
.size([width, height])
.gravity(.05)
.charge(-450)
.linkDistance(200)
.on("tick", tick);
var svg = d3.select("#activationGraphDiv").append("svg")
.attr("width", width)
.attr("height", height)
.on("mousemove", mousemove);
svg.append("rect")
.attr("width", width)
.attr("height", height);
// Draw Lines
var container = $('#activationGraphDiv');
var line = d3.svg.line()
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; })
.interpolate('linear');
svg
.append('svg:path')
.style('stroke-width', 1)
.style('stroke', 'silver')
.style('fill', 'rgba(120, 220, 54, 0.2)');
var lineData = [];
var redrawLine = function() {
var svgLines = svg.selectAll('path.my-lines')
.data(lineData)
.remove();
svgLines.enter()
.append('path')
.attr('d', line(lineData))
.attr('class', 'my-lines');
svgLines.exit()
.remove();
};
var mouseIsDown = false;
container.on('mousemove', function(e) {
if (mouseIsDown && sourceNode!=null) {
lineData[1] = [e.offsetX, e.offsetY];
redrawLine();
}})
.on('mouseup',function(){
sourceNode=null;
targetNode=null;
mouseIsDown=false;
svg.selectAll('path.my-lines')
.data(lineData)
.remove();
});
var nodes = force.nodes(),
links = force.links(),
node=svg.selectAll(".node"),
link = svg.selectAll(".link"),
text=svg.selectAll(".nodetext");
var cursor = svg.append("circle")
.attr("r", 0)
.attr("class", "cursor");
restart();
function mousemove() {
cursor.attr("transform", "translate(" + d3.mouse(this) + ")");
}
var i=0;
function mousedown() {
//x coordinate of node..
var x=document.getElementById("activationGraphDiv").offsetLeft;
//y coordinate of node..
var y=document.getElementById("activationGraphDiv").offsetTop;
var node = {x:x, y: y, name: i},
n = nodes.push(node);
i++;
console.log("node name: "+node.name);
restart();
sourceNode=null
targetNode=null;
mouseIsDown=false;
}
function tick() {
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; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
text.attr("x", function(d) {return d.x; })
.attr("y", function(d) { return d.y; });
}
svg.append("svg:defs").selectAll("marker")
.data(["arrow"])
.enter().append("svg:marker")
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 10)
.attr("refY", 0)
.attr("markerWidth", 10)
.attr("markerHeight", 10)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
function restart() {
node = node.data(nodes);
node.enter().insert("circle")
.attr("class", "node")
.attr("id",function(d){return d.name;})
.attr("r", 15);
//Insert text to node..
text=svg.selectAll(".nodetext")
.data(nodes)
.enter()
.append("text")
.attr("class","nodetext")
.text(function(d){return d.name;})
.attr("dx", 13)
.attr("dy", ".35em");
d3.selectAll(".node").on("mousedown",function(d){
if(sourceNode==null){
mouseIsDown = true;
lineData[0] = [d3.mouse(this)[0], d3.mouse(this)[1]];
redrawLine();
sourceNode=d.index;
console.log("Source node: "+d.name);
}
})
.on("mouseup",function(d){
if(targetNode==null && sourceNode!=null && mouseIsDown){
targetNode=d.index;
links.push({source: sourceNode, target: targetNode});
lineData[1] = [d3.mouse(this)[0], d3.mouse(this)[1]];
redrawLine();
console.log("Target node: "+d.name);
sourceNode=null;
targetNode=null;
mouseIsDown = false;
svg.selectAll('path.my-lines')
.data(lineData)
.remove();
restart();
}
});
link = link.data(links);
link.enter().insert("line")
.attr("class", "link");
link.attr("marker-end", "url(#arrow)");
force.start();
}
</script>
</ui:define>
</ui:composition>
直肠{
填充:无;
指针事件:全部;
}
.节点{
填充物:白色;
笔画:粉红色;
笔画宽度:2;
颜色:黑色;
}
.光标{
填充:无;
指针事件:无;
}
.链接{
行程:#999;
}
路线{
笔画:银色;
笔画宽度:2;
填充:无;
}
可变宽度=960,
高度=500;
var sourceNode,targetNode;
var fill=d3.scale.category20();
var-force=d3.layout.force()
.尺寸([宽度、高度])
.重力(.05)
。收费(-450)
.linkDistance(200)
.在(“滴答”,滴答)上;
var svg=d3.选择(#activationGraphDiv”).append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.on(“mousemove”,mousemove);
svg.append(“rect”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
//划线
变量容器=$('activationGraphDiv');
var line=d3.svg.line()
.x(函数(d){返回d[0];})
.y(函数(d){返回d[1];})
.插入(“线性”);
svg
.append('svg:path')
.style('笔划宽度',1)
.style('stroke','silver')
.样式(“填充”、“rgba(120、220、54、0.2)”;
var lineData=[];
var redrawLine=函数(){
var svgLines=svg.selectAll('path.my line'))
.数据(线条数据)
.remove();
svgLines.enter()
.append('路径')
.attr('d',行(行数据))
.attr(“类”、“我的行”);
svgLines.exit()
.remove();
};
var mouseIsDown=false;
container.on('mousemove',函数(e){
if(mouseIsDown&;sourceNode!=null){
lineData[1]=[e.offsetX,e.offsetY];
重画线();
}})
.on('mouseup',function(){
sourceNode=null;
targetNode=null;
mouseIsDown=false;
selectAll('path.my line')
.数据(线条数据)
.remove();
});
var nodes=force.nodes(),
links=force.links(),
node=svg.selectAll(“.node”),
link=svg.selectAll(“.link”),
text=svg.selectAll(“.nodetext”);
var cursor=svg.append(“圆”)
.attr(“r”,0)
.attr(“类别”、“光标”);
重启();
函数mousemove(){
cursor.attr(“transform”、“translate”(+d3.mouse(this)+”);
}
var i=0;
函数mousedown(){
//节点的x坐标。。
var x=document.getElementById(“activationGraphDiv”).offsetLeft;
//节点的y坐标。。
变量y=document.getElementById(“activationGraphDiv”).offsetTop;
var node={x:x,y:y,name:i},
n=节点。推送(节点);
i++;
日志(“节点名称:”+node.name);
重启();
sourceNode=null
targetNode=null;
mouseIsDown=false;
}
函数tick(){
attr(“x1”,函数(d){返回d.source.x;})
.attr(“y1”,函数(d){返回d.source.y;})
.attr(“x2”,函数(d){返回d.target.x;})
.attr(“y2”,函数(d){返回d.target.y;});
attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;});
attr(“x”,函数(d){return d.x;})
.attr(“y”,函数(d){返回d.y;});
}
追加(“svg:defs”)。选择全部(“标记”)
.数据([“箭头”])
.enter().append(“svg:marker”)
.attr(“id”,字符串)
.attr(“视图框”,“0-5 10”)
.attr(“参考文献”,第10页)
.attr(“参考文献”,0)
.attr(“markerWidth”,10)
.attr(“markerHeight”,10)
.attr(“方向”、“自动”)
.append(“svg:path”)
.attr(“d”,“M0,-5L10,0L0,5”);
函数重新启动(){
节点=节点。数据(节点);
node.enter().insert(“圆”)
.attr(“类”、“节点”)
.attr(“id”,函数(d){返回d.name;})
.attr(“r”,15);
//将文本插入到节点。。
text=svg.selectAll(“.nodetext”)
.数据(节点)
.输入()
.append(“文本”)
.attr(“类”、“节点文本”)
.text(函数(d){返回d.name;})
.attr(“dx”,13)
.attr(“dy”,“.35em”);
d3.选择所有(“.node”)。在(“鼠标向下”,函数(d){
if(sourceNode==null){
mouseIsDown=true;
lineData[0]=[d3.鼠标(此)[0],d3.鼠标(此)[1];
重画线();
sourceNode=d.index;
console.log(“源节点:+d.name”);
}
})
.on(“mouseup”,函数(d){
if(targetNode==null&;sourceNode!=null&;mouseIsDown){
targetNode=d.index;
push({source:sourceNode,target:targetNode});
lineData[1]=[d3.鼠标(此)[0],d3.鼠标(此)[1];
重画线();
console.log(“目标节点:+d.name”);
sourceNode=null;
targetNode=null;
mouseIsDown=false;
selectAll('path.my line')
.数据(线条数据)
.remove();
重启();
}
});
链接=链接数据(链接);
link.enter().insert(“行”)
.attr(“类”、“链接”);
link.attr(“标记结束”,“url(#箭头)”);
force.start();
}
规范的解决方案是将文本和圆圈分组。您不必单独移动文本和节点,而只需变换组即可
因此:
node.attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
});
text.attr("x", function (d) {
return d.x;
})
.attr("y", function (d) {
return d.y;
});
变成这样:
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
请查看此处的示例:
请允许我为您的代码创建一个JSFIDLE对不起,我忘了这个。这是JSFiddle链接