为什么d3在应用链接力后会说某些节点丢失了?

时间:2017-10-19 03:42:20

标签: javascript d3.js graph

我正在尝试跟随一本名为网络的交互式数据可视化的书。我想尝试构建那里描述的力图。当我使用这本书的虚拟数据时,一切都很好,但是当我尝试自己的数据时,我不断收到错误,说节点17丢失了。当我将此节点的目标更改为16时,它将表示缺少18。最终,当我将16,17和18全部更改为15时,图形将最终显示。但是显示的图形中仍然缺少某些节点的边缘。

我为数据尝试了所有不同的字符串/整数可能性而没有成功。数据与数据库查询结果中的forEach放在一起。源和目标整数是数据库中节点的ID。最后的结果是因为它有一个不必要的逗号,但这似乎也没关系。

当我保留节点原始目标值并删除这行代码时:.force("link", d3.forceLink(graph.links))图形将显示没有边缘,节点将分散在整个SVG上。当我按源数据对数据进行排序时,控制台会说d3没有定义......我真的迷失了这个。

我看过很多帖子,其中未定义的值或空值给出了原因,但我真的不明白如何相应地更改我的代码。在控制台中,可以清楚地看到一些节点在施加力后分配了一个索引号,而有些则没有。但我对于去哪里没有任何想法。请帮我正确的方向。这就是我尝试将图形数据放在Node.js中的方法:

var graph = {
            nodes: [
                <% nodes.forEach(function(a){ %>
                    {category: "<%= a.properties.Name %>"},
                <% }); %>
            ],
            links: [
                <% edges.forEach(function(a){ %>
                    {"source": <%= a.source %>, "target": <%= a.target %>},
                <% }); %>
            ]
        }

这就是名为graph的数据集内部:

var graph = {
            nodes: [
           {Name: "b"},
           {Name: "c"},
           {Name: "c"},
           {Name: "c"},
           {Name: "b"},
           {Name: "b"},
           {Name: "c"},
           {Name: "c"},
           {Name: "c"},
           {Name: "b"},
           {Name: "c"},
           {Name: "c"},
           {Name: "d"},
           {Name: "d"},
           {Name: "a"},
           {Name: "c"}
        ],
        links: [
            {source: 8, target: 3},
            {source: 3, target: 5},
            {source: 3, target: 6},
            {source: 3, target: 7},
            {source: 3, target: 11},
            {source: 3, target: 12},
            {source: 8, target: 0},
            {source: 0, target: 13},
            {source: 0, target: 14},
            {source: 8, target: 9},
            {source: 9, target: 17},
            {source: 9, target: 18},
            {source: 14,target: 15},
            {source: 14,target: 16},
            {source: 8, target: 10}                  
            ]
        }

这是我从书中复制的d3代码:

var w = 800;
        var h = 400;

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

        var force = d3.forceSimulation(graph.nodes)
        .force("charge", d3.forceManyBody())
        .force("link", d3.forceLink(graph.edges))
        .force("center", d3.forceCenter().x(w/1).y(h/1))

        var edges = svg.selectAll("line")
            .data(graph.edges)
            .enter()
            .append("line")
            .style("stroke", "#ccc")
            .style("stroke-width", 1)


        var nodes = svg.selectAll("circle")
            .data(graph.nodes)
            .enter()
            .append("circle")
            .attr("r", 10)


            nodes.append("title")
            .text(function(d) {
                return d.name
            })

            force.on("tick", function() {
            edges.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; })
            nodes.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; })
            })

这是错误。请帮助我说明为什么会发生这种情况error

PS。这是本书中的虚拟数据。我真的不明白为什么这个有用而我的没有。

var graph = {
        nodes: [
        { name: "Adam" },
        { name: "Bob" },
        { name: "Carrie" },
        { name: "Donovan" },
        { name: "Edward" },
        { name: "Felicity" },
        { name: "George" },
        { name: "Hannah" },
        { name: "Iris" },
        { name: "Jerry" }
        ],
        edges: [
        { source: 0, target: 1 },
        { source: 0, target: 2 },
        { source: 0, target: 3 },
        { source: 0, target: 4 },
        { source: 1, target: 5 },
        { source: 2, target: 5 },
        { source: 2, target: 5 },
        { source: 3, target: 4 },
        { source: 5, target: 8 },
        { source: 5, target: 9 },
        { source: 6, target: 7 },
        { source: 7, target: 8 },
        { source: 8, target: 9 }
        ]
        }

1 个答案:

答案 0 :(得分:1)

这里的问题非常简单。您只有16个节点:

&#13;
&#13;
var graph = {
  nodes: [{
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "b"
  }, {
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "d"
  }, {
    Name: "d"
  }, {
    Name: "a"
  }, {
    Name: "c"
  }],
  links: [{
    source: 8,
    target: 3
  }, {
    source: 3,
    target: 5
  }, {
    source: 3,
    target: 6
  }, {
    source: 3,
    target: 7
  }, {
    source: 3,
    target: 11
  }, {
    source: 3,
    target: 12
  }, {
    source: 8,
    target: 0
  }, {
    source: 0,
    target: 13
  }, {
    source: 0,
    target: 14
  }, {
    source: 8,
    target: 9
  }, {
    source: 9,
    target: 17
  }, {
    source: 9,
    target: 18
  }, {
    source: 14,
    target: 15
  }, {
    source: 14,
    target: 16
  }, {
    source: 8,
    target: 10
  }]
}

console.log("number of nodes: " + graph.nodes.length)
&#13;
&#13;
&#13;

他们的指数从0变为15(基于零)。

但是,在links数组中,您的源/目标高于17或18!那不会奏效。请注意,原始数据只有10个节点,边缘为&#39;数组有9作为源或目标的最大索引。

以下是您的代码和数据,将高于15的所有内容更改为其他数字:

&#13;
&#13;
var graph = {
  nodes: [{
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "b"
  }, {
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "b"
  }, {
    Name: "c"
  }, {
    Name: "c"
  }, {
    Name: "d"
  }, {
    Name: "d"
  }, {
    Name: "a"
  }, {
    Name: "c"
  }],
  links: [{
    source: 8,
    target: 3
  }, {
    source: 3,
    target: 5
  }, {
    source: 3,
    target: 6
  }, {
    source: 3,
    target: 7
  }, {
    source: 3,
    target: 11
  }, {
    source: 3,
    target: 12
  }, {
    source: 8,
    target: 0
  }, {
    source: 0,
    target: 13
  }, {
    source: 0,
    target: 14
  }, {
    source: 8,
    target: 9
  }, {
    source: 9,
    target: 10
  }, {
    source: 9,
    target: 10
  }, {
    source: 14,
    target: 15
  }, {
    source: 14,
    target: 10
  }, {
    source: 8,
    target: 10
  }]
}

var w = 800;
var h = 400;

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

var force = d3.forceSimulation(graph.nodes)
  .force("charge", d3.forceManyBody())
  .force("link", d3.forceLink(graph.links))
  .force("center", d3.forceCenter().x(w / 2).y(h / 2))

var edges = svg.selectAll("line")
  .data(graph.links)
  .enter()
  .append("line")
  .style("stroke", "#ccc")
  .style("stroke-width", 1)

var nodes = svg.selectAll("circle")
  .data(graph.nodes)
  .enter()
  .append("circle")
  .attr("r", 10)

nodes.append("title")
  .text(function(d) {
    return d.name
  })

force.on("tick", function() {
  edges.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;
    })
  nodes.attr("cx", function(d) {
      return d.x;
    })
    .attr("cy", function(d) {
      return d.y;
    })
})
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;