2012-07-09 15 views
34

से बल निर्देशित ग्राफ पर लिंक अपडेट करना मैं डी 3 के लिए नया हूं और एक बल निर्देशित ग्राफ पर काम कर रहा हूं जहां जेसन डेटा गतिशील है। मैं नए डेटा प्राप्त करने पर बल ग्राफ को बदलने में सक्षम हूं लेकिन यह एक वसंत प्रभाव के साथ होता है। कोड है कि मेरे बल ग्राफ बनाता है:गतिशील जेसन डेटा

<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> 

मैं एक नया ग्राफ जब एक नया json स्ट्रिंग पूरे समारोह फिर से याद करते हुए द्वारा प्राप्त होता है बनाने के लिए कर रहा हूँ। यह पुराने स्थान पर एक नया ग्राफ बनाता है। मूल्यों के नए सेट के साथ पुराने ग्राफ को अपडेट करने में असमर्थ हूं क्योंकि मान प्राप्त होते हैं; मेरे ग्राफ में नोड्स नहीं बदलते हैं, बस उनके बीच संबंध बदलता है।

मैंने एक उदाहरण (http://bl.ocks.org/1095795) पर ठोकर खाई जहां एक नया नोड हटा दिया गया और फिर से बनाया गया, लेकिन कार्यान्वयन थोड़ा अलग है।

किसी भी पॉइंटर्स या सहायता की वास्तव में सराहना की जाएगी।

उत्तर

55

वैसे मैं इस विषय पर सहायता की आवश्यकता वाले किसी के लिए यहां पोस्ट करके समाधान ब्राउज़ कर सकता हूं। विचार ग्राफ का ऑब्जेक्ट बनाना और नोड्स और लिंक एरे के साथ खेलना है। जे एस कोड के रूप में चला जाता है:

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 अनिवार्य रूप से आप पूरे ग्राफ redrawing कर रहे हैं? – Pramod

+2

मैं इस जवाब को समझने में सक्षम नहीं हूं। क्या कोई इसे समझने में मेरी मदद कर सकता है, ताकि मैं इसका उपयोग कर सकूं। –

+0

केवल कुछ अवलोकन, तत्व जो svg को शामिल करने वाला माना जाता है वह ग्राफ़ कन्स्ट्रक्टर का पैरामीटर है, लेकिन उसके बाद हार्ड कोडित मान का उपयोग किया जाता है। भी, फ़ंक्शन नामकरण लगातार camelCased नहीं है, जैसे removeallLinks। – glasspill

0

तैयार समारोह में drawGraph() कॉल करने के अलावा, आप भी तैनात कोड एक इनलाइन <script></script> ब्लॉक के अंदर एम्बेड कर सकते हैं।

इस प्रकार डी 3 साइट पर अधिकांश ट्यूटोरियल इसे संभालते हैं।

12

मैंने Rahuls महान उदाहरण लिया, कुछ बदलाव किए, और समय के साथ एनीमेशन के साथ एक bl.ock पोस्ट किया अगर कोई पूरी तरह से काम कर रहे उदाहरण में रुचि रखते हैं। लिंक/नोड्स को जोड़ना/निकालना वास्तव में इससे आसान होना चाहिए, लेकिन फिर भी बहुत अच्छा है।

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

enter image description here

+3

आपके ब्लॉक के कोड के बारे में। आप ** link.enter() को जोड़कर डीओएम को फिर से ऑर्डर करने के लिए Jquery का उपयोग करने से बच सकते हैं। ("लाइन") ** ** ** link.enter() में डालें। डालें ("लाइन", "जी") ** – timebandit

संबंधित मुद्दे