D3力定向图节点没有属性“D”;重量”;

D3 force-directed graph nodes have no attribute "weight"

本文关键字:属性 重量 节点 D3      更新时间:2023-09-26

我使用的是http://hughsk.github.io/colony/但我一直收到错误:

未捕获的类型错误:无法读取未定义的属性"weight"

这源于force.nodes(nodes)函数,文档表示不需要为其设置权重,因为在创建start()时,布局将初始化默认值。

有人能看到我做错了什么,导致权重值无法初始化吗?

这是我的代码:

var colony = {
  "nodes":[
    {
      "pages":123,
      "name":"Test",
      "id":2
    },
    {
      "pages":456,
      "name":"Test2",
      "id":3
    }
  ],
  "links":[
    {
      "source":123,
      "target":456,
      "weight":100
    }
  ]
}
var nodes = colony.nodes
  , links = colony.links
  , scale = 1
  , focus
var width = 960
  , height = 960
  , link
  , node
  , text
  , textTarget = false
var colors = {
      links: 'FAFAFA'
    , text: {
        subtitle: 'FAFAFA'
    }
    , nodes: {
        method: function(d) {
            return groups[d.group].color
        }
        , hover: 'FAFAFA'
        , dep: '252929'
    }
}
links.forEach(function(link) {
    var source = function(nodes,link){
        for (var i = 0; i < nodes.length; i++){
            if (nodes[i].id == link.source){
                return nodes[i];
            }
        }
    }
      , target = function(nodes,link){
        for (var i = 0; i < nodes.length; i++){
            if (nodes[i].id == link.target){
                return nodes[i];
            }
        }
    }
    source.children = source.children || []
    source.children.push(link.target)
    target.parents = target.parents || []
    target.parents.push(link.source)
})
var groups = nodes.reduce(function(groups, file) {
    var group = file.mgroup || 'none'
      , index = groups.indexOf(group)
    if (index === -1) {
        index = groups.length
        groups.push(group)
    }
    file.group = index
    return groups
}, [])
groups = groups.map(function(name, n) {
    var color = d3.hsl(n / groups.length * 300, 0.7, 0.725)
    return {
          name: name
        , color: color.toString()
    };
})
var force = d3.layout.force()
    .size([width, height])
    .charge(-50 * scale)
    .linkDistance(20 * scale)
    .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('cx', function(d) { return d.x; })
            .attr('cy', function(d) { return d.y; })
        if (textTarget) {
            text.attr('transform'
                    , 'translate(' + textTarget.x + ',' + textTarget.y + ')')
        }
    })
var vis = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)
force.nodes(nodes)
     .links(links)
     .start()

您的主要问题是必须修改forEach循环中的链接,这会给您带来类似于的结果

links.forEach(function (link) {
    //var source, target; 
    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].pages == link.source) {
            link.source = nodes[i];
        }
    }

    for (var i = 0; i < nodes.length; i++) {
        if (nodes[i].pages == link.target) {
            link.target = nodes[i];
        }
    }
    link.source.children = link.source.children || []
    link.source.children.push(link.target)
    link.target.parents = link.target.parents || []
    link.target.parents.push(link.source)
    return link;
})

然后,在tick函数中,还必须对所有linksnodes进行迭代。您可以在文档

中找到一个很好的例子