2012-03-05 18 views
34

के साथ निर्देशित लेआउट मैं डी 3 के लिए नया हूं और मेरे बल निर्देशित लेआउट के लिए सीमा निर्धारित करने में परेशानी है। मैं एक साथ टुकड़े करने में कामयाब रहा हूं (उदाहरणों से) जो मैं चाहता हूं, लेकिन मुझे ग्राफ को निहित करने की आवश्यकता है। टिक फ़ंक्शन में, एक ट्रांसफॉर्म/अनुवाद मेरे ग्राफ को सही तरीके से प्रदर्शित करेगा, लेकिन जब मैं Math.max/min (टिप्पणी कोड देखें) के साथ सीएक्स और साइ का उपयोग करता हूं, तो नोड्स को शीर्ष बाएं कोने में पिन किया जाता है जबकि रेखाएं ठीक से निहित होती हैं ।डी 3 बल बाध्यकारी बॉक्स

यहां मेरे पास क्या है ... मैं क्या गलत कर रहा हूं ??

var w=960, h=500, r=8, z = d3.scale.category20(); 

var color = d3.scale.category20(); 

var force = d3.layout.force() 
     .linkDistance(function(d) { return (d.value*180) }) 
     .linkStrength(function(d) { return (1/(1+d.value)) }) 
     .charge(-1000) 
     //.gravity(.08) 
     .size([w, h]); 

var vis = d3.select("#chart").append("svg:svg") 
     .attr("width", w) 
     .attr("height", h) 
     .append("svg:g") 
     .attr("transform", "translate(" + w/4 + "," + h/3 + ")"); 

vis.append("svg:rect") 
    .attr("width", w) 
    .attr("height", h) 
    .style("stroke", "#000"); 


d3.json("miserables.json", function(json) { 

     var link = vis.selectAll("line.link") 
       .data(json.links); 

     link.enter().append("svg:line") 
       .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.source.x; }) 
       .attr("y2", function(d) { return d.source.y; }) 
       .style("stroke-width", function(d) { return (1/(1+d.value))*5 }); 

     var node = vis.selectAll("g.node") 
       .data(json.nodes); 

     var nodeEnter = node.enter().append("svg:g") 
       .attr("class", "node") 
       .on("mouseover", fade(.1)) 
       .on("mouseout", fade(1)) 
       .call(force.drag); 

     nodeEnter.append("svg:circle") 
       .attr("r", r) 
       .style("fill", function(d) { return z(d.group); }) 
       .style("stroke", function(d) { return 
d3.rgb(z(d.group)).darker(); }); 

     nodeEnter.append("svg:text") 
       .attr("text-anchor", "middle") 
       .attr("dy", ".35em") 
       .text(function(d) { return d.name; }); 

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

     function tick() { 

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

     // This contains the lines within the boundary, but the nodes are 
stuck in the top left corner 
       //node.attr("cx", function(d) { return d.x = Math.max(r, Math.min(w 
- r, d.x)); }) 
       //  .attr("cy", function(d) { return d.y = Math.max(r, Math.min(h - 
r, 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; }); 
     } 

     var linkedByIndex = {}; 

    json.links.forEach(function(d) { 
     linkedByIndex[d.source.index + "," + d.target.index] = 1; 
    }); 

     function isConnected(a, b) { 
     return linkedByIndex[a.index + "," + b.index] || 
linkedByIndex[b.index + "," + a.index] || a.index == b.index; 
    } 

     function fade(opacity) { 
     return function(d) { 
      node.style("stroke-opacity", function(o) { 
         thisOpacity = isConnected(d, o) ? 1 : opacity; 
         this.setAttribute('fill-opacity', thisOpacity); 
       return thisOpacity; 
         }); 

         link.style("stroke-opacity", opacity).style("stroke-opacity", 
function(o) { 
       return o.source === d || o.target === d ? 1 : opacity; 
       }); 
     }; 
     } 

}); 
+0

मैंने कुछ पैरामीटर के साथ खेला है और फैसला किया है कि जब तक किसी के पास समाधान न हो, तो मैं केवल बहुत सारे .gravity() का उपयोग करूंगा। यदि ग्राफ बहुत बड़ा है तो यह अभी भी एक समस्या उत्पन्न करेगा, लेकिन अन्यथा नोड्स को ठीक से रखना चाहिए। –

उत्तर

59

मेरी talk on force layouts में एक bounding box example नहीं है। स्थिति वेरेट एकीकरण आपको "टिक" ईवेंट श्रोता के अंदर ज्यामितीय बाधाओं (जैसे बाध्यकारी बक्से और collision detection) को परिभाषित करने की अनुमति देता है; बस नोड्स को बाधा का अनुपालन करने के लिए ले जाएं और सिमुलेशन तदनुसार अनुकूलित होगा।

यह कहा गया है कि गुरुत्वाकर्षण निश्चित रूप से इस समस्या से निपटने के लिए एक अधिक लचीला तरीका है, क्योंकि यह उपयोगकर्ताओं को अस्थायी रूप से बाउंडिंग बॉक्स के बाहर ग्राफ खींचने की अनुमति देता है और फिर ग्राफ़ ठीक हो जाएगा। ग्राफ के आकार और प्रदर्शित क्षेत्र के आकार के आधार पर, आपको अपने ग्राफ को फिट करने के लिए गुरुत्वाकर्षण और चार्ज (प्रतिकृति) की विभिन्न सापेक्ष ताकत के साथ प्रयोग करना चाहिए।

+17

कुंजी 'node.attr (" cx ", फ़ंक्शन (डी) {वापसी dx = Math.max (आर, Math.min (चौड़ाई - आर, डीएक्स));}) .attr (" cy " , फ़ंक्शन (डी) {वापसी dy = Math.max (r, Math.min (ऊंचाई - आर, डीई));}); ' यदि आप 'लाइन' के बजाय' पथ 'का उपयोग करते हैं, तो आपको सीमा जोड़ने की आवश्यकता होगी 'attr ('d', function() {...}) के लिए जांचें;' '' '' ' – Limin

0

टिप्पणी कोड आपकी परिभाषा से एक नोड पर काम करता है, एक एसवीजी जी (रूपिंग) तत्व और सीएक्स/साइ गुणों को संचालित नहीं करता है। इन गुणों को जीवंत बनाने के लिए नोड के अंदर सर्कल तत्व का चयन करें:

node.select("circle") // select the circle element in that node 
    .attr("cx", function(d) { return d.x = Math.max(r, Math.min(w - r, d.x)); }) 
    .attr("cy", function(d) { return d.y = Math.max(r, Math.min(h - r, d.y)); });