d3.js如何以声明方式应用文本换行 [英] d3.js how to apply text wrapping declaratively

查看:251
本文介绍了d3.js如何以声明方式应用文本换行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承了一些气泡图代码,需要在其中添加气泡图标签的自动换行符.

I inherited some bubblechart code to which I need to add text wrapping of the bubble chart labels.

如何在此处应用答案如何对svg文本进行换行在javascript中?我不明白如何按照解决方案中的说明使d3更改svg标记.

How do I apply the answer here How to linebreak an svg text within javascript? to this scenario? I don't understand how to make d3 change the svg markup as given in the solution.

这是我的代码:

            function renderBubbles(root) {
                var diameter = element[0].offsetWidth * .6,
                    format = d3.format(",d"),
                    color = d3.scale.category20c();

                var bubble = d3.layout.pack()
                    .sort(null)
                    .size([diameter, diameter])
                    .padding(1.5);

                var svg = d3.select(element[0]).append("svg")
                    .attr("width", diameter)
                    .attr("height", diameter)
                    .attr("class", "bubble");


                var node = svg.selectAll(".node")
                    .data(bubble.nodes(classes(root))
                        .filter(function (d) {
                            return !d.children;
                        }))
                    .enter().append("g")
                    .attr("class", "node")
                    .attr("transform", function (d) {
                        return "translate(" + d.x + "," + d.y + ")";
                    })
                    .on('mouseover', function (d) {
                        var nodeSelection = d3.select(this).style({opacity: '0.5'});
                    })
                    .on('mouseout', function (d) {
                        var nodeSelection = d3.select(this).style({opacity: '1'});
                    })
                    .on("click", function (d) {
                        $log.debug(d);
                    })


                node.append("title")
                    .text(function (d) {
                        return d.className + ": " + format(d.value);
                    });

                node.append("circle")
                    .attr("r", function (d) {
                        return d.r;
                    })
                    .style("fill", function (d) {
                        return color(d.packageName);
                    })


                node.append("text")
                    .attr("dy", ".3em")
                    .style("text-anchor", "middle")
                    .text(function (d) {
                        return d.className.substring(0, d.r / 3);
                    });

// Returns a flattened hierarchy containing all leaf nodes under the root.
                function classes(root) {
                    var classes = [];

                    function recurse(name, node) {
                        if (node.children) node.children.forEach(function (child) {
                            recurse(node.name, child);
                        });
                        else classes.push({packageName: name, className: node.name, value: node.size});
                    }

                    recurse(null, root);
                    return {children: classes};
                }


                d3.select(self.frameElement).style("height", diameter + "px");

以下是给出的解决方案:

Here is the solution given:

<g transform="translate(123 456)"><!-- replace with your target upper left corner coordinates -->
  <text x="0" y="0">
    <tspan x="0" dy="1.2em">very long text</tspan>
    <tspan x="0" dy="1.2em">I would like to linebreak</tspan>
  </text>
</g>

推荐答案

@Mark谢谢.

node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function (d) {
    return d.className.substring(0, d.r / 2);
}).call(wrap,0)

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

这篇关于d3.js如何以声明方式应用文本换行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆