这是我的图...我有矩形节点我想在节点中包含文本。 我试过了
node.append("text").text("hello");
但不起作用。我如何分组我的节点和文本。 我想在节点上添加和编辑功能。编辑文本我该怎么做?
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<title>Force Editor</title>
<!-- <script src="d3.v2.min.js"></script> -->
<script src="http://d3js.org/d3.v2.min.js"></script>
<!-- <script src="jquery-1.8.3.min.js"></script> -->
<style>
body {
font: 13px sans-serif;
position: relative;
width: auto;
height: auto;
}
.node {
fill: #000;
cursor: crosshair;
}
.node_selected {
fill: #ff7f0e;
stroke: #ff7f0e;
}
.drag_line {
stroke: #999;
stroke-width: 5;
pointer-events: none;
}
.drag_line_hidden {
stroke: #999;
stroke-width: 0;
pointer-events: none;
}
.link {
stroke: #999;
stroke-width: 5;
cursor: crosshair;
}
.link_selected {
stroke: #ff7f0e;
}
</style>
<head>
<body>
<div id="chart">
</div>
<script>
var width = 1800,
height = 800,
fill = d3.scale.ordinal().range(["#ff0000", "#2ca02c","#ff0000"]);
// mouse event vars
var selected_node = null,
selected_link = null,
mousedown_link = null,
mousedown_node = null,
mouseup_node = null;
// init svg
var outer = d3.select("#chart")
.append("svg:svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-events", "all");
var vis = outer
.append('svg:g')
.call(d3.behavior.zoom().on("zoom", rescale))
.on("dblclick.zoom", null)
.append('svg:g')
.on("mousemove", mousemove)
.on("mousedown", mousedown)
.on("mouseup", mouseup);
vis.append('svg:rect')
.attr('width', width)
.attr('height', height)
.attr('fill', 'white');
// init force layout
var force = d3.layout.force()
.size([width, height])
.nodes([{}]) // initialize with a single node
.linkDistance(250)
.charge(-1500)
.on("tick", tick)
;
// line displayed when dragging new nodes
var drag_line = vis.append("line")
.attr("class", "drag_line")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", 0);
// get layout properties
var nodes = force.nodes(),
links = force.links(),
node = vis.selectAll(".node"),
link = vis.selectAll(".link");
// add keyboard callback
d3.select(window)
.on("keydown", keydown);
redraw();
// focus on svg
// vis.node().focus();
function mousedown() {
if (!mousedown_node && !mousedown_link) {
// allow panning if nothing is selected
vis.call(d3.behavior.zoom().on("zoom"), rescale);
return;
}
}
function mousemove() {
if (!mousedown_node) return;
// update drag line
drag_line
.attr("x1", mousedown_node.x)
.attr("y1", mousedown_node.y)
.attr("x2", d3.svg.mouse(this)[0])
.attr("y2", d3.svg.mouse(this)[1]);
}
function mouseup() {
if (mousedown_node) {
// hide drag line
drag_line
.attr("class", "drag_line_hidden")
if (!mouseup_node) {
// add node
var point = d3.mouse(this),
node = {x: point[0], y: point[1]},
n = nodes.push(node);
// select new node
selected_node = node;
selected_link = null;
// add link to mousedown node
links.push({source: mousedown_node, target: node});
}
redraw();
}
// clear mouse event vars
resetMouseVars();
}
function resetMouseVars() {
mousedown_node = null;
mouseup_node = null;
mousedown_link = null;
}
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("x", function(d) { return d.x-10; })// for circle its cx
.attr("y", function(d) { return d.y-10; });//for circle its cy
}
// rescale g
function rescale() {
trans=d3.event.translate;
scale=d3.event.scale;
vis.attr("transform",
"translate(" + trans + ")"
+ " scale(" + scale + ")");
}
// redraw force layout
function redraw() {
link = link.data(links);
link.enter().insert("line", ".node")
.attr("class", "link")
.on("mousedown",
function(d) {
mousedown_link = d;
if (mousedown_link == selected_link) selected_link = null;
else selected_link = mousedown_link;
selected_node = null;
redraw();
})
link.exit().remove();
link
.classed("link_selected", function(d) { return d === selected_link; });
node = node.data(nodes);
//node.enter()//.insert("circle")
/*node.enter().insert("circle")
.attr("class","node")
.attr("r", 5)*/
var rectSize = 50;
node.enter().append("svg:rect")
.attr("class","node")
.attr("width", rectSize)
.attr("height", rectSize)
.style("fill","powderBlue")
.attr("id", "hello")
.attr("title", "hello")
.style("fixed","true")
//.text("hello")
.on("mousedown",
function(d) {
// disable zoom
vis.call(d3.behavior.zoom().on("zoom"), null);
mousedown_node = d;
if (mousedown_node == selected_node) selected_node = null;
else selected_node = mousedown_node;
selected_link = null;
// reposition drag line
drag_line
.attr("class", "link")
.attr("x1", mousedown_node.x)
.attr("y1", mousedown_node.y)
.attr("x2", mousedown_node.x)
.attr("y2", mousedown_node.y);
redraw();
})
.on("mousedrag",
function(d) {
// redraw();
})
.on("mouseup",
function(d) {
if (mousedown_node) {
mouseup_node = d;
if (mouseup_node == mousedown_node) { resetMouseVars(); return; }
// add link
var link = {source: mousedown_node, target: mouseup_node};
links.push(link);
// select new link
selected_link = link;
selected_node = null;
// enable zoom
vis.call(d3.behavior.zoom().on("zoom"), rescale);
redraw();
}
})
.transition()
.duration(750)
.ease("elastic")
//.attr("r", 6.5);
.attr("width", rectSize+1)
.attr("height", rectSize+1);
node.exit().transition()
//.attr("r", 0)
.remove();
node
.classed("node_selected", function(d) { return d === selected_node; });
if (d3.event) {
// prevent browser's default behavior
d3.event.preventDefault();
}
force.start();
}
function spliceLinksForNode(node) {
toSplice = links.filter(
function(l) {
return (l.source === node) || (l.target === node); });
toSplice.map(
function(l) {
links.splice(links.indexOf(l), 1); });
}
function keydown() {
if (!selected_node && !selected_link) return;
switch (d3.event.keyCode) {
case 8: // backspace
case 46: { // delete
if (selected_node) {
nodes.splice(nodes.indexOf(selected_node), 1);
spliceLinksForNode(selected_node);
}
else if (selected_link) {
links.splice(links.indexOf(selected_link), 1);
}
selected_link = null;
selected_node = null;
redraw();
break;
}
}
}
</script>
</body>
</html>
答案 0 :(得分:1)
首先请不要把大部分代码都放在那里,但要把你的例子放到一个简单的东西上,因为这样很难帮助你。
如果您真的想要显示代码,请将其放入fidd,以便我们可以看到它的结果(http://fiddle.jshell.net/)。
好吧,如果我明白你想要什么,你必须在追加之前选择你的元素。 试试这个:
// Here to update the text
node.selectAll('text')
.text(function(d){ //what you want to do on update }
// Here the creation
rect.append('svg:text')
.text('Hello wold')
但是你还需要替换你的节点输入,并且不要忘记更新它们,确实d3创建的常见模式是//更新//输入//退出:
// your node update
node.selectAll('rect')
// do what you want on update
// your node enter
var g = node.enter().append('svg:g')
g.append('svg:rect')
// all of your stuff
这样你就会有一个g元素,它包含你的节点元素和与节点相关联的文本元素,这就是我认为你想要的一个方便的结构
干杯
答案 1 :(得分:0)
您可以设置<text>
的标准x,y属性并定义最大宽度,然后使用我在此处找到的这个很好的函数:
http://bl.ocks.org/mbostock/7555321
自动为长文本svg。
换行function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}