【问题标题】:D3.js multiple force layout graphs from json fileD3.js 来自 json 文件的多个力布局图
【发布时间】:2015-04-11 11:35:33
【问题描述】:

我已经定义了以下函数,它“在单击按钮时”从 JSON 文件中读取数据,它应该生成多个 d3 图形,每个图形都在自己的 svg 容器中:

    //button click 
function updateData() {
    var c = $("#select-list option:selected").text();

    d3.json("out_graph.json", function(subgraphs, ind) {
   for (k in ind) {
        var k_data = ind[k].graphs;
        if (k_data.values = c)
            {
            console.log(k_data.values ); //works
            var svgSUBS = d3.select("#subgraphs").append("svg")
                            .attr("id","subsID")
                            .attr("width", 300)
                            .attr("height", 300);

            nodes = [];
            links = [];
            nodes = ind[k].nodes;
            links = ind[k].links;

      var link = svgSUBS.selectAll(".linkSUB")
          .data(ind[k].links)
          .enter().append("g")
          .attr("class", "linkSUB");
           link.append("line")
          .style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });

      link.filter(function(d) { return d.bond > 1; }).append("line")
          .attr("class", "separator");

      var node = svgSUBS.selectAll(".nodeSUB")
          .data(ind[k].nodes)
          .enter().append("g")
          .attr("class", "nodeSUB")
          .call(d3.layout.force()
                .size([width, height])
                .charge(-400)
                .linkDistance(function(d) { return radius + 40;}).drag);

      node.append("circle")
          .attr("r", radius)
          .style("fill", function(d) { return color(d.Node); });

      node.append("text")
          .attr("dy", ".35em")
          .attr("text-anchor", "middle")
          .text(function(d) { return d.Node + d.label; });
              function tick() {
        link.selectAll("line")
            .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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
      }
      d3.layout.force()
                .size([width, height])
                .charge(-400)
                .linkDistance(function(d) { return radius + 40;})
                .nodes(nodes)
                .links(links)
                .on("tick", tick)
                .start();


            }                                      
    }   
    });
}

我执行后得到的结果如下:

JSON文件包含多个图形数据,格式如下:

[{
 "subgraph": "21",
 "nodes": [
{"Node": "0", "label": "N"},
{"Node": "1", "label": "N"},
{"Node": "2", "label": "C"},
{"Node": "3", "label": "C"},
{"Node": "4", "label": "C"}
],
"links": [
{"source":4, "target":0, "bond":1},
{"source":2, "target":1, "bond":1},
{"source":3, "target":2, "bond":1},
{"source":4, "target":3, "bond":1}
],
"graphs": [
{"graph": "1 HMDB00001"},
{"graph": "2 HMDB00002"},
{"graph": "2 HMDB00002"}
]},
{
 "subgraph": "22",
 "nodes": [
{"Node": "0", "label": "N"},
{"Node": "1", "label": "C"},
{"Node": "2", "label": "C"},
{"Node": "3", "label": "C"}
],
"links": [
{"source":1, "target":0, "bond":1},
{"source":2, "target":1, "bond":1},
{"source":3, "target":2, "bond":1}
],
"graphs": [
{"graph": "1 HMDB00001"},
{"graph": "2 HMDB00002"},
{"graph": "2 HMDB00002"}
]},
..........
........

我不明白为什么只有最后一个图表正确显示,而力布局仅适用于该图表。

【问题讨论】:

  • 看起来节点的位置没有为第一组图正确设置,你有 JSFiddle 吗?
  • 我尝试创建一个,但由于我是新手,我真的不知道如何让它读取 JSON 数据。这是我的代码的保管箱链接:
  • 只需将 JSON 放入 javascript 变量中并调用它:)

标签: javascript json svg d3.js force-layout


【解决方案1】:

我找到了解决方案,使用“forEach(function (k)”而不是“for (k in ind)”循环完成了工作。似乎后者只为循环的最后一个元素执行函数。完整的使用的代码:

//button click 
function updateData() {
    var selected_graph = $("#select-list option:selected").text();

    d3.json("out_graph.json", function(subgraphs, ID) {
    ID.forEach(function (k) {
        var k_data = k.graphs;
        if (k_data.values = selected_graph)
            {
            console.log(k_data.values ); //works
            console.log(k);
    var svgSUBS = d3.select("#subgraphs").append("svg")
                            .attr("id","subsID")
                            .attr("width", 300)
                            .attr("height", 300);

      var forceSUB = d3.layout.force()
                .size([width, height])
                .charge(-400)
                .linkDistance(function(d) { return radius + 40;});

      var link = svgSUBS.selectAll(".linkSUB")
          .data(k.links)
          .enter().append("g")
          .attr("class", "linkSUB");
           link.append("line")
          .style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });

      link.filter(function(d) { return d.bond > 1; }).append("line")
          .attr("class", "separator");

      var node = svgSUBS.selectAll(".nodeSUB")
          .data(k.nodes)
          .enter().append("g")
          .attr("class", "nodeSUB")
          .call(forceSUB.drag);

      node.append("circle")
          .attr("r", radius)
          .style("fill", function(d) { return color(d.Node); });

      node.append("text")
          .attr("dy", ".35em")
          .attr("text-anchor", "middle")
          .text(function(d) { return d.Node + d.label; });
              function tick() {
        link.selectAll("line")
            .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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
      }
            forceSUB
                .nodes(k.nodes)
                .links(k.links)
                .on("tick", tick)
                .start();
            }                                      
    }); 
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 2013-04-25
    • 2014-12-15
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多