首页 > 解决方案 > 将力生成的节点放置到径向散点图

问题描述

我有一个力布局,可以为给定的节点链接图生成一些节点位置。我的任务是将这些节点和链接放置到径向散点图。节点的放置方式应使其与中心节点的距离可见。出于这个原因,我计算节点到中心的欧几里得距离,并从计算的距离中找到最大值。然后将径向图的半径在 0 范围内缩放到最大距离值。但是当我尝试This example时,节点链接图没有放在散点图上。我的问题是如何将节点坐标放置到图中,以便散点图的圆线可以看到节点到中心节点的距离。这是我输入数据的一部分

{
"nodes": [
    {
        "id": "A0",
        "group": 0,
        "degree": 19,
        "name": "x"
    },
    {
        "id": "P0",
        "group": 0,
        "degree": 3,
        "name": "y"
    },
    {
        "id": "P1",
        "group": 0,
        "degree": 3,
        "name": "z"
    },
    {
        "id": "P2",
        "group": 0,
        "degree": 1,
        "name": "w"
    }
],
"links": [
    {
        "source": "P0",
        "target": "A0"
    },
    {
        "source": "P1",
        "target": "A0"
    },
    {
        "source": "P2",
        "target": "A0"
    }
]
}

这是我的代码的一部分。

var width = 1200,
  height = 800,
  radius = Math.min(width, height) / 2 - 30;
  //console.log(");

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var rd_at = 3,
    rd_pp = 2.5;

var author_cord = [];author_cord.push({x:width / 2,y:height / 2});

var given_person = 'x';

d3.json("json_file.json", function(graph) {

var simulation = d3.forceSimulation(graph.nodes)
    .force("charge", d3.forceManyBody().strength(-500))
    .force("center", d3.forceCenter(width / 2, height / 2))//ATTRACT NODES TO CENTER(width / 2, height / 2)
    .force("x", d3.forceX(width / 2).strength(1))//X ALLIGN
    .force("y", d3.forceY(height / 2).strength(1))//Y ALLIGN
    .force("link", d3.forceLink(graph.links).id(function(d) {return d.id; ).distance(40).strength(1))
    .stop();

 var loading = svg.append("text")
       .attr("dy", "0.35em")
       .attr("text-anchor", "middle")
       .attr("font-family", "sans-serif")
       .attr("font-size", 10)
       .text("Simulating. One moment please…");

 d3.timeout(function() {
      loading.remove();
      for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 -                   simulation.alphaDecay())); i < n; ++i) {
    simulation.tick();
}
var all_dist = [];
graph.nodes.forEach(function(d){
    var d_x = d.x - author_cord[0].x;
    var d_y = d.y - author_cord[0].y;

    var dist = Math.sqrt(d_x*d_x + d_y+d_y); 
    all_dist.push(dt);
});

var max_dist = d3.max(all_dist, function(d) {
  return d;
});
var r = d3.scaleLinear()
          .domain([0,12])
          .range([0, max_dist]);    

var line = d3.lineRadial()
             .radius(function(d) {
                return r(d[1]);
             });

var gr = svg.append("g")
  .attr("class", "r axis")
  .selectAll("g")
  .data(r.ticks(10).slice(1))
  .enter().append("g");

gr.append("circle")
  .attr("r", r);

var links = svg.append("g")
  .attr("stroke", "grey")
  .attr("stroke-width", 1)
  .selectAll("line")
  .data(graph.links)
  .enter().append("line")
  .style("opacity", function(d) { return d.target.name == given_author? 0 : 1; } )
  .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 n = svg.append("g")
         .selectAll("circle")
         .data(graph.nodes)
         .enter().append("circle")
         .attr("r",  function(d) {return d.group == 0 ? rd_at : rd_pp;})
         .attr("fill", function(d) { return color(d.group); })
         .attr("cx", function(d) { return d.x; })
         .attr("cy", function(d) { return d.y; })
         .attr("stroke", "#000")//.attr("stroke", function(d) {return d.group == 0 ? "red": "blue";})
         .attr("stroke-width", function(d) {return d.group == 0 ? 1.5 : 1;});

       });
    });

到目前为止,这是我的输出。图片. 这里,图中绿色节点是第 0 组节点,橙色节点是第 1 组节点。这里,中心节点是应该放置在径向图最内层中心位置的自我节点

标签: d3.js

解决方案


您的svg选择实际上对应于一个已经翻译了一半宽度和高度的组:

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height)
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

因此,您可以在模拟中更改"center","x""y",或者,您可以从svg选择中删除该组并转换圆圈的组:

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

var gr = svg.append("g")
  .attr("class", "r axis")
  .selectAll("g")
  .data(r.ticks(10).slice(1))
  .enter()
  .append("g")
  .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

推荐阅读