javascript - 在 D3 中应用包装功能后,文本刷新到初始状态

标签 javascript d3.js

我有以下函数用于在 D3 中包装文本,取自 this回答:

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
            x = text.attr("x"),
            y = text.attr("y"),
            dy = 0, //parseFloat(text.attr("dy")),
            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);
            }
        }
    });
}

我按以下方式初始化节点:

const nodes = [1, 2, 3]
const nodesTextsEnter = vis.g.selectAll('text.node').data(nodes).enter()
const nodesTextsUpdate = vis.g.selectAll('text.node').data(nodes)
vis.g.selectAll('text.node').data(nodes).exit().remove()
        
nodesTextsEnter.append('text')
                .attr('x', (d, i) => i*30)
                .attr('y', (d, i) => i*30)
                .attr('text-anchor', 'middle')
                .attr('dominant-baseline', 'middle')
                .attr('font-size', 12)
                .style('cursor', 'pointer')
                .attr('class', 'node')
                .attr('opacity', '0')
                .transition()
                .attr('opacity', '1')
                .attr('x', (d, i) => i*30)
                .attr('y', (d, i) => i*30)
                .text('This is a long text')
                .call(wrap, 30)

nodesTextsUpdate
                .transition(transitionDuration)
                .attr('x', (d, i) => i*30)
                .attr('y', (d, i) => i*30)
                .text('This is a long text')
                .call(wrap, 30)

问题是,在调试 wrap 函数时,我看到节点发生了所有包装更改,但在某个时候(具体来说,我认为它发生在 timerFlush() 上timer.jswake 函数中)节点的内容被刷新,就好像它从未被包装过一样。

为什么会发生这种情况?欢迎任何想法。

最佳答案

如果您在转换前设置文本内容,您的代码就可以工作:

nodesTextsEnter.append('text')
    .attr('x', (d, i) => i*30)
    .attr('y', (d, i) => i*30)
    .attr('text-anchor', 'middle')
    .attr('dominant-baseline', 'middle')
    .attr('font-size', 12)
    .style('cursor', 'pointer')
    .attr('class', 'node')
    .attr('opacity', '0')
    .text('This is a long text') // this line was moved up
  .transition()
    .attr('opacity', '1')
    .attr('x', (d, i) => i*30)
    .attr('y', (d, i) => i*30)
    .call(wrap, 30);

否则,wrapd3.select(this).text()的值为空,因此words只包含空的字符串。

关于javascript - 在 D3 中应用包装功能后,文本刷新到初始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68939861/

相关文章:

当数组中只有一项时,JavaScript Join 会插入逗号分隔符

javascript - 如何在PHP中为动态添加/删除输入字段创建错误处理程序

javascript - 使用 Angular 2 拖动和缩放 D3 V4 图表

javascript - v4 : pinch zooming a map when one finger is over a child element 中的 d3.js 缩放传播

javascript - 使用 d3 将按钮添加到 <g> 元素

javascript - 将状态设置为父级

javascript - Backbone 过滤器集合按名称返回模型?

javascript - 如何在 JavaScript node.js 中将 xml 文件解析为数组

javascript - 带时间刻度的 D3 直方图

d3.js - d3 过渡等待上一个?