在 d3.js 中创建强制布局节点标签 [英] Creating force layout node labels in d3.js

查看:27
本文介绍了在 d3.js 中创建强制布局节点标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有彩色节点的力图,我正在尝试向其中添加标签.现在它有标签,但它是浏览器原生的小而难以阅读的标签.我将如何添加更易于查看的标签?

I have a force graph with colored nodes that I am trying to add labels to. Right now it has labels, but it's the small, hard to read ones native to the browser. How would I add labels that are easier to see?

 <svg width="960" height="600"></svg>
 <script>
    var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory10);

var simulation = d3.forceSimulation()
 .force("link", d3.forceLink().id(function(d) { return d.id; }))
 .force("charge", d3.forceManyBody())
 .force("center", d3.forceCenter(width / 2, height / 2));

d3.json("got_relationships.json", function(error, graph) {
 if (error) throw error;

var link = svg.append("g")
  .attr("class", "links")
  .selectAll("line")
 .data(graph.links)
 .enter().append("line")
  .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = svg.append("g")
   .attr("class", "nodes")
  .selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 5)
  .attr("fill", function(d) { return color(d.group); })
  .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));

 node.append("title")
    .text(function(d) { return d.id; });

 simulation
   .nodes(graph.nodes)
   .on("tick", ticked);

 simulation.force("link")
   .links(graph.links);

 function ticked() {
   link
    .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
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });
   }
  });

 function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
  }

 function dragged(d) {
   d.fx = d3.event.x;
   d.fy = d3.event.y;
 }

 function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
 }
 </script>

推荐答案

标签"和工具提示"之间存在混淆.传统上,我们将在没有用户交互的情况下显示在节点旁边的文本命名为标签",而将用户与节点交互(例如,悬停节点)时显示的文本命名为工具提示".

There is a confusion between "labels" and "tooltips". Traditionally, we name "labels" the texts that show up next to the nodes without user interaction, and we name "tooltips" the texts that show up when the user interacts with the nodes (for instance, hovering the nodes).

因此,如果您的意思是标签",这是一个解决方案:将节点附加为组...

So, if you mean "labels", this is a solution: append the nodes as groups...

var node = svg.selectAll(".node")
    .data(graph.nodes)
    .enter().append("g")
    .attr("class", "node")
    .call(d3.drag().on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));

并将圆圈和标签(作为 元素)附加到它们:

And append the circles and the labels (as <text> elements) to them:

node.append("circle")
    .attr("r", 5)
    .attr("fill", function(d) { return color(d.group); });

node.append("text")
    .attr("dx", 6)
    .text(function(d) { return d.id; });

这是一个使用(大部分)代码的演示,其中包含一个虚构的数据:

Here is a demo using (most of) your code, with a made up data:

var graph = {
nodes:[
	{"id": "A", "group": 1},
	{"id": "B", "group": 2},
	{"id": "C", "group": 2},
	{"id": "D", "group": 2},
	{"id": "E", "group": 2},
	{"id": "F", "group": 3},
	{"id": "G", "group": 3},
	{"id": "H", "group": 3},
	{"id": "I", "group": 3}
],
links:[
{"source": "A", "target": "B", "value": 1},
{"source": "B", "target": "C", "value": 1},
{"source": "A", "target": "D", "value": 1},
{"source": "H", "target": "E", "value": 1},
{"source": "I", "target": "F", "value": 1},
{"source": "A", "target": "G", "value": 1},
{"source": "B", "target": "H", "value": 1},
{"source": "A", "target": "I", "value": 1},
]
};

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory20);

var simulation = d3.forceSimulation()
 .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(40))
 .force("charge", d3.forceManyBody())
 .force("center", d3.forceCenter(width / 2, height / 2));

var link = svg.append("g")
  .attr("class", "links")
  .selectAll("line")
 .data(graph.links)
 .enter().append("line")
  .attr("stroke-width", function(d) { return Math.sqrt(d.value); });


var node = svg.selectAll(".node")
            .data(graph.nodes)
            .enter().append("g")
						.attr("class", "node")
             .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended));
						
node.append("circle")
  .attr("r", 5)
  .attr("fill", function(d) { return color(d.group); });

 node.append("text")
 	.attr("dx", 6)
    .text(function(d) { return d.id; });

 simulation
   .nodes(graph.nodes)
   .on("tick", ticked);

 simulation.force("link")
   .links(graph.links);

 function ticked() {
   link
    .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.attr("transform", function(d) {
                return "translate(" + d.x + "," + d.y + ")";
            });
   }

 function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
  }

 function dragged(d) {
   d.fx = d3.event.x;
   d.fy = d3.event.y;
 }

 function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
 }

.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.node circle {
  stroke: #fff;
  stroke-width: 1.5px;
}

.node text{
	fill: #666;
	font-family: Helvetica
}

<svg width="400" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>

这篇关于在 d3.js 中创建强制布局节点标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆