d3垂直树-向路径添加标签

时间:2018-08-04 00:48:40

标签: d3.js

我正在基于http://bl.ocks.org/d3noob/8326869制作d3 v4垂直树形图,并且尝试在路径中添加文本标签(例如,是,否等)。到目前为止,这是链接部分中的代码:

function update (source) {
    // Assigns the x and y position for the nodes
    var treeData = treemap(root);

    // Compute the new tree layout.
    var nodes = treeData.descendants(),
        links = treeData.descendants().slice(1);

    // Normalize for fixed-depth.
    nodes.forEach(function (d) {
        d.y = d.depth * 95
    });

    // ****************** Nodes section ***************************

    // Update the nodes...
    var node = svg.selectAll('g.node')
    .data(nodes, function (d) {
        return d.id || (d.id = ++i);
    });

    // Enter any new modes at the parent's previous position.
    var nodeEnter = node.enter().append('g')
    .attr('class', 'node')
    .attr("transform", function (d) {
        return "translate(" + source.x0 + "," + source.y0 + ")";
    })
    .attr("data-info", function (d) { return d.data.info })
    .on('click', click);

    // Add Circle for the nodes
    /*nodeEnter.append('circle')
    .attr('class', 'node')
    .attr("id", function(d){return "node" + d.id;})//id of the node.
    .attr('r', 1e-6)
    .style("fill", function (d) {
        return d._children ? "lightsteelblue" : "#fff";
    });*/
    nodeEnter.append('rect')
    .attr('class', 'node')
    .attr('width', 170)
    .attr('height', 55)
    .attr('x', -85)
    .attr('y', -22)
    .attr('rx',7) //rounding
    .attr('ry',7)
    .attr("id", function(d){return "node" + d.id;});//id of the node.

    nodeEnter.append('text')
    //.attr("dy", ".25em")
    //.attr('x', -23)
    .attr('class', 'node-text')
    .attr("text-anchor", "middle")
    .text(function (d) {
        return d.data.name;
    })
    .call(wrap, 165);

    // UPDATE
    var nodeUpdate = nodeEnter.merge(node);

    // Transition to the proper position for the node
    nodeUpdate.transition()
    .duration(duration)
    .attr("transform", function (d) {
        return "translate(" + d.x + "," + d.y + ")";
    });

    // Update the node attributes and style
    nodeUpdate.select('rect.node')
    .style("fill", function (d) {
        if (d._children) {
            return "#007bff"; // dark blue
        }
    })
    .attr('cursor', 'pointer');

    // Remove any exiting nodes
    var nodeExit = node.exit().transition()
    .duration(duration)
    .attr("transform", function (d) {
        return "translate(" + source.x + "," + source.y + ")";
    })
    .remove();

    // On exit reduce the node circles size to 0
    nodeExit.select('circle')
    .attr('r', 1e-6);

    // On exit reduce the opacity of text labels
    nodeExit.select('text')
    .style('fill-opacity', 1e-6);

    // ****************** links section ***************************

    // Update the links...
    var link = svg.selectAll('path.link')
    .data(links, function (d) {
        return d.id;
    });

    // Enter any new links at the parent's previous position.
    var linkEnter = link.enter().insert('path', 'g')
    .attr("id", function(d){ return ("link" + d.id)})//unique id
    .attr("class", "link")
    .attr('d', function (d) {
        var o = {x: source.x0, y: source.y0}
        return diagonal(o, o);
    });

    // UPDATE
    var linkUpdate = linkEnter.merge(link);

    var linkLabel = link.enter().insert("text","g")
    .attr("class", "link2")
    .attr("id", function(d){ return ("link-label" + d.id)})//unique id
    .attr("dx",function(d){ return (d.parent.x + d.x)/2 })
    .attr("dy",function(d){ return (d.parent.y + d.y)/2 })
    .text(function(d) {
        if (d.data.label === "Yes") {
            this.setAttribute("x",-30);
        } else {
            this.setAttribute("x",10);
        }
        return d.data.label;
    });

    linkUpdate.merge(linkLabel);

    // Transition back to the parent element position
    linkUpdate.transition()
    .duration(duration)
    .attr('d', function (d) {
        svg.select("#link-label" + d.id).transition().duration(duration).attr("dx",function(d){ return (d.parent.x + d.x)/2 })
        .attr("dy",function(d){ return (d.parent.y + d.y)/2});
        return diagonal(d, d.parent)
    });

    // Remove any exiting links
    var linkExit = link.exit().transition()
    .duration(duration)
    .attr('d', function (d) {
        var o = {x: source.x, y: source.y};
        svg.selectAll("#link-label" + d.id).remove();
        return diagonal(o, o)
    })
    .remove();

    // Store the old positions for transition.
    nodes.forEach(function (d) {
        d.x0 = d.x;
        d.y0 = d.y;
    });

“ linkEnter.insert(“ text”,“ g”)“部分是我遇到麻烦的地方。看起来它一直在追加到元素上,而不是成为同级元素,因此它根本不会显示,而且我不确定如何编码,以使其不是的子元素,而在节点是隐藏/显示的。

在设法解决上述问题后,我也不知道如何设置坐标,以使文本标签位于路径的中间(或至少靠近路径)。

我尝试在节点部分中添加类似的代码,但是似乎很难找到正确的位置以与路径对齐。

========= 编辑:我已经更新了代码,因为它现在似乎正在工作。我创建了linkLabel,它从JSON变量中提取数据。它的位置靠近路径,但不重叠。动画不流畅,但至少看起来可以正常工作。

0 个答案:

没有答案