为D3网络添加标签

问题描述 投票:0回答:1

我是D3新手,正在玩D3网络图。我可以成功地创建一个网络图,并使其可以拖动,但我无法为节点添加标签。我找了一下答案,我觉得我的代码应该可以用。下面是代码。

注意:网络的布局在这里没有正确地呈现出来(但节点可以拖动以看到正确的布局),但当它在完整的网页上运行时,它正确地呈现出来(没有标签)。

请指出我哪里做错了。

非常感谢。

亚历克斯

var data = {
  "name": "A1",
  "children": [{
      "name": "B1",
      "children": [{
          "name": "C1",
          "value": 100
        },
        {
          "name": "C2",
          "value": 300
        },
        {
          "name": "C3",
          "value": 200
        }
      ]
    },
    {
      "name": "B2",
      "value": 200
    }
  ]
};

var root = d3.hierarchy(data);

function dragged(d) {
  d.x = d3.event.x, d.y = d3.event.y;
  d3.select(this).attr("cx", d.x).attr("cy", d.y);
  link.filter(function(l) {
    return l.source === d;
  }).attr("x1", d.x).attr("y1", d.y);
  link.filter(function(l) {
    return l.target === d;
  }).attr("x2", d.x).attr("y2", d.y);
}

// Nodes
var node = d3.select('#network g.nodes')
  .selectAll('circle.node')
  .data(root.descendants())
  .enter()
  .append('circle')
  .classed('node', true)
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', 4)
  .each(function(d) {
    console.log(d);
    d3.select(this)
      .append('text')
      .text(d.data.name);
  })
  .call(d3.drag().on("drag", dragged));


// Links
var link = d3.select('#network g.links')
  .selectAll('line.link')
  .data(root.links())
  .enter()
  .append('line')
  .classed('link', true)
  .attr('x1', function(d) {
    return d.source.x;
  })
  .attr('y1', function(d) {
    return d.source.y;
  })
  .attr('x2', function(d) {
    return d.target.x;
  })
  .attr('y2', function(d) {
    return d.target.y;
  });

/* 
  node.append("text")
     .attr("dx", 12)
     .attr("dy", ".35em")
     .text(function(d) { 
   	  console.log(d); 
   	  return d.data.name;
});
*/
circle {
  cursor: pointer;
}

.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 1px;
}

svg text {
  color: #000;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.2/d3.min.js"></script>
<svg id="network" width="400" height="220">
  <g transform="translate(20, 5)">
    <g class="links"></g>
    <g class="nodes"></g>
  </g>
</svg>
javascript d3.js
1个回答
2
投票

下面是@AndrewReid建议的示例。该 textcircle 归入和 <g> 元素。函数 dragged 更新 transform 的属性。

var data = {
  "name": "A1",
  "children": [
    {
      "name": "B1",
      "children": [
        {
          "name": "C1",
          "value": 100
        },
        {
          "name": "C2",
          "value": 300
        },
        {
          "name": "C3",
          "value": 200
        }
      ]
    },
    {
      "name": "B2",
      "value": 200
    }
  ]
};

var root = d3.hierarchy(data);

function dragged(d) {
  // Get coords relative to svg
  [d.x, d.y] = d3.mouse(this.parentNode.parentNode);
  d3.select(this.parentNode).attr("transform", 'translate(' + d.x + ',' + d.y + ')');

  link.filter(function(l) {
    return l.source === d;
  }).attr("x1", d.x).attr("y1", d.y);
  link.filter(function(l) {
    return l.target === d;
  }).attr("x2", d.x).attr("y2", d.y);
}

// Nodes
var nodeg = d3.select('#network g.nodes')
  .selectAll('circle.node')
  .data(root.descendants())
  .enter()
  .append('g');

nodeg.append('circle')
  .classed('node', true)
  .attr('cx', function(d) {
    return d.x;
  })
  .attr('cy', function(d) {
    return d.y;
  })
  .attr('r', 4)
  .each(function(d) {
    d3.select(this)
      .append('text')
      .text(d.data.name);
  })
  .call(d3.drag().on("drag", dragged));

// Links
var link = d3.select('#network g.links')
  .selectAll('line.link')
  .data(root.links())
  .enter()
  .append('line')
  .classed('link', true)
  .attr('x1', function(d) {
    return d.source.x;
  })
  .attr('y1', function(d) {
    return d.source.y;
  })
  .attr('x2', function(d) {
    return d.target.x;
  })
  .attr('y2', function(d) {
    return d.target.y;
  });

var texts = nodeg.append("text")
  .attr("dx", 12)
  .attr("dy", ".35em")
  .text(function(d) {
    //console.log(d); 
    return d.data.name;
  });
circle {
  cursor: pointer;
}

.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 1px;
}

svg text {
  color: #000;
  cursor: pointer;
}
<svg id="network" width="400" height="220">
  <g transform="translate(20, 5)">
    <g class="links"></g>
    <g class="nodes"></g>
  </g>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.2/d3.min.js"></script>

0
投票

根据@AndrewReid的评论,我修改了以下代码,工作正常。基本上,我需要打破链锁,使不同的元素附加到合适的父元素。

var node = d3.select('#network g.nodes')
  .selectAll('circle.node')
  .data(root.descendants())
  .enter()
  .append('g');

var circle = node.append('circle')
.classed('node', true)
.attr('cx', function(d) {return d.x;})
.attr('cy', function(d) {return d.y;})
.attr('r', 6)
.call(d3.drag().on("drag", dragged))
;


// Links
var link = d3.select('#network g.links')
.selectAll('line.link')
.data(root.links())
.enter()
.append('line')
.classed('link', true)
.attr('x1', function(d) {return d.source.x;})
.attr('y1', function(d) {return d.source.y;})
.attr('x2', function(d) {return d.target.x;})
.attr('y2', function(d) {return d.target.y;});


var text= node.append("text")
.attr('x', function(d) {return d.x;})
.attr('y', function(d) {return d.y;})
.attr("dx", 12)
.attr("dy", ".25em")
.text(function(d) {   
    return d.data.name;
});

function dragged(d) {
    d.x = d3.event.x, d.y = d3.event.y;
    d3.select(this).attr("cx", d.x).attr("cy", d.y);
    text
     .attr('x', function(d) {return d.x;})
     .attr('y', function(d) {return d.y;})
    link.filter(function(l) {return l.source === d; }).attr("x1", 
      d.x).attr("y1", d.y);
    link.filter(function(l) { return l.target === d; }).attr("x2", 
      d.x).attr("y2", d.y);
}
© www.soinside.com 2019 - 2024. All rights reserved.