【问题标题】:suggestion about how to adapt a function that wrap text in d3关于如何调整在 d3 中包装文本的函数的建议
【发布时间】:2019-10-14 19:23:48
【问题描述】:

我想在 d3 中换行,我已经阅读过它,并且我知道在 d3 中执行此操作的方法是将长文本分成插入tspan elmenets 的子字符串或将文本添加到foreignObject 元素。

我正在尝试使用tspan 方法调整此功能

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,
            y = text.attr("y"),
            x = text.attr("x"),
            dy = text.attr("dy"),
            dx = text.attr("dx"),
            tspan = text
                .text(null)
                .append("tspan")
                .attr("x", x)
                .attr("y", y)
                .attr("dx", dx)
                .attr("dy", dy);
        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("dx", dx)
                    .attr("dy", ++lineNumber * lineHeight + Math.abs(dy) + "em")
                    .text(word);
            }
        }
    });
}

这个函数可以正常工作,但是文本元素的dxdy定义的坐标丢失了,导致文本出现在图形中的错误位置。

我发现通过用.attr("dy", dy) 替换.attr("dy", ++lineNumber * lineHeight + Math.abs(dy) +" em ") 行,文本被放置在所需位置,但tspan 元素重叠。

得到这个

我是 d3 概念的新手,我很欣赏你的 cmets

更新1:调用函数wrap后的tspan元素分布

<g class="category">
    <circle r="15" cx="112.58330249197704" cy="64.99999999999997"></circle>
    <text x="112.58330249197704" y="64.99999999999997" dx="20" dy="10" text-anchor="start">
        <tspan x="112.58330249197704" y="64.99999999999997" dx="20" dy="10"></tspan>
        <tspan x="112.58330249197704" y="64.99999999999997" dx="20" dy="11">Third</tspan>
        <tspan x="112.58330249197704" y="64.99999999999997" dx="20" dy="11">Bit</tspan>
        <tspan x="112.58330249197704" y="64.99999999999997" dx="20" dy="11">Category</tspan>
    </text>
</g>

更新2:应用更新函数后的图形状态,文本分布细节

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    我已经使用这个功能有一段时间了,也许对你也有用(可能会稍作调整):

    function wrap(text, width) {
        text.each(function () {
            var text = d3.select(this),
                words = text.text().split(/\s+/).reverse(),
                word,
                line = [],
                lineNumber = 0,
                lineHeight = 1, 
                y = text.attr("y"),
                x = text.attr("x"),
                dy = 0,
                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", lineHeight + "em").text(word);
                    lineHeight++;
                }
            }
        });
    }
    

    更新:看起来我复制了错误的函数,我的项目中有多个版本。我相信这个应该可以正常工作。

    你的函数和我分享的第一个函数有同样的问题——我们都没有在循环中增加lineHeight(在你的情况下它被称为lineNumber)。

    【讨论】:

    • 感谢您的回答,我已经尝试过了,不幸的是,文本失去了坐标并且也重叠了。暂时不知道怎么调功能
    • @user615274 如果你能在某个地方建立一个工作示例,这样我就可以看看你的情况,这将非常有帮助。
    • 我想过,但对我来说很难,我是 d3 的新手,而且图表很复杂,我很难复制一个最小的功能版本。如果它是相关的,我已经更新了问题,一旦调用函数wrap,tspan 元素是如何分布的
    • @user615274 你能看看更新的代码吗?我认为这一次应该可以工作,如果仍然不行,请告诉我!
    • 再次感谢您的回答,效果更好,我最初显示的功能丢失了文本的坐标,您显示的上一个版本发生了同样的事情,这个版本的坐标不是丢失了,尽管文本的分布仍然存在细节。我用图表的可视化来更新问题,我详细说明了文本的主题。我知道有很多问题要问,但是如果您知道如何解决它,我将不胜感激
    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多