Javascript 勾选文本/变量标签未在d3条形图中换行
我尝试在d3条形图中沿x轴将换行应用于长变量标签。这是我在一个可观察笔记本上的图表: 我尝试应用一种解决方案,主要包括以下内容:Javascript 勾选文本/变量标签未在d3条形图中换行,javascript,d3.js,data-visualization,observablehq,Javascript,D3.js,Data Visualization,Observablehq,我尝试在d3条形图中沿x轴将换行应用于长变量标签。这是我在一个可观察笔记本上的图表: 我尝试应用一种解决方案,主要包括以下内容: function wrap(text, width) { text.each(function() { var text = d3.select(this), words = text.text().split(/\s+/).reverse(), word, line = [], lineNu
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)
}
}
})
}
svg.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height})`)
.call(xAxis)
.selectAll(".tick text")
.call(wrap, x.bandwidth())
它看起来像什么:
我正在努力实现的目标: 我还尝试将
wrap
函数移到其他地方,在代码的前面和后面,以及尝试移动以下行
.selectAll(".tick text")
.call(wrap, x.bandwidth())
要在这段代码中的某个地方工作,如下所示:
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.style("font-family", "HelveticaNeueLTStd-Cn")
.style("font-size", "9px")
.call(d3.axisBottom(x).tickSizeOuter(0))
.selectAll(".tick text")
.call(wrap, x.bandwidth())
但是(试图适应)不起作用。(我以前在其他d3可视化中使用过文本换行功能,这是值得的。)有人能演示一个基于分叉的工作解决方案吗?我成功地将文本换行技术应用于“从”中的x轴条/变量标签。它包含以下代码:
svg.append("g")
.call(yAxis);
const axis = svg.append("g")
.call(xAxis);
setTimeout(()=>{
axis.selectAll(".tick text")
.style("font-family", "HelveticaNeueLTStd-Cn")
.style("font-size", "9px")
.call(wrap, x.bandwidth());
}, 0);
以下是。中已经暗示的,
wrap
不起作用的原因是由于Observable的单元格如何运行。据Mike Bostock,Observable(和D3)的创建者说
[这个问题]通常发生在Observable中,因为标准模式是将单元格实现为“纯”函数,在这里创建分离的元素并返回它们,然后将它们插入DOM中;因此,在一个单元中,您几乎应该始终使用分离的元素。()
因此,当您调用tspan.node().getComputedTextLength()
时,DOM中还没有任何内容,因此它返回零
与您一样,我的解决方案只是使用一个0毫秒的setTimeout
,因此当您需要测量元素时,元素将在DOM中。有人可能会说,这是黑客行为,事实确实如此!顺便说一句,博斯托克的解决方案,沿着这些路线
const foo = html`<html structure here>`;
document.body.appendChild(foo);
//get the length of foo...
foo.remove();
constfoo=html`;
文件.body.appendChild(foo);
//获取foo的长度。。。
foo.remove();
。。。同样令人讨厌,甚至可能更糟。tspan.node().getComputedTextLength()总是返回“0”我有这个问题,但我也在x轴上使用转换,所以这个解决方案并不完美:。@eudoxyz是的,我同意,我不知道为什么这个问题会链接到你的问题,因为你的问题根本不同。请问你有什么解决我的问题的方法吗?