带文本锚点的D3文本换行:中 [英] D3 text wrap with text-anchor: middle
问题描述
在D3中,我想包装带有中间文本锚点的文本.我查看了来自Mike Bostok的示例,但我无法完全理解设置.>
我希望看到文本位于红色框的中心(水平和垂直).
var plot = d3.select(容器).insert("svg").attr('width',100).attr('height',200);plot.append("text").attr("x",50).attr("y",100).attr("text-anchor","middle").attr("alignment-baseline","alphabetic").text(棕狐跳!").call(wrap,100);函数wrap(文本,宽度){text.each(function(){var text = d3.select(this),单词= text.text().split(/\ s +/).reverse(),单词,行= [],lineNumber = 0,lineHeight = 1.1,//emsy = text.attr("y"),dy = 1tspan = 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("));如果(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(单词);}}});}
给出来自 Shashank 的指针,现在我可以使用翻译方法将文本放置在中央.仅仅设置文本的y似乎并没有改变任何东西.我还添加了yTrack变量,以便能够继续在已包装的文本下方进行绘制.
让yTrack = 100,情节= d3.select(容器).insert("svg").attr('width',100).attr('height',200);plot.append("text").attr("x",50).attr("y",yTrack).attr("text-anchor","middle").attr("font-family","sans-serif").text(快速的棕色狐狸跳过那只懒狗.").call(wrap,100);让height = parseInt(plot.select('text').node().getBoundingClientRect().height);plot.select("text").attr('transform','translate(0,'+(-height/2)+')');//plot.select("text").attr('y',0);yTrack + =(parseInt(height/2)+ 10);plot.append('rect').attr("x",0).attr("y",yTrack).attr("width",100).attr("height",10).style('fill','#999');函数wrap(文本,宽度){text.each(function(){让text = d3.select(this),单词= text.text().split(/\ s +/).reverse(),单词,行= [],lineNumber = 0,lineHeight = 1.1,//emsx = text.attr("x"),y = text.attr("y"),dy = 1.1,tspan = text.text(null).append("tspan").attr("x",x).attr("y",y).attr("dy",dy +"em");while(word = words.pop()){line.push(word);tspan.text(line.join("));如果(tspan.node().getComputedTextLength()> width){line.pop();tspan.text(line.join("));line = [word];tspan = text.append("tspan").attr("x",x).attr("y",y).attr("dy",++ lineNumber * lineHeight + dy +"em").text(单词);}}});}
#container {高度:200px;宽度:100px;边框:1px纯红色;}
< script src ="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js></script>< div id ="container"></div>
来自文档用于文本锚,中间
将导致以下结果:
将呈现的字符对齐,以使文本字符串的中间位置位于当前文本位置.
在您的情况下,当您将文本分解为 x
等于 0
的 tspan
s时-当前文本位置将是svg的开始位置(即,在点0处).另外,应用于 text
元素的 x:50
完全无关紧要.
-
一种方法是将中心值(即50)应用于
tspan
s:tspan.attr("x",50)
这是一个摘要:
var plot = d3.select(container).insert("svg").attr('width',100).attr('height',200);plot.append("text").attr("text-anchor","middle").attr("alignment-baseline","alphabetic").text(棕狐跳!").call(wrap,100);var height = plot.select('text').node().getBoundingClientRect().height;plot.select('text').attr('y',100-height/2);函数wrap(文本,宽度){text.each(function(){var text = d3.select(this),单词= text.text().split(/\ s +/).reverse(),单词,行= [],lineNumber = 0,lineHeight = 0.1,//emsy = text.attr("y"),dy = 1tspan = text.text(null).append("tspan").attr("x",50).attr("y",y).attr("dy",dy +"em");while(word = words.pop()){line.push(word);tspan.text(line.join("));如果(tspan.node().getComputedTextLength()> width){line.pop();tspan.text(line.join("));line = [word];tspan = text.append("tspan").attr("x",50).attr("y",y).attr("dy",++ lineNumber * lineHeight + dy +"em").text(单词);}}});}
#container {高度:200px;宽度:100px;边框:1px纯红色;}
< script src ="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js></script>< div id ="container"></div>
-
另一种方法是通过以下方式将'transform'属性应用于文本:
plot.select('text').attr('transform','translate(50,'+(100-height/2)+')');
以下是使用此方法的代码段:
var plot = d3.select(container).insert("svg").attr('width',100).attr('height',200);plot.append("text").attr("text-anchor","middle").attr("alignment-baseline","alphabetic").text(棕狐跳!").call(wrap,100);var height = plot.select('text').node().getBoundingClientRect().height;plot.select('text').attr('transform','translate(50,'+(100-height/2)+')');函数wrap(文本,宽度){text.each(function(){var text = d3.select(this),单词= text.text().split(/\ s +/).reverse(),单词,行= [],lineNumber = 0,lineHeight = 0.1,//emsy = text.attr("y"),dy = 1tspan = 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("));如果(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(单词);}}});}
#container {高度:200px;宽度:100px;边框:1px纯红色;}
< script src ="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js></script>< div id ="container"></div>
在上述两种方法中,我都没有使用y-center值,即 100 ,而是使用 getBoundingClientRect根据文字高度计算中点()
函数.
var height = plot.select('text').node().getBoundingClientRect().height;plot.select('text').attr('y',100-height/2);
希望这会有所帮助.:)
In D3 I would like to wrap texts which have a middle text anchor. I looked at this example from Mike Bostok but I cannot wrap my head around the settings.
I would like to see the text to be in the center (horizontal and vertical) of the red box.
var plot = d3.select(container)
.insert("svg")
.attr('width', 100)
.attr('height', 200);
plot.append("text")
.attr("x", 50)
.attr("y", 100)
.attr("text-anchor", "middle")
.attr("alignment-baseline", "alphabetic")
.text("The brown fox jumps!")
.call(wrap, 100);
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 = 1,
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);
}
}
});
}
Given the pointers from Shashank I was now able to position the text central with the translate method. Just setting the y of the text didn't seem to change anything. I also added a yTrack variable to be able to continue drawing below the wrapped text.
let yTrack = 100,
plot = d3.select(container)
.insert("svg")
.attr('width', 100)
.attr('height', 200);
plot.append("text")
.attr("x", 50)
.attr("y", yTrack)
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.text("The quick brown fox jumps over the lazy dog.")
.call(wrap, 100);
let height = parseInt(plot.select('text').node().getBoundingClientRect().height);
plot.select("text").attr('transform', 'translate(0, ' + (-height / 2) + ')');
//plot.select("text").attr('y', 0);
yTrack += (parseInt(height / 2) + 10);
plot.append('rect')
.attr("x", 0)
.attr("y", yTrack)
.attr("width", 100)
.attr("height", 10)
.style('fill', '#999');
function wrap(text, width) {
text.each(function() {
let text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = 1.1,
tspan = text.text(null).append("tspan").attr("x", x).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", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
#container {
height: 200px;
width: 100px;
border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="container"></div>
From the docs for text-anchor, middle
will result in the following:
The rendered characters are aligned such that the middle of the text string is at the current text position.
and in your case, as you are breaking down the text into tspan
s with x
equal to 0
-- the current text position would be the start of the svg (i.e. at point 0). Also, the x:50
applied to the text
element wouldn't matter at all.
One approach would be to apply the center value i.e. 50 to the
tspan
s:tspan.attr("x", 50)
Here's a snippet doing that:
var plot = d3.select(container) .insert("svg") .attr('width', 100) .attr('height', 200); plot.append("text") .attr("text-anchor", "middle") .attr("alignment-baseline", "alphabetic") .text("The brown fox jumps!") .call(wrap, 100); var height = plot.select('text').node().getBoundingClientRect().height; plot.select('text').attr('y', 100-height/2); function wrap(text, width) { text.each(function() { var text = d3.select(this), words = text.text().split(/\s+/).reverse(), word, line = [], lineNumber = 0, lineHeight = 0.1, // ems y = text.attr("y"), dy = 1, tspan = text.text(null).append("tspan").attr("x", 50).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", 50).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); } } }); }
#container { height: 200px; width: 100px; border: 1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="container"></div>
Another approach would be to apply 'transform' property to the text in the following way:
plot.select('text').attr('transform', 'translate(50, ' + (100-height/2)+')');
Here's a snippet with this method:
var plot = d3.select(container) .insert("svg") .attr('width', 100) .attr('height', 200); plot.append("text") .attr("text-anchor", "middle") .attr("alignment-baseline", "alphabetic") .text("The brown fox jumps!") .call(wrap, 100); var height = plot.select('text').node().getBoundingClientRect().height; plot.select('text').attr('transform', 'translate(50, ' + (100-height/2)+')'); function wrap(text, width) { text.each(function() { var text = d3.select(this), words = text.text().split(/\s+/).reverse(), word, line = [], lineNumber = 0, lineHeight = 0.1, // ems y = text.attr("y"), dy = 1, 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); } } }); }
#container { height: 200px; width: 100px; border: 1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="container"></div>
In both of the above approaches, I'm not using the y-center value i.e. 100 instead I'm calculating the mid-point based on the text height as well using getBoundingClientRect()
function.
var height = plot.select('text').node().getBoundingClientRect().height;
plot.select('text').attr('y', 100-height/2);
Hope this helps. :)
这篇关于带文本锚点的D3文本换行:中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!