简体   繁体   中英

D3 circle pack: html in text attribute

The code below works fine in that I can output a text string into the bubbles.

But how do I output HTML markup into the bubble text label? You can see my HTML markup in the first "name" attribute.

This div is very simple in this example, but it will eventually contain more markup and a class id to a css

<script>
    $(document).ready(function () {
        var json = {
            "name": "flare",
            "children": [
                { "name": "<div>test1<br>test again</div>", "size": 20, "color": "#ff0000" , "id": 1},
                { "name": "test2", "size": 40, "color": "#ffff00", "id": 2},
                { "name": "test3", "size": 60, "color": "#ff0000", "id": 3},
                { "name": "test4", "size": 80, "color": "#ff00ff", "id": 4 },
                { "name": "test5", "size": 100, "color": "#0000ff", "id": 5}
            ]
        };

        var r = 400,
            format = d3.format(",d"),
            fill = d3.scale.category20c();

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

        var vis = d3.select("#chart").append("svg")
            .attr("width", r)
            .attr("height", r)
            .attr("class", "bubble");

        var node = vis.selectAll("g.node")
            .data(bubble.nodes(classes(json))
            .filter(function (d) { return !d.children; }))
            .enter().append("g")
            .attr("class", "node")
            .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });

        node.append("circle")
            .attr("r", function (d) { return d.r; })
            .style("fill", function (d) { return d.color; })
            .on("click", function (d) { alert("id: " + d.id); });

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

        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, dispText: node.name, value: node.size, color: node.color, id: node.id});
            }

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

    });

    </script>

You want the foreignObject tag, which allows you to embed HTML (or other XML namespaces) - Mike Bostock has a good example of using this here: http://bl.ocks.org/mbostock/1424037

In your case, this might look like (untested):

node.append("foreignObject")
    // I believe w/h are required, though the size is arbitrary
    .attr("width", 200)
    .attr("height", 50)
  .append("xhtml:body")
    .html(function (d) { return d.dispText.substring(0, d.r / 3); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM