javascript - 将 JSON 对象加载到 D3 力定向图中

标签 javascript jquery json d3.js svg

将这个自定义 JSON 对象加载到我的力导向图中时遇到了极其困难的情况。目前,我在 Canvas 上绘制了一个节点,但似乎没有显示其他任何内容,但我看到 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>

关于javascript - 将 JSON 对象加载到 D3 力定向图中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32586598/

相关文章:

ios - 第一次单击按钮时未显示数据

json - Spark 数据帧写入 JSON 显示 NULL 输出

php - jquery 选择列表和 $_POST 帮助

javascript - 使用 RequireJS 通过 GTM 自定义 HTML 标签注入(inject) jQuery 片段

c# - Web API 表单数据收集

javascript - 循环遍历 html 元素时替换粘贴中的文本

javascript - 我有一个问题 JSON stringify with javascript 中的循环结构

javascript - 编辑 ckeditor config.js 没有影响

javascript - jquery插件公共(public)函数

javascript - 使用 JavaScript 理解匿名函数