加载JSON对象到D3力有向图

Load JSON object into D3 Force Directed Graph

本文关键字:有向图 D3 JSON 对象 加载      更新时间:2023-09-26

我有一个非常困难的时间加载这个自定义JSON对象到我的力有向图。我目前有一个节点被绘制在画布上,但似乎没有其他显示,但我看到JSON是通过变量来的。我知道getElementById和其他约定有一些错误,但我并不担心。我更关心的是弄清楚为什么我的JSON对象没有被加载到D3。我认为问题出在:

root = JSON.parse(jsonObject);
console.log("root"+root);
root.fixed = true; 
root.x = w / 2;
root.y = h / 2 - 80;
update();

下面是JSON对象:

{"nodes":[{"name":"Enrique_Acevedo","group":1,"size":1,"image":null},{"name":"DanaSenna","group":1,"size":3,"image":"http://pbs.twimg.com/profile_images/523240959111208960/f7yo6MeN_normal.jpeg"},{"name":"samspe3ks","group":1,"size":1,"image":"http://pbs.twimg.com/profile_images/639272140353568769/aMk9kLfV_normal.jpg"},{"name":"NRGMdaie","group":1,"size":1,"image":"http://pbs.twimg.com/profile_images/602232150822236160/QuZ9o-LY_normal.jpg"},{"name":"aPulaCVABBB","group":1,"size":5,"image":"http://pbs.twimg.com/profile_images/612764147353128961/SjqBEzvS_normal.jpg"},{"name":"amanda_paola","group":1,"size":1,"image":"http://pbs.twimg.com/profile_images/625547329463033856/fO_L38_I_normal.jpg"},{"name":"memoluna","group":1,"size":9,"image":"http://pbs.twimg.com/profile_images/603850856358744065/P1Y001yF_normal.jpg"},{"name":"chiquisholla","group":1,"size":20,"image":"http://pbs.twimg.com/profile_images/568655048419209216/_1nkyI3J_normal.jpeg"},{"name":"OrangeSky31","group":1,"size":4,"image":"http://pbs.twimg.com/profile_images/565820749345067009/WF1MuChB_normal.jpeg"},{"name":"megustanadar","group":1,"size":1,"image":"http://pbs.twimg.com/profile_images/604971301506281472/m9VNqFPA_normal.jpg"}],"links":[{"source":1,"target":0,"value":1},{"source":2,"target":0,"value":1},{"source":3,"target":0,"value":1},{"source":4,"target":0,"value":1},{"source":5,"target":0,"value":1},{"source":6,"target":0,"value":1},{"source":7,"target":0,"value":1},{"source":8,"target":0,"value":1},{"source":9,"target":0,"value":1}]}

这是原来的JS文件:

function start(){
var w = 1200,
    h = 600,
    radius = 10,
    node,
    link,
    root;

var count = 0;
var force = d3.layout.force()
    .on("tick", tick)
    .charge(function(d) { return -500; })
    .linkDistance(function(d) { return d.target._children ? 100 : 50; })
    .size([w, h - 160]);
var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);
root = JSON.parse(jsonObject);
console.log("root"+root);
root.fixed = true; 
root.x = w / 2;
root.y = h / 2 - 80;
update();
console.log("JsonObject2"+jsonObject)

function update() {
    var nodes = flatten(root),
    links = d3.layout.tree().links(nodes);
    // Restart the force layout.
    force
        .nodes(nodes)
        .links(links)
        .start();

    // Update the links…
    link = svg.selectAll(".link")
        .data(links);
    // Enter any new links.
    link.enter().insert("svg:line", ".node")
        .attr("class", "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; });
    // Exit any old links.
    link.exit().remove();
    // Update the nodes…
      node = svg.selectAll("circle.node")
            .data(nodes, function(d) {
                return d.name;
            })
            .style("fill", color);
    node.transition()
        .attr("r", radius);

    // Enter any new nodes.
    node.enter().append("svg:circle")
        .attr("xlink:href",  function(d) { return d.image;})
        .attr("class", "node")
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("r", radius)
        .style("fill", color)
        .on("click", click)
        .call(force.drag);
    node.append("title")
    .text(function(d) { return d.name; });
    // Exit any old nodes.
    node.exit().remove();

    title = svg.selectAll("text.title")    
         .data(nodes);
    // Enter any new titles.
    title.enter()
        .append("text")
        .attr("class", "title");
        //.text(function(d) { return d.name; });
    // Exit any old titles.
    title.exit().remove();
}
function tick() {
    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; });
    title.attr("transform", function(d){ return "translate("+d.x+","+d.y+")"; });
}
function checkTitle() {
}
// Color leaf nodes orange, and packages white or blue.
function color(d) {
    if(d._children){
        return "#95a5a6";
    }else{
        switch(d.group) {
            case 'r': //adverb
                return "#e74c3c";
                break;
            case 'n': //noun
                return "#3498db";
                break;
            case 'v': //verb
                return "#2ecc71";
                break;
            case 's': //adjective
                return "#e78229";
                break;
            default:
                return "#9b59b6";
        }
    }
}
// Toggle children on click.
function click(d) {
document.getElementById("image").src = d.image;
document.getElementById("username").innerHTML = "Username:"+d.name;
document.getElementById("id").innerHTML = "ID:" + d.id;
document.getElementById("friends").innerHTML = d.friend;
document.getElementById("nodeTitle").innerHTML = "";
//document.getElementById("id").innerHTML = "Friend Count:" + d.name;
//if (d._children)
//grabImage();
//document.getElementById("image").innerHTML = (d.image);
/*if (d.children) { 
        d._children = d.children;
        d.children = null;
    } else {
        d.children = d._children;
        d._children = null;
    }
    update();*/
}
function mouseover() {
  d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 16);
}

function mouseout() {
  d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 8);
}
// Returns a list of all nodes under the root.
function flatten(root) {
    var nodes = [], i = 0;
    function recurse(node) {
        if (node.children) node.size = node.children.reduce(function(p, v) { return p + recurse(v); }, 0);
        if (!node.id) node.id = ++i;
        nodes.push(node);
        return node.size;
    }
    root.size = recurse(root);
    return nodes;
}};
do{
var intervalID = window.setTimeout(start, 1000)
}
while(jsonObject!=""){
}

您输入的数据有误。nodes必须是数组;你传递给它一个对象。这里不需要flatten函数,数据已经很平坦了。此外,您不需要调用d3.layout.tree().links,因为您的链接数据也已经正确格式化:

function update() {
    var nodes = root.nodes,
        links = root.links;

下面是你的代码:

<!DOCTYPE html>
<html>
<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <style>
    .node {
      cursor: pointer;
      stroke: #3182bd;
      stroke-width: 1.5px;
    }
    
    .link {
      fill: none;
      stroke: #9ecae1;
      stroke-width: 1.5px;
    }
  </style>
</head>
<body>
  <script>
    var jsonObject = {
      "nodes": [{
        "name": "Enrique_Acevedo",
        "group": 1,
        "size": 1,
        "image": null
      }, {
        "name": "DanaSenna",
        "group": 1,
        "size": 3,
        "image": "http://pbs.twimg.com/profile_images/523240959111208960/f7yo6MeN_normal.jpeg"
      }, {
        "name": "samspe3ks",
        "group": 1,
        "size": 1,
        "image": "http://pbs.twimg.com/profile_images/639272140353568769/aMk9kLfV_normal.jpg"
      }, {
        "name": "NRGMdaie",
        "group": 1,
        "size": 1,
        "image": "http://pbs.twimg.com/profile_images/602232150822236160/QuZ9o-LY_normal.jpg"
      }, {
        "name": "aPulaCVABBB",
        "group": 1,
        "size": 5,
        "image": "http://pbs.twimg.com/profile_images/612764147353128961/SjqBEzvS_normal.jpg"
      }, {
        "name": "amanda_paola",
        "group": 1,
        "size": 1,
        "image": "http://pbs.twimg.com/profile_images/625547329463033856/fO_L38_I_normal.jpg"
      }, {
        "name": "memoluna",
        "group": 1,
        "size": 9,
        "image": "http://pbs.twimg.com/profile_images/603850856358744065/P1Y001yF_normal.jpg"
      }, {
        "name": "chiquisholla",
        "group": 1,
        "size": 20,
        "image": "http://pbs.twimg.com/profile_images/568655048419209216/_1nkyI3J_normal.jpeg"
      }, {
        "name": "OrangeSky31",
        "group": 1,
        "size": 4,
        "image": "http://pbs.twimg.com/profile_images/565820749345067009/WF1MuChB_normal.jpeg"
      }, {
        "name": "megustanadar",
        "group": 1,
        "size": 1,
        "image": "http://pbs.twimg.com/profile_images/604971301506281472/m9VNqFPA_normal.jpg"
      }],
      "links": [{
        "source": 1,
        "target": 0,
        "value": 1
      }, {
        "source": 2,
        "target": 0,
        "value": 1
      }, {
        "source": 3,
        "target": 0,
        "value": 1
      }, {
        "source": 4,
        "target": 0,
        "value": 1
      }, {
        "source": 5,
        "target": 0,
        "value": 1
      }, {
        "source": 6,
        "target": 0,
        "value": 1
      }, {
        "source": 7,
        "target": 0,
        "value": 1
      }, {
        "source": 8,
        "target": 0,
        "value": 1
      }, {
        "source": 9,
        "target": 0,
        "value": 1
      }]
    };
    start();
    function start() {
      var w = 1200,
        h = 600,
        radius = 10,
        node,
        link,
        root;
      var count = 0;
      var force = d3.layout.force()
        .on("tick", tick)
        .charge(function(d) {
          return -500;
        })
        .linkDistance(function(d) {
          return d.target._children ? 100 : 50;
        })
        .size([w, h - 160]);
      var svg = d3.select("body").append("svg")
        .attr("width", w)
        .attr("height", h);
      root = jsonObject;
      console.log("root" + root);
      root.fixed = true;
      root.x = w / 2;
      root.y = h / 2 - 80;
      update();
      console.log("JsonObject2" + jsonObject)
      function update() {
        var nodes = root.nodes,
          links = root.links;
        // Restart the force layout.
        force
          .nodes(nodes)
          .links(links)
          .start();
        // Update the links…
        link = svg.selectAll(".link")
          .data(links);
        // Enter any new links.
        link.enter().insert("svg:line", ".node")
          .attr("class", "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;
          });
        // Exit any old links.
        link.exit().remove();
        // Update the nodes…
        node = svg.selectAll("circle.node")
          .data(nodes, function(d) {
            return d.name;
          })
          .style("fill", color);
        node.transition()
          .attr("r", radius);
        // Enter any new nodes.
        node.enter().append("svg:circle")
          .attr("xlink:href", function(d) {
            return d.image;
          })
          .attr("class", "node")
          .attr("cx", function(d) {
            return d.x;
          })
          .attr("cy", function(d) {
            return d.y;
          })
          .attr("r", radius)
          .style("fill", color)
          .on("click", click)
          .call(force.drag);
        node.append("title")
          .text(function(d) {
            return d.name;
          });
        // Exit any old nodes.
        node.exit().remove();
        title = svg.selectAll("text.title")
          .data(nodes);
        // Enter any new titles.
        title.enter()
          .append("text")
          .attr("class", "title");
        //.text(function(d) { return d.name; });
        // Exit any old titles.
        title.exit().remove();
      }
      function tick() {
        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;
          });
        title.attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        });
      }
      function checkTitle() {}
      // Color leaf nodes orange, and packages white or blue.
      function color(d) {
        if (d._children) {
          return "#95a5a6";
        } else {
          switch (d.group) {
            case 'r': //adverb
              return "#e74c3c";
              break;
            case 'n': //noun
              return "#3498db";
              break;
            case 'v': //verb
              return "#2ecc71";
              break;
            case 's': //adjective
              return "#e78229";
              break;
            default:
              return "#9b59b6";
          }
        }
      }
      // Toggle children on click.
      function click(d) {
        document.getElementById("image").src = d.image;
        document.getElementById("username").innerHTML = "Username:" + d.name;
        document.getElementById("id").innerHTML = "ID:" + d.id;
        document.getElementById("friends").innerHTML = d.friend;
        document.getElementById("nodeTitle").innerHTML = "";
        //document.getElementById("id").innerHTML = "Friend Count:" + d.name;
        //if (d._children)
        //grabImage();
        //document.getElementById("image").innerHTML = (d.image);
        /*if (d.children) { 
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update();*/
      }
      function mouseover() {
        d3.select(this).select("circle").transition()
          .duration(750)
          .attr("r", 16);
      }
      function mouseout() {
        d3.select(this).select("circle").transition()
          .duration(750)
          .attr("r", 8);
      }
      // Returns a list of all nodes under the root.
      function flatten(root) {
        var nodes = [],
          i = 0;
        function recurse(node) {
          if (node.children) node.size = node.children.reduce(function(p, v) {
            return p + recurse(v);
          }, 0);
          if (!node.id) node.id = ++i;
          nodes.push(node);
          return node.size;
        }
        root.size = recurse(root);
        return nodes;
      }
    }
  </script>
</body>
</html>