0

I put my html file and json file under the same folder. When I run my code, it can't load the json file. Here is the html file:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>  
    <body>  
    
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>  

    <script type="text/javascript">

var nodes1;
d3.json("test.json", function(error, data){
 nodes1 = data;
});

var edges1 = [  { source : 0  , target: 1 } , { source : 0  , target: 2 } ,
       { source : 0  , target: 3 } , { source : 1  , target: 4 } ,
       { source : 1  , target: 5 } , { source : 1  , target: 6 } ,
       { source : 0  , target: 4 } , { source : 4  , target: 0 }]; 

         myfunction(nodes1, edges1);
        function myfunction(nodes, edges){
         
          var width = 900;
       var height = 400;
       
       
       var svg = d3.select("body")
          .append("svg")
          .attr("width",width)
          .attr("height",height);
       
       var force = d3.layout.force()
         .nodes(nodes) 
         .links(edges) 
         .size([width,height]) 
         .linkDistance(150) 
         .charge(-400); 

       force.start(); 

       console.log(nodes);
       console.log(edges);
       
         
       var svg_edges = svg.selectAll("line")
            .data(edges)
            .enter()
            .append("line")
            .style("stroke","#ccc")
            .style("stroke-width",1);
       
       var color = d3.scale.category20();
         
          
       var svg_nodes = svg.selectAll("circle")
            .data(nodes)
            .enter()
            .append("circle")
            .attr("r",20)
            .style("fill",function(d,i){
             return color(i);
            })
            .call(force.drag);

    
       var svg_texts = svg.selectAll("text")
            .data(nodes)
            .enter()
            .append("text")
            .style("fill", "black")
            .attr("dx", 20)
            .attr("dy", 8)
            .text(function(d){
             return d.name;
            });
          

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


         svg_texts.attr("x", function(d){ return d.x; })
          .attr("y", function(d){ return d.y; });
       });
        } 
       
        
        </script>
    </body>  
</html>  

And here is my json file:

[ 
 { name: "www"}, 
 { name: "ddd"},
 { name: "sdf"}, 
 { name: "ccc"},
 { name: "ads"}, 
 { name: "adh"},
 { name: "sdf"}
]

My server is tomcat 7 and I use eclipse to test my code. I also used Chrome, IE11, Edge, firefox and changed security strategy to run my code, but nothing appear on the explorer. Is that might because the wrong file directory? Or the method I use to load json file?

Ma Hans
  • 11
  • 1
  • What does your console say? Specifically the network tab. – Marty Sep 26 '16 at 05:19
  • 2
    `d3.json` is asynchronous - therefore you wont have any data in `nodes1` when the rest of the script runs (which will be before the d3.json even starts getting data, let alone finishes) ... `console.log(nodes);` is probably logging **undefined** if you'd bother to look at the console – Jaromanda X Sep 26 '16 at 05:22
  • console display nothing. – Ma Hans Sep 26 '16 at 05:25
  • https://github.com/d3/d3-3.x-api-reference/blob/master/Requests.md#d3_json describes how the callback works. The loaded data probably isn't available until that callback is called. Try putting a `console.log` in there and then consider calling your `myfunction` inside that callback – Scotty Waggoner Sep 26 '16 at 05:30

2 Answers2

1

as @Jaromanda X mentioned in his comment, you are loading json asynchronously so that when you invoke myfunction the value of nodes1 is still undefined

to make it work you should move myfunction invocation to json callback:

d3.json("test.json", function(error, data){
    nodes1 = data;
    myfunction(nodes1, edges1);
});
pwolaq
  • 6,343
  • 19
  • 45
  • It still not work. Nothing display on the screen. Is it possible that I have to convert data type from json to array? PS: if I just put my data into html file, it could work very well. – Ma Hans Sep 26 '16 at 05:47
0

Thank you all guys help! I solve the problem. I think I got two problems. One is like @Jaromanda X and @pwolaq said, json have asynchronously issue so that I have to load functions within my method. The second one I GUESS is MIGHT BE I have to convert json type to js array, I'm still not sure about it. I finally use another method to load data from json. Here is my method:

var request = new XMLHttpRequest();
 request.open('GET', 'test.json');
 request.onreadystatechange = function(){
  if((request.readyState == 4)&& (request.status == 200)){
   var nodes1 = JSON.parse(request.responseText);
   myfunction(nodes1);
  }
 };
 request.send();
Ma Hans
  • 11
  • 1