0

使用 ad3.layout.tree()我正在尝试过滤选择以仅包含链接nodes深度小于的链接线leafDepth

以下行是我尝试这样做的方式:

links.enter().filter(function(d){return d.target.depth < leafDepth;})....

没有过滤器,图形绘制得很好,但是添加过滤器后,我在控制台中收到以下错误:

Uncaught TypeError: Cannot read property 'depth' of undefined 

您可以看到我d.targetlinkKey. 所以我不明白为什么d.target稍后当我尝试检查d.target.depth我知道所有元素都存在哪些时未定义?关于使用身份功能“获取”数据时会发生什么,我是否遗漏了什么?var link = links.selectAll("path.treeline").data( function(d){return d;} , linkKey);

再一次,这一切都很好,直到我添加该行.filter(function(d){return d.target.depth < leafDepth;})

这是我的图形绘制功能的主要部分(不包括随后的一堆 getter/setter)

Tree = function () {

    var width = 1000,  //default width
        height = 1000, //default height
        left = 0,
        top = 0,
        leafDepth = 5, // depth at which leaf nodes are at
        leafClick = function (d){return console.log(d);},
        linkKey, // key function for links
        pathGenerator = d3.svg.diagonal().projection( function(d) {  
                            return [d.x, height-d.y]; }),
        childrenKey = function(d) { 
                            return (!d.values || d.values.length === 0) ? null : d.values; },
        linkKey = function(d) { return d.source.key+"_"+d.target.key; }
    ;

    function chart(selection) {
        selection.each(function (d) {

            // setup layout
            var tree = d3.layout.tree()
                .size([width,height])
                .children( function(d) {
                    return (!d.values || d.values.length === 0) ? null : d.values;
                });

            var nodeData = tree.nodes(d);
            var linkData = tree.links(nodeData);

            // 'this' is the selection
            var links = d3.select(this).selectAll("g#links")
                .data( [linkData] );

            links.enter()
                .append("g")
                .attr("transform", "translate("+left+", "+top+")")
                .attr("id","links");

            var linkKey = function(d) { return d.source.key+"_"+d.target.key; }            
            var link = links.selectAll("path.treeline")
                .data( function(d){return d;} , linkKey);

            link.enter()
                .filter(function(d){return d.target.depth < leafDepth;}) // PROBLEM HERE !!
                .append("svg:path")
                .attr("class", "treeline")
                .attr("d", pathGenerator);

            link.transition()
                .attr("d", pathGenerator);

            link.exit()
                .remove();    

        });

        return chart;
    };

    // a bunch of getter/setters for the vars defined at top

    return chart; // this is using a version of the re-usable chart pattern by the way 
}
4

1 回答 1

0

将过滤器移动到数据分配是可行的,尽管这意味着它们已完全从join.

var linkLeafFilter = function(d){return d.target.depth < leafDepth;}
var link = links.selectAll("path.treeline")
                .data( function(d){return d.filter(linkLeafFilter);} , linkKey);
于 2012-10-23T00:28:26.123 回答