我找到了这个很棒的插件,textwrap.js包含了很长的svg文本行。我在d3js上使用这个插件。我能够使用d3和json对象创建我的文本框和文本。但是当我应用textwrap.js函数时,文本将按预期进行换行,但它将从文本框中重新定位文本并将文本放在浏览器屏幕的左上角;忽略我在d3 selectAll文本结构中建立的x和y定位。 Textwrap.js不会包装文本并将其保留在文本框中。我玩了几种技术来包装文本并将其保存在特定的文本框中,但我没有发现任何快乐。我附加了当前代码,将包装好的文本放在左上角。我非常感谢您解决此问题的任何帮助(将包装好的文本放在文本框中)。提前谢谢。
链接到textwrap.js文档:https://github.com/kstohr/d3textwrap
<!DOCTYPE HTML>
<meta charset = "UTF-8" />
<head>
<title>Text Wrap Practice</title>
<link href="myCSS_Style.css" rel="stylesheet" type="text/css">
<script src="jquery-1.10.2.min.js "></script>
<script src="d3.min.js"></script>
<script src="textwrap.js"></script><!---->
<script src="myJS.js"></script>
</head>
<body>
<div id="chartData"></div>
</body>
</html>
$(document).ready(function(){
var width = 960,
height = 500;
var svg = d3.select("#chartData").append("svg")
.attr("width", width)
.attr("height", height)
d3.json("data.json", function(json) {
var elem = svg.selectAll("text")
.data(json.nodes)
var elemEnter = elem.enter()
.append("g")
var circle = elemEnter.append("rect")
.attr("x", function(d){return d.x} )
.attr("y", function(d){return d.y} )
.attr("width", function(d){return d.w} )
.attr("height", function(d){return d.h} )
.attr("stroke","black")
.attr("fill", "white")
elemEnter.append("text")
.attr("class", function(d) { return "txtElem" + d.id; })
.attr("x", function(d){return d.x + 50} )
.attr("y", function(d){return d.y + 40} )
.text(function(d){return d.label});
var wrap = d3.textwrap().bounds({height: 50, width: 250});
d3.selectAll('text').call(wrap);
});
数据文件,data.json:
{&#34;节&#34;:[ {&#34; id&#34;:1,&#34; x&#34;:80,&#34; y&#34;:40,&#34; w&#34;:250,&#34; h& #34;:50,&#34;标签&#34;:&#34;这是我需要用textwrap&#34;}包裹的长文本1, {&#34; id&#34;:2,&#34; x&#34;:200,&#34; y&#34;:160,&#34; w&#34;:250,&#34; h& #34;:50,&#34;标签&#34;:&#34;长文本2我喜欢在文本框中包装&#34;}, {&#34; id&#34;:3,&#34; x&#34;:380,&#34; y&#34;:280,&#34; w&#34;:250,&#34; h& #34;:50,&#34;标签&#34;:&#34;我的长篇文章3我试图将其包装到文本框中&#34;} ]}
答案 0 :(得分:0)
I can force it to work if I call it like this:
d3.selectAll("text").each(function(){
d3.select(this).textwrap(this.previousElementSibling.getBBox());
});
Full code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Text Wrap Practice</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://rawgit.com/kstohr/d3textwrap/master/d3textwrap.v0.js"></script>
</head>
<body>
<div id="chartData"></div>
<script>
var width = 960,
height = 500;
var svg = d3.select("#chartData").append("svg")
.attr("width", width)
.attr("height", height);
//d3.json("data.json", function(json) {
var json = {"nodes":[{"id":1,"x":80,"y":40,"w":250,"h":50,"label":"This is my long text 1 that need to be wrapped by textwrap"},{"id":2,"x":200,"y":160,"w":250,"h":50,"label":"Long Text 2 I like to wrap in the text box"},{"id":3,"x":380,"y":280,"w":250,"h":50,"label":"My Long Text 3 I'm try to wrap into the text box"}]};
var elem = svg.selectAll("text")
.data(json.nodes)
var elemEnter = elem.enter()
.append("g")
var circle = elemEnter.append("rect")
.attr("x", function(d) {
return d.x
})
.attr("y", function(d) {
return d.y
})
.attr("width", function(d) {
return d.w
})
.attr("height", function(d) {
return d.h
})
.attr("stroke", "black")
.attr("fill", "white")
var textElements = elemEnter.append("text")
.attr("class", function(d) {
return "txtElem" + d.id;
})
.attr("x", function(d) {
return d.x + 50
})
.attr("y", function(d) {
return d.y + 40
})
.text(function(d) {
return d.label
});
d3.selectAll("text").each(function(){
d3.select(this).textwrap(this.previousElementSibling.getBBox());
})
//});
</script>
</body>
</html>
To be honest, though, I find the plugin to be confusing and of dubious quality. When I need to wrap text I usually follow this example.
I'd refactor your code a bit and that example and in the end my code would look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Text Wrap Practice</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://rawgit.com/kstohr/d3textwrap/master/d3textwrap.v0.js"></script>
</head>
<body>
<div id="chartData"></div>
<script>
var width = 960,
height = 500;
var svg = d3.select("#chartData").append("svg")
.attr("width", width)
.attr("height", height);
//d3.json("data.json", function(json) {
var json = {
"nodes": [{
"id": 1,
"x": 80,
"y": 40,
"w": 250,
"h": 50,
"label": "This is my long text 1 that need to be wrapped by textwrap"
}, {
"id": 2,
"x": 200,
"y": 160,
"w": 250,
"h": 50,
"label": "Long Text 2 I like to wrap in the text box"
}, {
"id": 3,
"x": 380,
"y": 280,
"w": 250,
"h": 50,
"label": "My Long Text 3 I'm try to wrap into the text box"
}]
};
var elem = svg.selectAll("text")
.data(json.nodes)
var elemEnter = elem.enter()
.append("g")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
var circle = elemEnter.append("rect")
.attr("width", function(d) {
return d.w
})
.attr("height", function(d) {
return d.h
})
.attr("stroke", "black")
.attr("fill", "white")
var textElements = elemEnter.append("text")
.attr("class", function(d) {
return "txtElem" + d.id;
})
.text(function(d) {
return d.label
})
.attr("y", 12);
d3.selectAll("text").call(wrap, function(d) {
return this.previousElementSibling.getBBox().width;
});
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")) || 0,
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
width = (typeof width === "function") ? width.call(this) : width;
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);
}
}
});
}
//});
</script>
</body>
</html>