2012-05-01 16 views
56

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

force.on("tick", function() { 
     vis.selectAll("g.node") 
      .attr("transform", function(d) { 
       return (d.someAttribute == true) ? 
        "translate(" + d.xcoordFromAttribute + "," + d.ycoordFromAttribute +")" : 
        "translate(" + d.x + "," + d.y + ")" 
      }); 
    }); 

मैं भी मैन्युअल नोड के एक्स और ऑन-टिक y विशेषता सेट करने की कोशिश की है, लेकिन फिर लिंक जहां नोड अगर यह होगा के लिए बाहर फ्लोट करने के लिए जारी रखने के लिए बल से प्रभावित था।

स्पष्ट रूप से मुझे यह समझने की मूलभूत समझ है कि यह कैसे काम करना चाहिए, तो क्या कोई मुझे एक उदाहरण के लिए इंगित कर सकता है जहां कुछ नोड्स अपनी स्थिति में स्थिर होते हैं (लेकिन फिर भी खींचने योग्य) और शेष नोड्स बल के चारों ओर तैर रहे हैं- निर्देशित की तरह, और सभी लिंक अभी भी काम कर रहे हैं?

उत्तर

69

वांछित नोड्स पर d.fixed सेट करें, और d.x और d.y वांछित स्थिति में प्रारंभ करें। ये नोड्स अभी भी सिमुलेशन का हिस्सा होंगे, और आप सामान्य प्रदर्शन कोड का उपयोग कर सकते हैं (उदा।, एक रूपांतरण विशेषता सेट करना); हालांकि, क्योंकि उन्हें निश्चित के रूप में चिह्नित किया गया है, उन्हें सिमुलेशन द्वारा खींचकर न केवल स्थानांतरित किया जा सकता है।

अधिक जानकारी के लिए force layout दस्तावेज़ीकरण देखें, और यह भी देखें कि this example में रूट नोड कैसे स्थित है। बल लेआउट में

8

d3v4 तय नोड्स

d3v3 d.fixedd.x और d.y पर नोड्स ठीक कर देंगे में; हालांकि, d3v4 में यह विधि अब समर्थित नहीं है। d3v4 documentation कहता है: प्रत्येक टिक के अंत में

fx - the node’s fixed x-position

fy - the node’s fixed y-position

, के बाद:

दी गई स्थिति में एक नोड, आप दो अतिरिक्त गुण निर्दिष्ट कर सकता है ठीक करने के लिए किसी भी बल के अनुप्रयोग, एक परिभाषित node.fx के साथ एक नोड इस मान पर node.x रीसेट है और node.vx शून्य पर सेट करें; इसी तरह, एक परिभाषित node.fy के साथ एक नोड node.y पर रीसेट है यह मान और node.vy शून्य पर सेट है। पहले से तय किए गए नोड को निष्पादित करने के लिए, node.fx और node.fy को शून्य पर सेट करें, या इन गुणों को हटाएं।

आप अपने डेटा स्रोत में बल नोड्स के लिए fx और fy गुण सेट कर सकते हैं, या आप जोड़ सकते हैं और गतिशील रूप fx और fy मान निकाल सकते हैं। टुकड़ा नीचे खींचें घटनाओं के अंत में इन गुणों सेट, बस एक नोड खींचें अपनी स्थिति को ठीक करने के लिए:

var data ={ 
 
"nodes": 
 
    [{"id": "A"},{"id": "B"},{"id": "C"},{"id":"D"}], 
 
"links": 
 
    [{"source": "A", "target": "B"}, 
 
    {"source": "B", "target": "C"}, 
 
    {"source": "C", "target": "A"}, 
 
    {"source": "D", "target": "A"}] 
 
} 
 
var height = 250; 
 
var width = 400; 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width",width) 
 
    .attr("height",height); 
 
    
 
var simulation = d3.forceSimulation() 
 
    .force("link", d3.forceLink().id(function(d) { return d.id; }).distance(50)) 
 
    .force("charge", d3.forceManyBody()) 
 
    .force("center", d3.forceCenter(width/2, height/2)); 
 
    
 
var link = svg.append("g") 
 
    .selectAll("line") 
 
    .data(data.links) 
 
    .enter().append("line") 
 
    .attr("stroke","black"); 
 

 
var node = svg.append("g") 
 
.selectAll("circle") 
 
.data(data.nodes) 
 
.enter().append("circle") 
 
.attr("r", 5) 
 
.call(d3.drag() 
 
    .on("start", dragstarted) 
 
    .on("drag", dragged) 
 
    .on("end", dragended)); 
 
    
 
simulation 
 
.nodes(data.nodes) 
 
.on("tick", ticked); 
 

 
simulation.force("link") 
 
.links(data.links); 
 
     
 
function ticked() { 
 
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("cx", function(d) { return d.x; }) 
 
    .attr("cy", function(d) { return d.y; }); 
 
}  
 
    
 
function dragstarted(d) { 
 
    d.fx = null; 
 
    d.fy = null; 
 
} 
 

 
function dragged(d) { 
 
    d.x = d3.event.x; 
 
    d.y = d3.event.y; 
 
} 
 

 
function dragended(d) { 
 
    d.fx = d3.event.x; 
 
    d.fy = d3.event.y; 
 
} 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.6.0/d3.min.js"></script>