代码之家  ›  专栏  ›  技术社区  ›  alQemist

D3向定向布局中的节点添加文本列表

  •  0
  • alQemist  · 技术社区  · 4 年前

    我成功地创建了forceDirect布局,每个节点都有一行文本作为标签。现在我有一个项目,我需要向每个节点添加一个列表(多个文本)。

    我已经能够使用同一个模型添加多个文本,该模型可以为每个节点添加一个标签和一个标签。

    标签、矩形和多行文字分别添加到单独的节点,但只有文字列表不会“固定”到节点。

                var node = svg.append("g")
                .attr("transform", "translate("+[margin.left, margin.top]+")")
                .attr("class", "nodes")
                .selectAll("rect")
                .data(data.nodes)
                .enter()
                .append("rect")
                .style("width",function(d){
                    return setRectWidth(d)
                })
                .style("height",function(d){
                    return 30
                })
                .attr("fill",function(d){
                    return setBackground(d)
                })
                //.attr("x",0)
                .attr("rx",4)
                .attr("ry",4)
                .call(d3.drag()
                    .on("start", dragstarted)
                    .on("drag", dragged)
                    .on("end", dragended))
    
    
            var text = svg.append("g")
                .attr("class", "text")
                .selectAll("txt")
                .data(data.nodes)
                .enter()
                .append("text")
                .attr("x", 0)
                .text(function(d){
                    return d.label
                })
                .style("text-anchor","middle")
                .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended));
    
    
    
            var subtext = svg.append("g")
                .attr("class", "subtext")
                .selectAll("subtext")
                .data(data.node_items)
                .enter()
                .append("text")
                .attr("x", 0)
                .text(function(d){
                    return d.label
                })
                .style("text-anchor","middle")
                .call(d3.drag()
                .on("start", dragstarted)
                .on("drag", dragged)
                .on("end", dragended));
    

    以下是原始结果

    enter image description here

    注:潜文本未指定xy

    以下是我想要的:

    enter image description here

    在我看来,勾号功能还可以,所以我不知道我缺少了什么。

     var ticked = function() {
    
     node
     .attr("x", function(d) { return  d.x + setRectWidth(d)*-.5; })
     .attr("y", function(d) { return d.y + setRectHeight(d)*-.5 });
    
     link
     .attr("d", function(d) {
     var a = []
     a.push({x: d.source.x,y:d.source.y});
     a.push({x: d.target.x,y:d.target.y});
     return line(a)
     })
    
     text
     .attr("x", function(d) { return  d.x  })
     .attr("y", function(d) { return d.y + setTextY(d)  });
    
     subtext
     .attr("x", function(d) { return  d.x  })
     .attr("y", function(d) { return d.y  });
    
    }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   alQemist    3 年前

    我提出的解决方案是将列表时间作为节点项添加到每个节点,然后使用勾选函数迭代列表,并根据项目索引重新分配x、y位置。

    var ticked = function(){.....
    
    nodeitems.attr("x", function (d) {
                    let new_x = d.fixed_x ? d.fixed_x : d.x;
                    return new_x - setRectWidth(d) * .4;
                })
                .attr("y", function (d, i) {
                    let new_y = d.fixed_y ? d.fixed_y : d.y;
                    return new_y + (i * row_height) + setTextY(d) + row_height + 5
                });
    

    你可以在这里看到有效的解决方案- https://alqemist.github.io/EAGIR/erd/

    源代码在这里-看看erd文件夹 https://github.com/alQemist/EAGIR