D3力导向图节点没有属性“权重”

时间:2013-07-08 21:39:44

标签: javascript d3.js force-layout

我正在使用来自http://hughsk.github.io/colony/的调整代码,但我一直收到错误:

  

未捕获的TypeError:无法读取未定义的属性'weight'

这源于force.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()

1 个答案:

答案 0 :(得分:1)

您的主要问题是您必须修改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。您可以在documentation

中找到一个很好的示例