2012-07-09 26 views
34

Tôi mới đến D3 và đang làm việc trên đồ thị có lực tác động nơi dữ liệu json động. Tôi có thể thay đổi đồ thị lực khi nhận dữ liệu mới nhưng điều đó xảy ra với hiệu ứng tạo luồng. Mã tạo biểu đồ lực của tôi là:Cập nhật các liên kết trên đồ thị lực tác động từ dữ liệu json động

<div class="graph"></div> 
<script> 
var w = 660, 
    h = 700, 
    r = 10; 
var vis = d3.select(".graph") 
    .append("svg:svg") 
    .attr("width", w) 
    .attr("height", h) 
    .attr("pointer-events", "all") 
    .append('svg:g') 
    .call(d3.behavior.zoom().on("zoom", redraw)) 
    .append('svg:g'); 
vis.append('svg:rect') 
    .attr('width', w) 
    .attr('height', h) 
    .attr('fill', 'rgba(1,1,1,0)'); 
function redraw() { 
    console.log("here", d3.event.translate, d3.event.scale); 
    vis.attr("transform", "translate(" + d3.event.translate + ")" + 
          " scale(" + d3.event.scale + ")"); 
}; 

var force = d3.layout.force() 
    .gravity(.05) 
    .charge(-200) 
    .linkDistance(260) 
    .size([w, h]); 

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

d3.json(graph, function(json) { 

    var nodeList = json.nodes; 
    var link = vis.selectAll("line") 
     .data(json.links) 
     .enter() 
     .append("line") 
     .attr("stroke-opacity", function(d) { 
      if(d.label == 'is a') { 
       return '0.8'; 
      } else { 
       return '0.2'; 
      }; 
     }) 
     .attr("stroke-width", function(d) { 
      if(d.value !== null) { 
       return d.value; 
      } else { 
       return 2; 
      }; 
     }) 
     .style("stroke", function(d) { 
      if(d.color !== null) { 
       return d.color; 
      }; 
     }) 
     .on("mouseover", function() { 
      d3.select(this) 
       .style("stroke", "#999999") 
       .attr("stroke-opacity", "1.0"); 
     }) 
     .on("mouseout", function() { 
      d3.select(this) 
       .style("stroke", function(d) { 
        if(d.color !== null) { 
         return d.color; 
        }; 
       }) 
       .attr("stroke-opacity", function(d) { 
        if(d.label == 'is a') { 
         return '0.8'; 
        } else { 
         return '0.2'; 
        }; 
       }) 
      }); 

    link.append("title") 
     .text(function(d) { return d.label });   

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

    node.append("svg:circle") 
     .attr("r", function(d) { 
      if (d.size > 0) { 
       return 10+(d.size*2); 
      } else { 
       return 10; 
      } 
     }) 
     .attr("id", function(d) { return "Node;"+d.id; }) 
     .style("fill", function(d) { 
      if(d.style == 'filled') { 
       return d.color; 
      }; 
     }) 
     .style("stroke", function(d) { 
      if(d.style !== 'filled') { 
       return d.color; 
      }; 
     }) 
     .style("stroke-width", "2") 
     .on("mouseover", function() { 
      d3.select(this).style("fill", "#999"); 
      fade(.1); 
     }) 
     .on("mouseout", function(d) { 
      if (d.style == 'filled') { 
       d3.select(this).style("fill",d.color);fade(1); 
      } else { 
       d3.select(this).style("stroke",d.color); 
       d3.select(this).style("fill","black"); 
      } 
      fade(1); 
     }); 

    node.append("title") 
     .text(function(d) { return d.Location; });   

    force.nodes(json.nodes) 
     .links(json.links) 
     .on("tick", tick) 
     .alpha(1) 
     .start(); 

    function tick() { 
    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }) 
     .attr("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; 
    }); 

    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; }); 
    } 

}); 
</script> 

Tôi có thể tạo biểu đồ mới khi nhận được chuỗi json mới bằng cách gọi lại toàn bộ hàm. Điều này tạo ra một đồ thị mới thay cho cũ. Tôi không thể cập nhật biểu đồ cũ với tập giá trị mới khi nhận được các giá trị; các nút trong biểu đồ của tôi không thay đổi, chỉ là mối quan hệ giữa chúng thay đổi.

Tôi đã vấp ngã khi một ví dụ (http://bl.ocks.org/1095795) trong đó một nút mới bị xóa và tạo lại, nhưng việc triển khai thực hiện hơi khác một chút.

Bất kỳ con trỏ hoặc trợ giúp nào sẽ được đánh giá cao.

Trả lời

55

Tôi có thể tìm giải pháp duyệt qua, đăng giải pháp ở đây cho bất kỳ ai cần trợ giúp về chủ đề này. Ý tưởng là tạo ra một đối tượng của đồ thị và chơi xung quanh với các nút và các mảng liên kết. Mã JS diễn ra như:

var graph; 
function myGraph(el) { 

// Add and remove elements on the graph object 
this.addNode = function (id) { 
    nodes.push({"id":id}); 
    update(); 
}; 

this.removeNode = function (id) { 
    var i = 0; 
    var n = findNode(id); 
    while (i < links.length) { 
     if ((links[i]['source'] == n)||(links[i]['target'] == n)) 
     { 
      links.splice(i,1); 
     } 
     else i++; 
    } 
    nodes.splice(findNodeIndex(id),1); 
    update(); 
}; 

this.removeLink = function (source,target){ 
    for(var i=0;i<links.length;i++) 
    { 
     if(links[i].source.id == source && links[i].target.id == target) 
     { 
      links.splice(i,1); 
      break; 
     } 
    } 
    update(); 
}; 

this.removeallLinks = function(){ 
    links.splice(0,links.length); 
    update(); 
}; 

this.removeAllNodes = function(){ 
    nodes.splice(0,links.length); 
    update(); 
}; 

this.addLink = function (source, target, value) { 
    links.push({"source":findNode(source),"target":findNode(target),"value":value}); 
    update(); 
}; 

var findNode = function(id) { 
    for (var i in nodes) { 
     if (nodes[i]["id"] === id) return nodes[i];}; 
}; 

var findNodeIndex = function(id) { 
    for (var i=0;i<nodes.length;i++) { 
     if (nodes[i].id==id){ 
      return i; 
     } 
     }; 
}; 

// set up the D3 visualisation in the specified element 
var w = 500, 
    h = 500; 
var vis = d3.select("#svgdiv") 
    .append("svg:svg") 
    .attr("width", w) 
    .attr("height", h) 
    .attr("id","svg") 
    .attr("pointer-events", "all") 
    .attr("viewBox","0 0 "+w+" "+h) 
    .attr("perserveAspectRatio","xMinYMid") 
    .append('svg:g'); 

var force = d3.layout.force(); 

var nodes = force.nodes(), 
    links = force.links(); 

var update = function() { 
     var link = vis.selectAll("line") 
     .data(links, function(d) { 
      return d.source.id + "-" + d.target.id; 
      }); 

    link.enter().append("line") 
     .attr("id",function(d){return d.source.id + "-" + d.target.id;}) 
     .attr("class","link"); 
    link.append("title") 
    .text(function(d){ 
     return d.value; 
    }); 
    link.exit().remove(); 

    var node = vis.selectAll("g.node") 
     .data(nodes, function(d) { 
      return d.id;}); 

    var nodeEnter = node.enter().append("g") 
     .attr("class", "node") 
     .call(force.drag); 

    nodeEnter.append("svg:circle") 
    .attr("r", 16) 
    .attr("id",function(d) { return "Node;"+d.id;}) 
    .attr("class","nodeStrokeClass"); 

    nodeEnter.append("svg:text") 
    .attr("class","textClass") 
    .text(function(d){return d.id;}) ; 

    node.exit().remove(); 
    force.on("tick", function() { 

     node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y   + ")"; }); 

     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; }); 
    }); 

    // Restart the force layout. 
    force 
    .gravity(.05) 
    .distance(50) 
    .linkDistance(50) 
    .size([w, h]) 
    .start(); 
}; 


// Make it all go 
update(); 
} 

function drawGraph() 
{ 
graph = new myGraph("#svgdiv"); 
graph.addNode('A'); 
graph.addNode('B'); 
graph.addNode('C'); 
graph.addLink('A','B','10'); 
graph.addLink('A','C','8'); 
graph.addLink('B','C','15'); 
} 
+1

@Rahul Về cơ bản bạn đang vẽ lại toàn bộ đồ thị? – Pramod

+2

tôi không thể hiểu câu trả lời này. bất cứ ai có thể giúp tôi hiểu nó, để tôi có thể sử dụng nó. –

+0

chỉ là một vài quan sát, phần tử được cho là chứa svg là một tham số của hàm tạo Graph, nhưng sau đó một giá trị mã hóa cứng được sử dụng thay thế. Ngoài ra, việc đặt tên hàm không nhất quán là camelCased, như removeallLinks. – glasspill

0

Ngoài việc gọi drawGraph() trong hàm sẵn sàng, bạn cũng có thể nhúng mã đăng tải bên trong một inline <script></script> khối.

Đây là cách hầu hết các hướng dẫn trên trang web d3 xử lý nó.

12

Tôi lấy ví dụ tuyệt vời của Rahuls, thực hiện một số thay đổi và đăng bl.ock hoàn chỉnh với hoạt ảnh theo thời gian nếu có ai quan tâm đến một ví dụ đầy đủ chức năng. Thêm/xóa các liên kết/nút thực sự sẽ dễ dàng hơn thế này, nhưng vẫn khá thú vị.

http://bl.ocks.org/ericcoopey/6c602d7cb14b25c179a4

enter image description here

+3

Về mã khối của bạn. Bạn có thể tránh sử dụng Jquery để sắp xếp lại DOM bằng cách thay đổi ** link.enter(). Append ("dòng") ** thành ** link.enter(). Insert ("line", "g") ** – timebandit

Các vấn đề liên quan