d3.layout.tree中的颜色路径

时间:2013-11-21 20:54:45

标签: javascript d3.js

我想基于直接位于最低级别上方的节点之一,在可折叠d3布局中为路径着色。显然,当扩展子节点正上方的一个节点时,只会有不同的颜色。

我正在使用d3js示例中的代码,只做了很小的修改:

function buildTree(data) {
        var margin = {top: 20, right: 120, bottom: 20, left: 120},
                width = 960 - margin.right - margin.left,
                height = 800 - margin.top - margin.bottom;
        var i = 0,
                duration = 750,
                root;
        var tree = d3.layout.tree()
                .size([height, width]);
        var diagonal = d3.svg.diagonal()
                .projection(function (d) {
                    return [d.y, d.x];
                });
        var svg = d3.select("#node").append("svg")
                .attr("width", width + margin.right + margin.left)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        root = data;
        root.x0 = height / 2;
        root.y0 = 0;
        function collapse(d) {
            if (d.children) {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }
        }
        root.children.forEach(collapse);
        update(root);
        d3.select(self.frameElement).style("height", "800px");
        function update(source) {
            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                    links = tree.links(nodes);
            // Normalize for fixed-depth.
            nodes.forEach(function (d) {
                d.y = d.depth * 180;
            });
            // Update the nodes…
            var node = svg.selectAll("g.node")
                    .data(nodes, function (d) {
                        return d.id || (d.id = ++i);
                    });
            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter().append("g")
                    .attr("class", "node")
                    .attr("transform", function (d) {
                        return "translate(" + source.y0 + "," + source.x0 + ")";
                    })
                    .on("click", click);
            nodeEnter.append("circle")
                    .attr("r", 1e-6)
                    .style("fill", function (d) {
                        return d._children ? "lightsteelblue" : "#fff";
                    });
            nodeEnter.append("text")
                    .attr("x", function (d) {
                        return d.children || d._children ? -10 : 10;
                    })
                    .attr("dy", "1em")
                    .attr("text-anchor", function (d) {
                        return d.children || d._children ? "end" : "start";
                    })
                    .text(function (d) {
                        return d.name;
                    })
                    .style("fill-opacity", 1e-6);
            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                    .duration(duration)
                    .attr("transform", function (d) {
                        return "translate(" + d.y + "," + d.x + ")";
                    });
            nodeUpdate.select("circle")
                    .attr("r", 4.5)
                    .style("fill", function (d) {
                        return d._children ? "lightsteelblue" : "#fff";
                    });

            nodeUpdate.select("text")
                    .style("fill-opacity", 1);
            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                    .duration(duration)
                    .attr("transform", function (d) {
                        return "translate(" + source.y + "," + source.x + ")";
                    })
                    .remove();
            nodeExit.select("circle")
                    .attr("r", 1e-4);
            nodeExit.select("text")
                    .style("fill-opacity", 1e-6);
            // Update the links…
            var link = svg.selectAll("path.link")
                    .data(links, function (d) {
                        return d.target.id;
                    });
            // Enter any new links at the parent's previous position.
            link.enter().insert("path", "g")
                    .attr("class", "link")
                    .attr("d", function (d) {
                        var o = {x: source.x0, y: source.y0};
                        return diagonal({source: o, target: o});
                    });
            // Transition links to their new position.
            link.transition()
                    .duration(duration)
                    .attr("d", diagonal);
            // Transition exiting nodes to the parent's new position.
            link.exit().transition()
                    .duration(duration)
                    .attr("d", function (d) {
                        var o = {x: source.x, y: source.y};
                        return diagonal({source: o, target: o});
                    })
                    .remove();
            // Stash the old positions for transition.
            nodes.forEach(function (d) {
                d.x0 = d.x;
                d.y0 = d.y;
            });
        }
        // Toggle children on click.
        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }
    }

“链接”颜色(我想要改变的颜色)来自一些定义的样式:

    .node {
        cursor: pointer;
    }

    .node circle {
        fill: #fff;
        stroke: steelblue;
        stroke-width: 2px;
    }

    .node text {
        font: 12px sans-serif;
        fill: white;
    }

    .link {
        fill: none;
        stroke: white;
        stroke-width: 1.5px;
    }

我在黑色背景上,所以我想保持颜色为红色,绿色,蓝色,白色等(可以看到黑色)。

2 个答案:

答案 0 :(得分:2)

您可以通过在代码中设置笔触颜色来动态地为链接着色。节点的深度(如果我正确理解的是你所追求的)是其数据的一部分,所以你可以直接引用它。

var color = d3.scale.category20();
// ...
link.transition()
    .duration(duration)
    .attr("d", diagonal)
    .style("stroke", function(d) { return color(d.source.depth); });

答案 1 :(得分:-1)

您可以在创建时设置link颜色,代码如下:

       link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("d", function (d) {
                    var o = {x: source.x0, y: source.y0};
                    return diagonal({source: o, target: o});
                })
                .attr("stroke", function (d) { return 'blue'; }) 
                               // ^^ return your color here.

然后,您可以安全地删除stroke .link的CSS定义。