bde*_*ham 62 javascript svg d3.js
我正在使用D3生成条形图(我使用了此示例中的代码).我在x轴上使用的标签每个都是两个字,因为这使得所有标签重叠,我需要跨行打破这些标签.(如果我可以用换行符替换每个标签中的所有空格,那就没问题了.)
我最初尝试使用文字换行符(
)替换空格并xml:space="preserve"在标签<text>元素上设置.不幸的是,事实证明SVG不尊重这个属性.接下来,我尝试将每个单词包装成<tspan>我以后可以使用的单词.我通过这个函数传递了每个标签:
function (text) {
return '<tspan>' + text.replace(/ /g, '</tspan><tspan>') + '</tspan>';
}
Run Code Online (Sandbox Code Playgroud)
但这只是将文字<tspan>放入输出中.如何将文本标签包装在tspans中(或执行其他操作)以使我的标签不重叠?
bde*_*ham 86
我最终使用以下代码来跨行打破每个x轴标签:
var insertLinebreaks = function (d) {
var el = d3.select(this);
var words = d.split(' ');
el.text('');
for (var i = 0; i < words.length; i++) {
var tspan = el.append('tspan').text(words[i]);
if (i > 0)
tspan.attr('x', 0).attr('dy', '15');
}
};
svg.selectAll('g.x.axis g text').each(insertLinebreaks);
Run Code Online (Sandbox Code Playgroud)
请注意,这假定已经创建了标签.(如果您遵循规范直方图示例,那么标签将以您需要的方式设置.)也没有任何真正的断行逻辑; 该函数将每个空格转换为换行符.这符合我的目的,但您可能需要编辑该split()行以更智能地将字符串的各个部分划分为行.
小智 6
我发现有用的东西是使用'foreignObject'标签而不是text或tspan元素.这允许简单地嵌入HTML,允许单词自然地破解.需要注意的是满足特定需求的对象的整体尺寸:
var myLabel = svg.append('foreignObject')
.attr({
height: 50,
width: 100, // dimensions determined based on need
transform: 'translate(0,0)' // put it where you want it...
})
.html('<div class"style-me"><p>My label or other text</p></div>');
Run Code Online (Sandbox Code Playgroud)
您可以使用d3.select/selectAll动态更新文本值,以便随后可以获取此对象内部的任何元素.
环顾四周后,我发现 Mike Bostock 提供了一个解决方案,使您可以将文本环绕。
http://bl.ocks.org/mbostock/7555321
要在我的代码上实现它(我正在使用折叠树图)。我只是复制了“wrap”方法。
然后附加以下内容
// Standard code for a node
nodeEnter.append("text")
.attr("x", function(d) { return d.children || d._children ? -10 : 10; })
.attr("dy", ".35em")
.text(function(d) { return d.text; })
// New added line to call the function to wrap after a given width
.call(wrap, 40);
Run Code Online (Sandbox Code Playgroud)
我看不出有任何理由这不适用于力导向、条形或任何其他模式
修正案 :
对于阅读本文并使用可折叠图的任何人,我已将换行函数修改为以下内容。“x”属性的更改正确设置了对齐方式,增加行号是在单独的行上执行的,因为原始代码中注意到了问题,并且“y”已硬设置为零,否则会出现行距增加的问题每行。
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
lineHeight = 1.1, // ems
tspan = text.text(null).append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
var textWidth = tspan.node().getComputedTextLength();
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
++lineNumber;
tspan = text.append("tspan").attr("x", function(d) { return d.children || d._children ? -10 : 10; }).attr("y", 0).attr("dy", lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
Run Code Online (Sandbox Code Playgroud)