为什么这些标签不可见

时间:2017-04-07 18:35:24

标签: javascript d3.js

我有一个双环饼图的视觉效果。我添加了以下内容以尝试在图表外添加标签:

var arcs = svg.selectAll(".theArc")

arcs.append("text")
    .attr("transform", function(d) {

        var c = arc.centroid(d),
            x = c[0],
            y = c[1],
            // pythagorean theorem for hypotenuse
            h = Math.sqrt(x * x + y * y);
            console.log(c, h)
        return "translate(" + (x / h * labelr) + ',' +
            (y / h * labelr) + ")";
    })
    .attr("text-anchor", "middle")
    .text(function(d,i) {
        if (d.name !== 'root') {
            return "hello" + d.name;
        }
    })
    .attr("class", "theTxtsOuter")

我可以在检查器中看到文本但不在页面上呈现 - 为什么文本不可见?

以下是视觉内容:http://plnkr.co/edit/cnump1mG0XRXxrCur0OT?p=preview

以下是创建饼图的函数的填充代码:

function pieChart(dataFile) {

    var plot;
    var vis;

    var width = 400,
        height = 400,
        radius = Math.min(width, height) / 2.1,
        color = d3.scale.ordinal()
        .range(["#338ABA", "#016da9", "#4c96d5"])
        .domain([0, 2]);

    var labelr = radius + 5 // radius for label anchor

    var div = d3.select("body")
        .append("div")
        .attr("class", "toolTip");



    var arc = d3.svg.arc()
        .startAngle(function(d) {
            return d.x;
        })
        .endAngle(function(d) {
            return d.x + d.dx;
        })
        .outerRadius(function(d) {
            return (d.y + d.dy) / (radius);
        })
        .innerRadius(function(d) {
            return d.y / (radius);
        });


    //check if the svg already exists
    plot = d3.select("#svgPIEChart")
    if (plot.empty()) {
        vis = d3.select("#pieChart")
            .append("svg")
            .attr({
                id: "svgPIEChart"
            })
    } else {
        vis = d3.select("#svgPIEChart")
        vis.selectAll("*").remove();
    };

    //group of the svg element
    var svg = vis
        .append("g")
        .attr({
            'transform': "translate(" + width / 2 + "," + height * .52 + ")"
        });


    //svg element
    vis.attr({
        //set the width and height of our visualization (these will be attributes of the <svg> tag
        width: width,
        height: height
    });



    d3.text(dataFile, function(text) {
        var csv = d3.csv.parseRows(text);
        var json = buildHierarchy(csv);

        // it seems d3.layout.partition() can be either squares or arcs
        var partition = d3.layout.partition()
            .sort(null)
            .size([2 * Math.PI, radius * radius])
            .value(function(d) {
                return d.SalesRev;
            });

        var path = svg.data([json]).selectAll(".theArc")
            .data(partition.nodes)
            .enter()
            .append("path")
            .attr("class", "theArc")
            .attr("id", function(d, i) {
                return "theArc_" + i;
            }) //Give each slice a unique ID 
            .attr("display", function(d) {
                return d.depth ? null : "none";
            })
            .attr("d", arc)
            .style("stroke", "#fff")
            .style("fill", function(d) {
                return color((d.children ? d : d.parent).name);
            })
            .attr("fill-rule", "evenodd")
            .style("opacity", 0.01)
            .style("stroke-opacity", 0.01)
            .each(stash);


        path.transition()
            .duration(PIEOBJ.transTime)
            .style("opacity", 1)
            .style("stroke-opacity", 1)

        path
            .on("mouseout", mouseout)
            .on("mousemove", function(d) {
                div.style("left", d3.event.pageX + 10 + "px");
                div.style("top", d3.event.pageY - 25 + "px");
                div.style("display", "inline-block");
                div.html(d.name + "<br>" + PIEOBJ.formatShrtInt(d.SalesRev));
            })



        var txts = svg.data([json]).selectAll(".theTxts")
            .data(partition.nodes)
            .enter()
            .append("text");
        txts
            .attr("class", "theTxts")
            .attr("dx", 10) //Move the text from the start angle of the arc
            .attr("dy", 15) //Move the text down
            .style("opacity", 0)
        txts
            .transition()
            .duration(PIEOBJ.transTime)
            .style("opacity", 1);



        var txtPths = txts.append("textPath")
            // .attr("xlink:href", function(d, i) {
            .attr("href", function(d, i) {
                return "#theArc_" + i;
            })
            .text(function(d) {
                if (d.name === 'root') {
                    return;
                } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
                    return;
                } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
                    return;
                } else {
                    return d.name;
                }
            });




        /* ------- TEXT LABELS OUTSIDE THE PIE-------*/
        var arcs = svg.selectAll(".theArc")

        arcs.append("text")
            .attr("transform", function(d) {

                var c = arc.centroid(d),
                    x = c[0],
                    y = c[1],
                    // pythagorean theorem for hypotenuse
                    h = Math.sqrt(x * x + y * y);
                    console.log(c, h)
                return "translate(" + (x / h * labelr) + ',' +
                    (y / h * labelr) + ")";
            })
            .attr("text-anchor", "middle")
            .text(function(d,i) {
                if (d.name !== 'root') {
                    return "hello" + d.name;
                }
            })
            .attr("class", "theTxtsOuter")
        /* ----------------------------------------*/





        d3.selectAll("input").on("change", function change() {


            function createValueFunc(val) {
                // currentMeasure = val;
                return function(d) {
                    return d[val];
                };
            }

            value = createValueFunc(this.value);

            PIEOBJ.currentMeasure = this.value;

            var path2 = svg.data([json]).selectAll(".theArc");
            path2
                .data(partition.value(value).nodes)
                .transition()
                .duration(1500)
                .attrTween("d", arcTween)
                .each("start", function() {
                    d3.select(this)
                        .on("mouseout", null) //CLEARING the listeners
                        .on("mousemove", null)
                })
                .each("end", function() {
                    d3.select(this)
                        .on("mouseout", mouseout) //attaching the listeners
                        .on("mousemove", function(d) {
                            div.style("left", d3.event.pageX + 10 + "px");
                            div.style("top", d3.event.pageY - 25 + "px");
                            div.style("display", "inline-block");
                            div.html(d.name + "<br>" + PIEOBJ.formatShrtInt(value(d)));
                        })
                });

            svg.selectAll("textPath")
                .text(function(d) {
                    if (d.name === 'root') {
                        return;
                    } else if ((d.depth === 1) && (d.dx < (d.name.length * 0.15))) {
                        return;
                    } else if ((d.depth === 2) && (d.dx < (d.name.length * 0.1))) {
                        return;
                    } else {
                        return d.name;
                    }
                });

            // the following deletes what was originally created and then recreates the text
            // svg.selectAll("#titleX").remove();

        });



        function mouseout() {
            div.style("display", "none"); //<< gets rid of the tooltip <<
        };

        // Stash the old values for transition.
        function stash(d) {
            d.x0 = d.x;
            d.dx0 = d.dx;
        };

        // Interpolate the arcs in data space.
        function arcTween(a) {
            var i = d3.interpolate({
                x: a.x0,
                dx: a.dx0
            }, a);
            return function(t) {
                var b = i(t);
                a.x0 = b.x;
                a.dx0 = b.dx;
                return arc(b);
            };
        };

    });


};

// // Take a 2-column CSV and transform it into a hierarchical structure suitable
// // for a partition layout. 
function buildHierarchy(csv) {
    var root = {
        "name": "root",
        "children": []
    };
    for (var i = 0; i < csv.length; i++) {

        var sequence = csv[i][0];

        // var APD = +csv[i][1];
        var SalesRev = +csv[i][1];
        var Amount = +csv[i][2];

        if (isNaN(SalesRev)) { // e.g. if this is a header row
            continue;
        }
        var parts = sequence.split("-");
        var currentNode = root;
        for (var j = 0; j < parts.length; j++) {
            var children = currentNode["children"];
            var nodeName = parts[j];
            var childNode;
            if (j + 1 < parts.length) {
                // Not yet at the end of the sequence; move down the tree.
                var foundChild = false;
                for (var k = 0; k < children.length; k++) {
                    if (children[k]["name"] == nodeName) {
                        childNode = children[k];
                        foundChild = true;
                        break;
                    }
                }
                // If we don't already have a child node for this branch, create it.
                if (!foundChild) {
                    childNode = {
                        "name": nodeName,
                        "children": []
                    };
                    children.push(childNode);
                }
                currentNode = childNode;
            } else {
                // Reached the end of the sequence; create a leaf node.
                childNode = {
                    "name": nodeName,
                    // "APD": APD,
                    "SalesRev": SalesRev,
                    "Amount": Amount
                };
                children.push(childNode);
            }
        }
    }

    root.children.forEach(function(v) {
        v.SalesRev = 0;
        v.Amount = 0;

        v.children.forEach(function(a) {
            v.SalesRev += a.SalesRev;
            v.Amount += a.Amount;
        });
    });

    return root;
}

1 个答案:

答案 0 :(得分:2)

文本未显示,因为它是作为path元素的子元素添加的。使用g元素在同一级别的path标记下添加文字。一种方法就是这样(它为每个弧添加一级g个元素,将弧和文本组合在一起):

 var arcs = svg.data([json]).selectAll(".arcG")
     .data(partition.nodes)
     .enter()
     .append("g")
     .attr("class","arcG");

 arcs.append("path")
      .attr("class","theArc")
      .attr("d", arc)
      ...

 arcs.append("text")
    .attr("transform", function(d) {

        var c = arc.centroid(d),
            x = c[0],
            y = c[1],
            // pythagorean theorem for hypotenuse
            h = Math.sqrt(x * x + y * y);
            console.log(c, h)
        return "translate(" + (x / h * labelr) + ',' +
            (y / h * labelr) + ")";
    })
    ....