Javascript d3.js将节点和标签一起移动

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:

在我们的项目中,我想在单击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: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 &amp;&amp; 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 &amp;&amp; sourceNode!=null &amp;&amp; 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链接