【问题标题】:How do I make a d3.js force directed graph interactive using ajax and python?如何使用 ajax 和 python 使 d3.js 强制有向图交互?
【发布时间】:2013-01-06 15:23:06
【问题描述】:

我正在尝试在 d3.js 中创建一个力有向图交互式。 我创建了显示它的 html,还编写了生成内容的 python 脚本。但我不能让它一起工作。

我可以从浏览器调用 python 脚本,它会返回有效的 json,但我如何将它放入 d3?

不知何故,它总是调用带有结果的 url (*GET http://localhost/vici/[object%20Object] 404 (Not Found)*),但警报会显示 python 脚本的结果。

这是我的代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <script type="text/javascript" src="d3.v2.js?2.1.3"></script>
    <script src="jquery-1.8.3.js"></script>
    <style type="text/css">
        circle {
          stroke-width: 1.5px;
        }

        line {
          stroke: #999;
        }

        text {
          font: 10px sans-serif;
          pointer-events: none;
        }
    </style>
  </head>
  <body>
      <script type="text/javascript">

          $(document).ready(function() {

              $.ajax({
                  type: "GET",
                  url: "/vici/kellner.py/display",
                  contentType: "application/json; charset=utf-8",
                  dataType: "json",
                  data: {name: 302,level: 2}
              })

              .success(function(pyjson) {
              alert(pyjson);
              var data = pyjson;
                var w = 960,
                    h = 600,
                    r = 6;

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

                d3.json(pyjson, function(json) {
                  var force = d3.layout.force()
                    .nodes(json.nodes)
                    .links(json.links)
                    .gravity(.02)
                    .distance(50)
                    .charge(-400)
                    .size([w, h])
                    .start();

                  var link = svg.selectAll("line.link")
                    .data(json.links)
                    .attr("class", "link")
                    .enter().append("svg:line");

                  var node = svg.selectAll(".node")
                    .data(json.nodes)
                    .enter().append("g")
                    .attr("class", "node")
                    .call(force.drag);

                  node.append("image")
                    .attr("xlink:href", function(d) { return d.avatar })
                    .attr("x", -8)
                    .attr("y", -8)
                    .attr("width", function(d) { return d.avatarWidth })
                    .attr("height", function(d) { return d.avatarHeight });

                  node.append("text")
                    .attr("dx", 12)
                    .attr("dy", ".70em")
                    .text(function(d) { return d.avatarName });

                  node.append("svg:title")
                    .text(function(d) { return d.author; }, function(d) { return d.institute; } );

                  force.on("tick", function() {
                    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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
                  });

                });

              }); 
          });
    </script>

    <div id="d3vis"></div>
  </body>
</html>

但不仅如此:单击节点后如何让 d3 重新加载?每个节点都有一个名称(“作者”:“某个名称”),我的 python 脚本可以搜索该名称并返回一个新结果。

我对此进行了搜索并找到了一些东西(例如Updating links on a force directed graph from dynamic json data),看起来真的很好,我想做些什么,但我不明白,所以我无法根据我的需要对其进行修改。 (数据来自哪里,或者我可以在哪里调用我的 python 脚本来提供数据?)

我只需要将 json 导入 d3 并在单击节点时更改图形。

我是 Java Script 的新手,因此我们将不胜感激。

编辑: 这里还有一些测试数据:

{
"nodes": [
    {"institute": "None", "avatarWidth": "16", "avatar": "img/user.png", "avatarHeight": "16", "author": "Some Name"}, 
    {"institute": "None", "avatarWidth": "16", "avatar": "img/user.png", "avatarHeight": "16", "author": "Some Name"}, 
    {"institute": "None", "avatarWidth": "16", "avatar": "img/user.png", "avatarHeight": "16", "author": "Some Name"}, 
    {"author": "Main Name", "institute": "None", "avatarName": "Main Name", "avatar": "img/main.png", "avatarHeight": "24", "avatarWidth": "24"}, 
    {"institute": "None", "avatarWidth": "16", "avatar": "img/user.png", "avatarHeight": "16", "author": "Some Name"}
    ], 
"links": [
    {"color": "red", "source": 0, "target": 2, "weight": 1}, 
    {"color": "orange", "source": 1, "target": 2, "weight": 1}, 
    {"color": "yellow", "source": 2, "target": 3, "weight": 1}, 
    {"color": "yellow", "source": 2, "target": 4, "weight": 1}
    ]
}

【问题讨论】:

    标签: javascript python ajax d3.js force-layout


    【解决方案1】:

    好的,显然 d3.json(pyjson, function(json) { 行是“坏”行。这是 d3 试图发出自己的 ajax 请求吗?

    无论如何,我删除了它,它现在似乎可以工作了。此外,我点击一个节点重新加载的想法也不是很理想,因为你必须能够拉动它们并点击会阻止它。

    这是我的功能代码以供将来参考:(以及其他有相同问题的人)

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset=utf-8>
        <script type="text/javascript" src="d3.v2.js?2.1.3"></script>
        <script src="jquery-1.8.3.js"></script>
        <style type="text/css">
            circle {
              stroke-width: 1.5px;
            }
    
            line {
              stroke: #999;
            }
    
            text {
              font: 10px sans-serif;
              pointer-events: none;
            }
        </style>
      </head>
      <body>
          <script type="text/javascript">
    
              $(document).ready(function() {
    
                  $.ajax({
                      type: "GET",
                      url: "/vici/kellner.py/display",
                      contentType: "application/json; charset=utf-8",
                      dataType: "json",
                      data: {name: 302,level: 2}
                  })
    
                  .done(function(pyjson) {
    
                    var w = 960,
                        h = 600,
                        r = 6;
    
                    var svg = d3.select("#d3vis").append("svg:svg")
                        .attr("width", w)
                        .attr("height", h);
    
                    var force = d3.layout.force()
                      .nodes(pyjson.nodes)
                      .links(pyjson.links)
                      .gravity(.02)
                      .distance(50)
                      .charge(-400)
                      .size([w, h])
                      .start();
    
                    var link = svg.selectAll("line.link")
                      .data(pyjson.links)
                      .attr("class", "link")
                      .enter().append("svg:line");
    
                    var node = svg.selectAll(".node")
                      .data(pyjson.nodes)
                      .enter().append("g")
                      .attr("class", "node")
                      .call(force.drag);
    
                    node.append("image")
                      .attr("xlink:href", function(d) { return d.avatar })
                      .attr("x", -8)
                      .attr("y", -8)
                      .attr("width", function(d) { return d.avatarWidth })
                      .attr("height", function(d) { return d.avatarHeight });
    
                    node.append("text")
                      .attr("dx", 12)
                      .attr("dy", ".70em")
                      .text(function(d) { return d.avatarName });
    
                    node.append("svg:title")
                      .text(function(d) { return d.author; }, function(d) { return d.institute; } );
    
                    force.on("tick", function() {
                      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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
                    }); //End of force.on("tick", function() {
    
    
    
                  }); //End of .done(function(pyjson) {
              }); //End of $(document).ready(function() {
        </script>
    
        <div id="d3vis"></div>
      </body>
    </html>
    

    【讨论】:

    • d3.json 发出自己的 ajax 请求。看看doc
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多