【问题标题】:Projecting relative positions of graph nodes to absolute coordinates将图形节点的相对位置投影到绝对坐标
【发布时间】:2015-12-13 02:24:48
【问题描述】:

我有一个这样的数据结构:

nodes = [
         {
          "id":0,
          "proximities":{
             "1": 12.34,
             "2": 56.78
           }, 
         {
          "id":1,
          "proximities":{
             "0": 12.34,
             "2": 90.12
           }, 
         {
          "id":2,
          "proximities":{
             "0": 56.78,
             "1": 90.12
           }, 
      ]

这是我想在屏幕上放置的节点数组。每个节点都包含一组“接近度”,即到其他节点的数字距离,我想使用这些距离来计算显示节点的绝对 XY 位置。 也就是说,我们希望通过算法计算出一个布局,其中每对节点之间的距离尽可能接近数据中给定的距离。

我已将此问题标记为 d3,因为我将使用 d3 来绘制图形,并且对它具有的任何内置功能感到好奇,这可能会使我更容易做到这一点。

也就是说,我的问题的根源更广泛:我在这里尝试做的事情有名称吗?我确信有解决这个问题的图论方法,但我很难找到它们,因为我不确定这个问题叫什么。我应该谷歌什么?

【问题讨论】:

  • D3 没有为此内置任何内容。通常,您应该能够迭代地执行此操作 - 放置第一个节点,将第二个节点放置在具有适当距离的点处,将第三个节点放置在与前两个​​节点适当的距离处,依此类推。看起来您的数据有点狡猾,距离 0-2 与距离 2-0 不同。
  • @LarsKotthoff 谢谢。不同的距离是一个错字——它们确实是对称的。当我引起你的注意时,你能想出一种方法,我可以通过使用力导向的布局来近似这项任务,以某种方式将邻近关系表示为加权边缘吗?
  • 强制布局在这里不起作用。我会采用我描述的方法。

标签: javascript algorithm d3.js graph graph-theory


【解决方案1】:

这是我处理您的问题集的方法。

我的节点和它们的邻近度是这样的:

nodes = [{
  "id": 0,
  name: "cyril",
  "proximities": {
    "1": 12.34,
    "2": 56.78,
    "3": 40
  }
}, {
  "id": 1,
  name: "tia",
  "proximities": {
    "0": 12.34,
    "2": 90.12
  }
}, {
  "id": 2,
  name: "josh",
  "proximities": {
    "0": 56.78,
    "1": 90.12
  }
}, {
  "id": 3,
  name: "sim",
  "proximities": {
    "0": 40,
  }
}]

将数据集更改为 Force Layout D3 可接受的格式。

function makeNodesLinks(nodes) {

  var graph = {};
  graph.nodes = [];
  graph.links = [];
  var keys = [];

  nodes.forEach(function(d) {
    //add node
    graph.nodes.push({
      name: d.name,
      id: d.id
    });
    for (var key in d.proximities) {
      if (keys.indexOf(d.id + "-" + key)<0)//this means if link is present don't add
      {
        keys.push(d.id + "-" + key);//done to make links unique
        keys.push(key + "-" + d.id);
        //add link and value stores its approx distance.
        graph.links.push({
          source: d.id,
          target: parseInt(key),
          value: d.proximities[key]
        });
      }
    }
  });
  return graph;
}

最后在强制布局中,链接之间的距离由 value key 决定。

  force
    .nodes(graph.nodes)
    .links(graph.links)
    .linkDistance(function(d) {
      return d.value*3;//approx distance between 2 nodes.
    })
    .start();

工作代码here.

现在,如果您不想看到链接,请更改 CSS 中的样式:将 opacity 设为 0,使其不可见。

.link {
  stroke: #999;
  stroke-opacity: 0;
}

【讨论】:

  • 它确实有帮助 - 很好的答案,抱歉迟到了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
  • 1970-01-01
相关资源
最近更新 更多