gpt4 book ai didi

javascript - d3.js 一起移动节点和标签

转载 作者:行者123 更新时间:2023-11-29 22:11:55 25 4
gpt4 key购买 nike

在我们的项目中,我想在单击添加节点按钮时动态添加圆圈,并用箭头链接这些圆圈。但是当我链接圆圈标签时,圆圈标签不会与圆圈一起移动。代码如下。

JS Fiddle 链接:http://jsfiddle.net/pinargocebe/kEhes/3/

我该如何解决这个问题?

提前致谢..

 <!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>

最佳答案

规范的解决方案是将文本和圆圈放在一个组中。您无需 force.tick() 单独移动文本和节点,只需转换组即可。

所以这样:

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 + ")"; });

查看示例:

http://bl.ocks.org/mbostock/950642

关于javascript - d3.js 一起移动节点和标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17740379/

25 4 0