为什么内部工具提示"未定义"?

时间:2016-11-09 19:41:43

标签: javascript d3.js

我有以下csv:

P-Cp,750,50
P-Trd,150,16
B-Cb,450,67
B-Trd,156,46

然后我将以下javascript应用于它:

<meta charset="utf-8">
<style>
#sunBurst {
    position: absolute;
    top: 60px;
    left: 10px;
    width: 350px;
    height: 350px;
}

</style>
<label>
    <input type="radio" name="mode" value="amount" checked="checked"> Rev</label>
<label>
    <input type="radio" name="mode" value="users"> Users</label>
<script src="//d3js.org/d3.v3.min.js"></script>
<div id="sunBurst"></div>
<script>
//
//
createPie();

function createPie() {
    var width = 300,
        height = 300,
        radius = Math.min(width, height) / 2,
        color = d3.scale.category20c();

    //this bit is easy to understand:
    var svg = d3.select("#sunBurst")
        .append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr({
            'transform': "translate(" + width / 2 + "," + height * .5 + ")",
            id: "sunGroup"
        });


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



    d3.text("testing.csv", function(text) {
        var csv = d3.csv.parseRows(text);
        console.log(csv)
        var json = buildHierarchy(csv);
        console.log(json)

        var partition = d3.layout.partition()
            .sort(null)
            .size([2 * Math.PI, radius * radius])
            .value(function(d) {
                return d.amount;
            });

        var path = svg.data([json]).selectAll("path")
            .data(partition.nodes)
            .enter()
            .append("path")
            .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", 1)
            .each(stash)

        //this is a start>>>>>   
        path
            .append("title") //mouseover title showing the figures
            .text(function(d) {
                return d.name + ": " + d.amount;
            });


        d3.selectAll("input").on("change", function change() {
            console.log(this.value)
            var value = this.value === "amount" ? function(d) {
                return d.amount;
            } : function(d) {
                return d.users;
            };

            path
                .data(partition.value(value).nodes)
                .transition()
                .duration(2500)
                .attrTween("d", arcTween)
        });


        // 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);
            };
        }

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

    });

};

// Take a 2-column CSV and transform it into a hierarchical structure suitable
// for a partition layout. The first column is a sequence of step names, from
// root to leaf, separated by hyphens. The second column is a count of how 
// often that sequence occurred.
function buildHierarchy(csv) {
    var root = {
        "name": "root",
        "children": []
    };
    for (var i = 0; i < csv.length; i++) {
        var sequence = csv[i][0];
        var amount = +csv[i][1];
        var users = +csv[i][2];
        if (isNaN(amount)) { // 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,
                    "amount": amount,
                    "users": users
                };
                children.push(childNode);
            }
        }
    }
    return root;
};

</script>

以下是一个工作示例:https://plnkr.co/edit/hjXvIA9wbovoMgnFV0qm?p=preview

如果我将鼠标悬停在任何内部段上,则值为&#34;未定义&#34; - 如何将值附加到这些工具提示?

补充

我尝试修改构建层次结构函数,以便每个节点都有关联的值,但不确定如何使这些值等于其子项的总和:

     if (!foundChild) {
                childNode = {
                    "name": nodeName,
                    "amount": amount,
                    "users": users,
                    "children": []
                };
                children.push(childNode);
            }

1 个答案:

答案 0 :(得分:1)

代码中的部分为您提供“工具提示”(实际上是svg中元素的标题:

path
        .append("title") //mouseover title showing the figures
        .text(function(d) {
            return d.name + ": " + d.amount;
        });

问题在于,在构建数据时 - 添加不含金额的子元素:

if (j + 1 < parts.length) {
 ....
           if (!foundChild) {
                childNode = {
                    "name": nodeName,
                    "children": []
                };
                children.push(childNode);
            }

所以基本上你的标题是d.name + ": " + undefined(这正是你得到的)。 我不确定你想要的数据到底是什么,但这里有一个你可以采取和修改的变化:

    path
        .append("title") //mouseover title showing the figures
        .text(function(d) {
            if (d.hasOwnProperty('amount')) {
                return d.name + ": " + d.amount;
            } else {
                return d.name + ": " + d.children.length;
            }
        });

更新

您可以遍历节点中的每个元素,并总结其子元素的数量:

root.children.forEach(function(v) {
    v.amount = v.children.reduce(function(a, b) { console.log(a); return {amount: a.amount+b.amount}}, {'amount': 0}).amount
})

在第188行(return root;之前)

添加此内容