2016-03-30 6 views
1

のプロパティ「重量」を読み込めません、私は次のようなJSON構造を持っている:はd3.js現在捕捉されない例外TypeErrorを返すノード間のリンクの作成:未定義

data = { 
      "nodes":[ 
       { 
       "nodeType":"File", 
       "nodeId":16392, 
       "property1":"coint_ctolocal_partitions", 
       "property2":null, 
       "group":0, 
       "more":false 
       }, 
       { 
       "nodeType":"File", 
       "nodeId":16386, 
       "property1":"pers_contrato_partitions", 
       "property2":null, 
       "group":0, 
       "more":false 
       } 
      ], 
      "links":[ 
       { 
       "source":16386, 
       "target":16392, 
       "value":0, 
       "val":"{\"Contract\":[\"Insurance\"]}", 
       "type":"PTN" 
       } 
      ] 
     }; 

現在、これはUncaught TypeError: Cannot read property 'weight' of undefinedを返しています。

私たちのテストデータでは、単純にsource:0target:1を使用していました。これは、ノードのインデックスを使用してオブジェクトをリンクすると仮定して動作します。あるいは、おそらくlinkindexの機能です。一意のノードを識別し、我々はnodeIdを持つノードデータで

returnTableRelationshipData = function(){ 

     data = {} // json data as described above 

     // used to store the number of links between two nodes. 
     // mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex; 
     var mLinkNum = {}; 

     // sort links first 
     sortLinks();         

     // set up linkIndex and linkNumer, because it may possible multiple links share the same source and target node 
     setLinkIndexAndNum(); 

     // check that we don't have empty or null values 
     checkDataNotEmpty(); 

     var w = 600, 
      h = 500; 

     var force = d3.layout.force() 
        .nodes(d3.values(data.nodes)) 
        .links(data.links) 
        .size([w, h]) 
        .linkDistance(150) 
        .charge(-300) 
        .on("tick", tick) 
        .start(); 

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

     var path = svg.append("svg:g") 
        .selectAll("path") 
        .data(force.links()) 
        .enter().append("svg:path") 
        .attr("class", "link"); 

     var circle = svg.append("svg:g") 
        .selectAll("circle") 
        .data(force.nodes()) 
        .enter().append("svg:circle") 
        .attr("r", 6) 
        .call(force.drag); 

     var text = svg.append("svg:g")         
        .selectAll("g") 
        .data(force.nodes()) 
        .enter().append("svg:g"); 

     // A copy of the text with a thick white stroke for legibility. 
     text.append("svg:text") 
      .attr("x", 12) 
      .attr("y", ".31em") 
      .attr("class", "shadow") 
      .text(function(d){ return d.property1; }); 

     text.append("svg:text") 
      .attr("x", 12) 
      .attr("y", ".31em") 
      .text(function(d){ return d.property1; }); 

     // Use elliptical arc path segments to doubly-encode directionality. 
     function tick() { 
      path.attr("d", function(d){ 
       var dx = d.target.x - d.source.x, 
        dy = d.target.y - d.source.y, 
        dr = Math.sqrt(dx * dx + dy * dy); 
       // get the total link numbers between source and target node 
       var lTotalLinkNum = mLinkNum[d.source.id + "," + d.target.id] || mLinkNum[d.target.id + "," + d.source.id]; 
       if(lTotalLinkNum > 1) 
       { 
        // if there are multiple links between these two nodes, we need generate different dr for each path 
        dr = dr/(1 + (1/lTotalLinkNum) * (d.linkindex - 1)); 
       }  
       // generate svg path 
       return "M" + d.source.x + "," + d.source.y + 
        "A" + dr + "," + dr + " 0 0 1," + d.target.x + "," + d.target.y + 
        "A" + dr + "," + dr + " 0 0 0," + d.source.x + "," + d.source.y;  
      }); 

      circle.attr("transform", function(d){ 
       return "translate(" + d.x + "," + d.y + ")"; 
      }); 

      text.attr("transform", function(d){ 
       return "translate(" + d.x + "," + d.y + ")"; 
      }); 
     } 

     // sort the links by source, then target 
     function sortLinks(){ 
      if(data.links != null){       
       data.links.sort(function(a,b){ 
        if(a.source > b.source){ 
         return 1; 
        }else if(a.source < b.source){ 
         return -1; 
        }else{ 
         if(a.target > b.target){ 
          return 1; 
         }if(a.target < b.target){ 
          return -1; 
         }else{ 
          return 0; 
         } 
        } 
       }); 
      } 
     } 

     //any links with duplicate source and target get an incremented 'linknum' 
     function setLinkIndexAndNum(){        
      for(var i = 0; i < data.links.length; i++){ 
       if(i != 0 && 
        data.links[i].source == data.links[i-1].source && 
        data.links[i].target == data.links[i-1].target){ 
        data.links[i].linkindex = data.links[i-1].linkindex + 1; 
       }else{ 
        data.links[i].linkindex = 1; 
       }// save the total number of links between two nodes 
       if(mLinkNum[data.links[i].target + "," + data.links[i].source] !== undefined){ 
        mLinkNum[data.links[i].target + "," + data.links[i].source] = data.links[i].linkindex; 
       }else{ 
        mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex; 
       } 
      } 
     } 

     function checkDataNotEmpty(){ 
      data.links.forEach(function(link, index, list) { 
       if (typeof link.source === 'undefined') { 
        console.log('undefined link', data.nodes[link.source]); 
       } 
       if (typeof link.target === 'undefined') { 
        console.log('undefined source', data.nodes[link.target]); 
       } 
       console.log(typeof link.source, typeof link.target); 
      }); 
     } 

} 

$(document).ready(function(){ 
    returnTableRelationshipData(); 
}); 

フル機能は、次のようになります。我々はまた、一意のテーブル名であるproperty1を持っています。

これは可能な場合、カスタムjsonキーを使用して既存のデータ間のソースとターゲットを設定する方法が必要ですか? (すなわち、ノードIDがソースまたはターゲットにマップされます)。

最初は整数、文字列などで問題が発生していると思っていましたが、それが助けになる場合は、これらの間で変換できます。 (私はこれを試してみたが成功しなかったことを意味する)。私はここにフィドルをした

https://jsfiddle.net/lharby/j1q1oLzL/1/

答えて

2

あなたは、インデックスのノードの配列で、それにターゲット/ソースIDを変換するために、このようにそれを行うことができます。

//find the node index 
function find(f){ 
    var i = -1 
    data.nodes.forEach(function(node, index){ 
     if(node.nodeId == f) 
      i = index; 
    }); 
    return i; 
} 
//set the source and target index 
data.links.forEach(function(d){ 
      d.source = find(d.source); 
      d.target = find(d.target); 
     }); 

リンク元のターゲットがなければなりませんhere

+1

ああおかげで、偉大に見える、私はTRますdocs

作業コードで述べたように、ノードの配列のインデックスまもなくそれは外に出る。 – lharby

関連する問題