d3 力图,根据连接链接的数量有条件地渲染节点

d3 force graph, conditionally rendering nodes depending on amount of connected links

我有一个力导向图,其中节点的大小取决于它们连接的链接数量。

我想做的是: 使节点有条件地呈现,以便“d.weight”小于 21 的节点附加一个文本元素,那些等于或大于 21 的节点附加一个圆形元素。

下面是我的代码不起作用。问题可能来自“测试”变量。 任何帮助都非常受欢迎

        var node = g
        .selectAll(".circle-group")
        .data(nodes)
        .join(enter => {
          node = enter.append("g")        
          .attr("class", "circle-group")


          var test = function(d){ link.filter(function(l) {
          return l.source.index == d.index || l.target.index == d.index
          }).size();  }


            //NODE BACKGROUND CIRCLE
          node.append("circle")
          .attr("class", "background") 
          .style("fill", "#e7c203")
          .attr("r", function(d) {     
          d.weight = link.filter(function(l) {
          return l.source.index == d.index || l.target.index == d.index
          }).size();      
          if(d.weight < 2){return "2px"}
          else if(d.weight >= 2 && d.weight < 6){return "5px"}
          else if(d.weight >= 6 && d.weight < 21){return "10px"}
          else if(d.weight >= 21){return "15px"}
          else{return "200px"}
          })
           
           //NODE TEXT FOREGROUND
          if(test < 21){ 
            node.append("text")
            .attr("text-anchor", "middle")
            .attr("dominant-baseline", "central") 
            .text(function(d){return d.id})
            .attr("fill", "white")
            .attr('stroke', 'white')
            .attr('stroke-width', '0.1px')
            .attr("y", -7)
            .style("font-size", "5px")

          //NODE IMAGE FOREGROUND
          }else{ 
            node.append("circle")
            .attr("class", "foreground") 
            .style("fill", d => `url(#${d.id})`)
            .attr("r", function(d) {      
            d.weight = link.filter(function(l) {
            return l.source.index == d.index || l.target.index == d.index
            }).size();      
            if(d.weight < 2){return "2px"}
            else if(d.weight >= 2 && d.weight < 6){return "5px"}
            else if(d.weight >= 6 && d.weight < 21){return "10px"}
            else if(d.weight >= 21){return "15px"}
            else{return "200px"}
            }) 
          }
            
          node.attr("stroke", "#e7c203").call(drag(simulation));
        })

好吧,我终于自己弄明白了。

诀窍是过滤节点,然后附加所需的元素。 在我的例子中,因为我想附加不同的元素,我不得不过滤两次(每个条件一次)

下面是固定代码:


var node = g
        .selectAll(".circle-group")
        .data(nodes)
        .join(enter => {
          node = enter.append("g")        
          .attr("class", "circle-group")


          var test = function(d){ link.filter(function(l) {
          return l.source.index == d.index || l.target.index == d.index
          }).size();  }


            //NODE BACKGROUND CIRCLE
          node.append("circle")
          .attr("class", "background") 
          .style("fill", "#e7c203")
          .attr("r", function(d) {     
          d.weight = link.filter(function(l) {
          return l.source.index == d.index || l.target.index == d.index
          }).size();      
          if(d.weight < 2){return "2px"}
          else if(d.weight >= 2 && d.weight < 6){return "5px"}
          else if(d.weight >= 6 && d.weight < 21){return "10px"}
          else if(d.weight >= 21){return "15px"}
          else{return "200px"}
          })
           
           //NODE TEXT FOREGROUND
             node.filter(function(d){ return d.weight<6 }).append("text")
            .attr("text-anchor", "middle")
            .attr("dominant-baseline", "central") 
            .text(function(d){return d.id})
            .attr("fill", "white")
            .attr('stroke', 'white')
            .attr('stroke-width', '0.1px')
            .attr("y", -7)
            .style("font-size", "5px")

          //NODE IMAGE FOREGROUND
         node.filter(function(d){ return d.weight>5 }).append("circle")
            .attr("class", "foreground") 
            .style("fill", d => `url(#${d.id})`)
            .attr("r", function(d) {      
            d.weight = link.filter(function(l) {
            return l.source.index == d.index || l.target.index == d.index
            }).size();      
            if(d.weight < 2){return "2px"}
            else if(d.weight >= 2 && d.weight < 6){return "5px"}
            else if(d.weight >= 6 && d.weight < 21){return "10px"}
            else if(d.weight >= 21){return "15px"}
            else{return "200px"}
            }) 
          
            
          node.attr("stroke", "#e7c203").call(drag(simulation));
        })