无法将标签添加到d3js强制布局网络可视化

2024-04-20 11:47:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在努力用d3js在一个force-directed-layout网络可视化中实现标签(我使用Python和Flask从API生成一个JSON文件并在网页中呈现viz)。在

我看过很多例子,比如。。。在

http://bl.ocks.org/mbostock/2706022

http://bl.ocks.org/mbostock/1153292

http://bl.ocks.org/MoritzStefaner/1377729

。。。但我对Javascript还很陌生,所以很难将这些代码重新实现到当前代码中:

我一直使用的JSON文件是:

{"directed": true, "graph": [], "nodes": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}, {"id": "user4"}, {"id": "user5"}, {"id": "user6"}, {"id": "user7"}, {"id": "user8"}, {"id": "user9"}, {"id": "user10"}, {"id": "user11"}, {"id": "user12"}, {"id": "user13"}, {"id": "user14"}, {"id": "user15"}, {"id": "user16"}, {"id": "user17"}, {"id": "user18"}, {"id": "user19"}, {"id": "user20"}, {"id": "user21"}, {"id": "user22"}, {"id": "myaccount"}, {"id": "user23"}, {"id": "user24"}, {"id": "user25"}, {"id": "user26"}, {"id": "user27"}, {"id": "user28"}, {"id": "user29"}, {"id": "user30"}, {"id": "user31"}, {"id": "user32"}, {"id": "user33"}, {"id": "user34"}, {"id": "user35"}, {"id": "user36"}, {"id": "user37"}, {"id": "user38"}, {"id": "user39"}, {"id": "user40"}, {"id": "user41"}, {"id": "user42"}, {"id": "user43"}, {"id": "user44"}, {"id": "user45"}, {"id": "user46"}, {"id": "user47"}, {"id": "user48"}, {"id": "user49"}, {"id": "user50"}, {"id": "user51"}, {"id": "user52"}, {"id": "user53"}, {"id": "user54"}, {"id": "user55"}, {"id": "user56"}, {"id": "user57"}, {"id": "user58"}, {"id": "user59"}, {"id": "user60"}, {"id": "user61"}, {"id": "user62"}, {"id": "user63"}, {"id": "user64"}, {"id": "user65"}, {"id": "user66"}, {"id": "user67"}, {"id": "user68"}, {"id": "user69"}, {"id": "user70"}, {"id": "user71"}, {"id": "user72"}, {"id": "user73"}, {"id": "user74"}, {"id": "user75"}, {"id": "user76"}, {"id": "user77"}, {"id": "user78"}, {"id": "user79"}, {"id": "user80"}, {"id": "user81"}, {"id": "user82"}, {"id": "user83"}, {"id": "user84"}, {"id": "user85"}, {"id": "user86"}, {"id": "user87"}, {"id": "user88"}, {"id": "user89"}, {"id": "user90"}, {"id": "user91"}, {"id": "user92"}, {"id": "user93"}, {"id": "user94"}, {"id": "user95"}, {"id": "user96"}, {"id": "user97"}, {"id": "user98"}, {"id": "user99"}, {"id": "user100"}, {"id": "user101"}, {"id": "user102"}, {"id": "cuser103"}, {"id": "user104"}, {"id": "user105"}, {"id": "user106"}, {"id": "user107"}, {"id": "user108"}, {"id": "user109"}, {"id": "user110"}, {"id": "user111"}, {"id": "user112"}, {"id": "user113"}, {"id": "user114"}, {"id": "user115"}, {"id": "user116"}, {"id": "user117"}, {"id": "user118"}, {"id": "user119"}, {"id": "user120"}, {"id": "user121"}, {"id": "user122"}, {"id": "user123"}, {"id": "user124"}, {"id": "user125"}, {"id": "user126"}, {"id": "user127"}, {"id": "user128"}, {"id": "user129"}, {"id": "user130"}, {"id": "user131"}], "links": [{"source": 22, "target": 72, "weight": 1}, {"source": 22, "target": 65, "weight": 3}, {"source": 22, "target": 115, "weight": 1}, {"source": 22, "target": 56, "weight": 1}, {"source": 22, "target": 106, "weight": 1}, {"source": 22, "target": 124, "weight": 3}, {"source": 22, "target": 48, "weight": 1}, {"source": 22, "target": 101, "weight": 1}, {"source": 22, "target": 111, "weight": 1}, {"source": 22, "target": 64, "weight": 4}, {"source": 22, "target": 112, "weight": 1}, {"source": 22, "target": 71, "weight": 1}, {"source": 48, "target": 121, "weight": 1}, {"source": 48, "target": 114, "weight": 1}, {"source": 48, "target": 34, "weight": 1}, {"source": 48, "target": 28, "weight": 1}, {"source": 48, "target": 43, "weight": 1}, {"source": 48, "target": 52, "weight": 1}, {"source": 48, "target": 64, "weight": 1}, {"source": 56, "target": 101, "weight": 1}, {"source": 56, "target": 9, "weight": 1}, {"source": 56, "target": 50, "weight": 1}, {"source": 56, "target": 85, "weight": 1}, {"source": 64, "target": 51, "weight": 1}, {"source": 64, "target": 46, "weight": 1}, {"source": 64, "target": 104, "weight": 1}, {"source": 64, "target": 122, "weight": 1}, {"source": 64, "target": 20, "weight": 2}, {"source": 64, "target": 2, "weight": 1}, {"source": 64, "target": 23, "weight": 1}, {"source": 64, "target": 94, "weight": 1}, {"source": 64, "target": 60, "weight": 1}, {"source": 64, "target": 6, "weight": 1}, {"source": 64, "target": 89, "weight": 1}, {"source": 64, "target": 96, "weight": 1}, {"source": 64, "target": 131, "weight": 3}, {"source": 64, "target": 50, "weight": 1}, {"source": 65, "target": 73, "weight": 2}, {"source": 65, "target": 90, "weight": 1}, {"source": 65, "target": 11, "weight": 3}, {"source": 65, "target": 1, "weight": 3}, {"source": 65, "target": 29, "weight": 4}, {"source": 65, "target": 13, "weight": 1}, {"source": 65, "target": 83, "weight": 1}, {"source": 65, "target": 78, "weight": 1}, {"source": 65, "target": 88, "weight": 1}, {"source": 65, "target": 113, "weight": 2}, {"source": 65, "target": 63, "weight": 1}, {"source": 71, "target": 10, "weight": 1}, {"source": 72, "target": 98, "weight": 3}, {"source": 72, "target": 123, "weight": 1}, {"source": 72, "target": 91, "weight": 1}, {"source": 72, "target": 12, "weight": 1}, {"source": 72, "target": 107, "weight": 1}, {"source": 72, "target": 7, "weight": 2}, {"source": 72, "target": 36, "weight": 4}, {"source": 72, "target": 128, "weight": 4}, {"source": 72, "target": 129, "weight": 1}, {"source": 72, "target": 38, "weight": 2}, {"source": 101, "target": 69, "weight": 1}, {"source": 101, "target": 119, "weight": 1}, {"source": 101, "target": 82, "weight": 1}, {"source": 101, "target": 21, "weight": 1}, {"source": 101, "target": 116, "weight": 1}, {"source": 101, "target": 125, "weight": 1}, {"source": 101, "target": 4, "weight": 1}, {"source": 101, "target": 109, "weight": 1}, {"source": 101, "target": 64, "weight": 2}, {"source": 101, "target": 53, "weight": 1}, {"source": 101, "target": 130, "weight": 1}, {"source": 101, "target": 102, "weight": 1}, {"source": 101, "target": 32, "weight": 1}, {"source": 101, "target": 80, "weight": 1}, {"source": 101, "target": 62, "weight": 1}, {"source": 106, "target": 103, "weight": 1}, {"source": 106, "target": 84, "weight": 1}, {"source": 106, "target": 66, "weight": 1}, {"source": 106, "target": 67, "weight": 1}, {"source": 106, "target": 87, "weight": 1}, {"source": 106, "target": 15, "weight": 1}, {"source": 106, "target": 126, "weight": 2}, {"source": 106, "target": 74, "weight": 1}, {"source": 106, "target": 127, "weight": 1}, {"source": 106, "target": 42, "weight": 4}, {"source": 106, "target": 5, "weight": 1}, {"source": 106, "target": 77, "weight": 2}, {"source": 106, "target": 79, "weight": 1}, {"source": 106, "target": 118, "weight": 1}, {"source": 111, "target": 92, "weight": 1}, {"source": 111, "target": 54, "weight": 1}, {"source": 111, "target": 55, "weight": 1}, {"source": 111, "target": 95, "weight": 1}, {"source": 111, "target": 41, "weight": 2}, {"source": 111, "target": 3, "weight": 1}, {"source": 111, "target": 93, "weight": 3}, {"source": 111, "target": 76, "weight": 1}, {"source": 111, "target": 49, "weight": 1}, {"source": 111, "target": 99, "weight": 1}, {"source": 111, "target": 44, "weight": 1}, {"source": 111, "target": 61, "weight": 1}, {"source": 111, "target": 117, "weight": 2}, {"source": 111, "target": 81, "weight": 1}, {"source": 111, "target": 97, "weight": 1}, {"source": 112, "target": 26, "weight": 1}, {"source": 112, "target": 8, "weight": 1}, {"source": 112, "target": 39, "weight": 1}, {"source": 112, "target": 45, "weight": 1}, {"source": 112, "target": 57, "weight": 1}, {"source": 112, "target": 47, "weight": 1}, {"source": 112, "target": 108, "weight": 1}, {"source": 112, "target": 37, "weight": 5}, {"source": 112, "target": 17, "weight": 1}, {"source": 112, "target": 31, "weight": 1}, {"source": 112, "target": 131, "weight": 4}, {"source": 112, "target": 94, "weight": 1}, {"source": 115, "target": 18, "weight": 3}, {"source": 115, "target": 19, "weight": 1}, {"source": 115, "target": 33, "weight": 1}, {"source": 115, "target": 30, "weight": 1}, {"source": 115, "target": 110, "weight": 1}, {"source": 115, "target": 70, "weight": 1}, {"source": 124, "target": 120, "weight": 1}, {"source": 124, "target": 0, "weight": 1}, {"source": 124, "target": 40, "weight": 1}, {"source": 124, "target": 105, "weight": 1}, {"source": 124, "target": 35, "weight": 1}, {"source": 124, "target": 27, "weight": 1}, {"source": 124, "target": 86, "weight": 3}, {"source": 124, "target": 68, "weight": 1}, {"source": 124, "target": 14, "weight": 1}, {"source": 124, "target": 58, "weight": 1}, {"source": 124, "target": 24, "weight": 1}, {"source": 124, "target": 25, "weight": 1}, {"source": 124, "target": 100, "weight": 1}, {"source": 124, "target": 59, "weight": 1}, {"source": 124, "target": 75, "weight": 2}, {"source": 124, "target": 16, "weight": 2}], "multigraph": false}

而目前生成无标签可视化的代码是:

^{pr2}$

您也可以看到一些(注释掉的)代码,这些代码基于前面的问题,如D3.js, force-graph, cannot display text/label of nodes

感谢任何帮助!在


解决方案:下面的最终代码有效。在

<script src="http://d3js.org/d3.v3.min.js"></script>

<script>
var width = 500, height = 450;

var svg = d3.select("div").append("svg");

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

svg.attr("width", width)
    .attr("height", height);

d3.json("static/reblognetwork_{{ session_username }}.json", function(error, graph) {
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

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

  var node = svg.selectAll("g.node")
      .data(graph.nodes);
  var nodeEnter = node.enter()
      .append("g")
      .attr("class", "node")
      .call(force.drag);
  nodeEnter.append("circle")
      .attr("r", 5)
      .style("fill", function(d) { return color(d.group); })
      .call(force.drag);

  nodeEnter.append("text")
     .attr("dx", 5)
     .style("text-anchor", "start")
     .text(function(d) { return d.id; });

  force.on("tick", function() {
    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] + ")";
    });
  });
};


</script>

<div id="networkgraph"></div>

Tags: 代码svgidsourcetargetreturnvarfunction
2条回答

当为一个节点添加多个元素时,通常最好使用一个g元素,该元素的位置由您设置,并包含所有其他元素,就像您链接到的第一个示例中一样。在你的例子中,这可能看起来像下面这样。在

var node = svg.selectAll("g.node")
  .data(graph.nodes);
var nodeEnter = node.enter()
  .append("g")
  .attr("class", "node")
  .call(force.drag);
nodeEnter.append("circle")
  .attr("r", 5)
  .style("fill", function(d) { return color(d.group); })
  .call(force.drag);
nodeEnter.append("text")
 .attr("dx", 5)
 .style("text-anchor", "start")
 .text(function(d) { return d.id; });

完成演示here。在

我不擅长故障排除,但我将代码插入JSFiddle中,节点就会呈现(尽管不是链接)。在

也许这和你传递的数据有关?在本例中,我插入了Les Miserables数据进行测试(因此,我所做的唯一更改就是去掉d3.json调用并调整节点文本的大小)。在

http://jsfiddle.net/JA4kD/1/

var width = 500,
    height = 450;

var svg = d3.select("#networkgraph").append("svg");

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

svg.attr("width", width)
    .attr("height", height);

force.nodes(graph.nodes)
    .links(graph.links)
    .start();

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

var node = svg.selectAll("g.node")
    .data(graph.nodes);

var nodeEnter = node.enter()
    .append("g")
    .attr("class", "node")
    .call(force.drag);

nodeEnter.append("circle")
    .attr("r", 5)
    .style("fill", function (d) { return color(d.group); })
    .call(force.drag);

nodeEnter.append("text")
    .attr("dx", 5)
    .style("text-anchor", "start")
    .style("font-size", "8px")
    .text(function (d) { return d.name; });

force.on("tick", function () {
    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] + ")"; });
});

相关问题 更多 >