在d3.force实现中无法读取未定义的属性“weight” [英] Cannot read property 'weight' of undefined in d3.force implementation

查看:1575
本文介绍了在d3.force实现中无法读取未定义的属性“weight”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经困扰这个问题了一段时间,现在不知道该怎么做,即使基于现有的答案。我在统一响应的最后一个JSON条目上收到此错误。

  ... {paperCount:1,PMIDs:[20626970],authorA:79,authorB :80},
{paperCount:1,PMIDs:[20492581],authorA:81,authorB:82},
{paperCount:1,PMIDs :20492581],authorA:81,authorB:83},
{paperCount:1,PMIDs:[20492581] ,
{paperCount:1,PMIDs:[20492581],authorA:82,authorB:83},
{paperCount:1,PMIDs:[20492581 ],authorA:82,authorB:84},
{paperCount:1,PMIDs:[20492581],authorA:83,authorB:84}] ...

下面的代码提取了该信息。它在for循环中保持失败...

  $ .getJSON('/ papers.txt',function(response){ 
var w = 1280,
h = 900,
fill = d3.scale.category10(),
nodes = d3.range(1000).map(Object),
links = d3.range(1000).map(Object);

var index = 0;
var mouseX = 0,
mouseY = 0;

for(var j = 0; j< response.length; j ++){
links [j] = {source:nodes [response [j] .authorA],target:nodes [response [j ] .authorB],value:response [j] .paperCount};
}



解决方案

简介



< h2>

在此之前,我建议您仔细阅读文档,因为我在这个答案中写的所有内容都写在

中。

好吧,不使用强制布局,你不用声明节点,你不包括在svg中的节点...所以基本上,从我看到,毫无疑问,它引发一个错误。您应该查看此示例,了解如何创建最小的有向图。



我还建议下次你有一个问题,你建立一个jsFiddle,所以我们可以工作,看看问题是在哪里,因为使用代码提供它是不可能看到确切的地方出错,因为你不以常规方式使用d3.js。



因此,让我们回到基础。



定义图形



首先,在加载数据之前,我们需要定义图形的一般属性:

  var width = 960,
height = 500;

var color = d3.scale.category20();

/ *这里我们定义我们将使用force布局,我们添加一些参数来设置图的基本布局* /
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width,height]);

/ *这里我们在页面中包含图形* /
var svg = d3.select(body)append(svg)
.attr width,width)
.attr(height,height);

但是,现在图形没有节点。我们需要加载数据。



加载数据



要加载数据,d3提供了一个帮助,所以让我们使用它而不是jQuery的,不需要混合另一个库。有关信息,json加载程序需要一个.json文件,因此不要使用.txt文件,即使它们包含json格式的数据。

  d3.json(papers.json,function(error,data){
// do whatever you需要处理json数据,例如:创建图形
}

全部



格式化数据



从我在这里看到的你的数据似乎只是一个链接列表,我只考虑你的节点只是从0到99的分数。

  var my_nodes = d3.range(100).map(function(d){return {name:d};}); 
var my_links = my_data.map(function(d){return {source :d.authorA,target:d.authorB,value:d.paperCount,origin:d};});



构建强制有向图



要从我的数据构建力导向图,

  force //我使用之前定义的变量force来添加数据
.nodes(my_nodes)
.links(my_links)
.start()//启动模拟

现在,力布局模拟开启了,知道有数据,但仍然没有添加到svg。现在我们添加一切:

  var link = svg.selectAll(。link)
.data(my_links )
.enter()。append(line)
.attr(class,link)

var node = svg.selectAll )
.data(my_nodes)
.enter()。append(circle)//如果你想知道为什么使用enter(),参见文档
.attr ,node)
.attr(r,5)
.style(fill,function(d){returnred;})
。拖动);

有关类属性,请参阅 example



声明tick()函数



最后,你必须声明将在force布局函数的每次迭代中调用的tick函数。

  force.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 dx;})
.attr cy,function(d){return dy;});
});



结论



示例,您的数据显示它的工作原理: http://bl.ocks.org/ChrisJamesC/5028030






或...



主要的问题是你不明白$ .getJson()函数是异步,所以你不应该只是构建链接它,你也应该使用它只在这个函数,否则它将不会被加载。






或...



来自于您应该将json文件命名为 /papers.json 而不是 /papers.txt 。 p>

I've been stuck on this problem for a while now and have no idea what to do even based on existing answers. I keep getting this error on the last JSON entry of a uniform response.

...{"paperCount": 1, "PMIDs": [20626970], "authorA": 79, "authorB": 80}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 81, "authorB": 82}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 81, "authorB": 83}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 81, "authorB": 84}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 82, "authorB": 83}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 82, "authorB": 84}, 
{"paperCount": 1, "PMIDs": [20492581], "authorA": 83, "authorB": 84}]...

The code is below to extract that information. It keeps failing in the for loop...

  $.getJSON('/papers.txt', function(response){
    var w = 1280,
    h = 900,
    fill = d3.scale.category10(),
    nodes = d3.range(1000).map(Object),
    links = d3.range(1000).map(Object);

    var index = 0;
    var mouseX = 0,
      mouseY = 0;

    for (var j = 0; j < response.length; j++){
      links[j] = {source: nodes[response[j].authorA], target: nodes[response[j].authorB], value: response[j].paperCount};
    }

Any help would be appreciated.

Thanks!

解决方案

Introduction

Before all, I suggest that you take a long look at the documentation as all I am going to say in this answer is written in it

Well, first in the code you provide you don't use the force layout at all, you don't declare the nodes with it, you don't include the nodes in the svg... So basically, from what I see, there is no doubt that it throws an error. You should take a look at this example to see how to create a minimal force directed graph.

I would also advise that the next time you have a question, you build a jsFiddle so we can work on it and see where the problem is, because with the code you provide it is not possible to see exactly where it went wrong as you don't use d3.js in a conventional manner.

So, let's go back to the basics.

Define the graph

First, before loading the data, we need to define the general properties of the graph:

var width = 960,
    height = 500;

var color = d3.scale.category20();

/* Here we define that we will use the force layout an we add some parameters to setup the basic layout of the graph */
var force = d3.layout.force() 
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

/* Here we include the graph in the page */
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

However, for now the graph has no nodes. We need to load the data.

Load the data

To load the data, d3 provides an helper, so let's use it instead of jQuery's one, no need to mix another library. For information, the json loader needs a .json file, so don't use .txt files even if they contain json formated data.

d3.json("papers.json", function(error, data) {
    // do whatever you need to do with the json data, for this example : create the graph
}

All that I will do later should be included inside these braces.

Format the data

From what I see here your data seems to be only a list of links, I will just consider that your nodes are just points from 0 to 99.

var my_nodes = d3.range(100).map(function(d){return {"name": d};});
var my_links = my_data.map(function(d){return {"source": d.authorA, "target": d.authorB, "value":d.paperCount, "origin": d};});

Build a force directed graph

To build the force directed graph out of my data,

force // I use the previously defined variable force to add the data.
    .nodes(my_nodes)
    .links(my_links)
    .start() //start the simulation

Now, the force layout simulation is on, it knows that there is data, but still, nothing is added to the svg. We will now add everything:

var link = svg.selectAll(".link")
    .data(my_links)
    .enter().append("line")
    .attr("class", "link")

var node = svg.selectAll(".node")
    .data(my_nodes)
    .enter().append("circle") // If you wonder why enter() is used, see the documentation
    .attr("class", "node")
    .attr("r", 5)
    .style("fill", function(d) { return "red"; })
    .call(force.drag);

For the class attributes, see example.

Declare the tick() function

Finally, you have to declare the tick function that will be called on each iteration of the force layout function

force.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; });
});

Conclusion

I just translated the basic example for your data to show it works: http://bl.ocks.org/ChrisJamesC/5028030


Or...

Maybe, the main problem you had is that you didn't understand that $.getJson() function is asynchronous so you should not just build the links vector in it, you should also use it only in this function because otherwise it won't be loaded yet.


Or...

Maybe, your error just comes from the fact that you should name the json file /papers.json instead of /papers.txt.

这篇关于在d3.force实现中无法读取未定义的属性“weight”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆