2012-06-15 10 views
18

डी 3 का निर्देशन रेखांकन जैसे कि निम्न कि सख्त पेड़ हैं, के लिए लेआउट की एक किस्म है:डी 3 के साथ एक गैर पेड़ पदानुक्रम लेआउट कैसे

A 
|\ 
B C 
/\ 
D E 

मुझे लगता है कि नहीं है नोड्स के एक पदानुक्रम आकर्षित करने की आवश्यकता एक पेड़, लेकिन एक निर्देशित विश्वकोश ग्राफ है। यह एक पेड़ लेआउट के लिए एक समस्या है, क्योंकि शाखाओं के कई अभिसरण:

A 
|\ 
B C 
\| 
    D 

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

+0

आप बल निर्देशित ग्राफ़ लेआउट पर एक नज़र डालना चाहते हैं। –

उत्तर

1

पेड़ और डेटा पदानुक्रम के आम तौर पर बात हो रही है, तो आप सिर्फ दोनों बी और सी

अपने नोड सूची बनाने के लिए बच्चों की सूची में 'डी' की आवश्यकता है, सुनिश्चित करें कि आप में एक विशिष्ट आईडी ताकि लौटे कर "डी" दो बार प्रकट नहीं होता है।

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

फिर जब आप फोन

var links = tree.links(nodes) 

आप डी जो एकल नोड के लिए दो पंक्तियों में जो परिणाम (बी और "स्रोत" क्रमशः के रूप में सी के साथ) में दो बार 'लक्ष्य' के रूप में प्रदर्शित मिलना चाहिए 'डी'।

+0

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

+0

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

10

आप क्रम में एक डी 3 लेआउट पर भरोसा करने के लिए यह कर पाने के बिना अपने स्वयं के कोड बना सकते हैं।

मैं एक example in a jsFiddle प्रदान की है। उदाहरण बहुत सरल है और अधिक जटिल उदाहरणों को समायोजित करने के लिए थोड़ा सा काम करने की आवश्यकता होगी।

उदाहरण को क्रमिक डेटा को संसाधित करने के साथ-साथ अपेक्षाकृत कम प्रयास के साथ फिर से काम किया जा सकता है।

// Sample data set 
var json = { 
    nodes: [{ 
     name: 'A'}, 
    { 
     name: 'B'}, 
    { 
     name: 'C'}, 
    { 
     name: 'D'}], 
    links: [{ 
     source: 'A', 
     target: 'B'}, 
    { 
     source: 'A', 
     target: 'C'}, 
    { 
     source: 'B', 
     target: 'D'}, 
    { 
     source: 'C', 
     target: 'D'} 
                        ] 

}; 

var vis = d3.select('#vis').attr('transform', 'translate(20, 20)'); 

// Build initial link elements - Build first so they are under the nodes 
var links = vis.selectAll('line.link').data(json.links); 
links.enter().append('line').attr('class', 'link').attr('stroke', '#000'); 

// Build initial node elements 
var nodes = vis.selectAll('g.node').data(json.nodes); 
nodes.enter().append('g').attr('class', 'node').append('circle').attr('r', 10).append('title').text(function(d) { 
    return d.name; 
}); 

// Store nodes in a hash by name 
var nodesByName = {}; 
nodes.each(function(d) { 
    nodesByName[d.name] = d; 
}); 

// Convert link references to objects 
links.each(function(link) { 
    link.source = nodesByName[link.source]; 
    link.target = nodesByName[link.target]; 
    if (!link.source.links) { 
     link.source.links = []; 
    } 
    link.source.links.push(link.target); 
    if (!link.target.links) { 
     link.target.links = []; 
    } 
    link.target.links.push(link.source); 
}); 

// Compute positions based on distance from root 
var setPosition = function(node, i, depth) { 
    if (!depth) { 
     depth = 0; 
    } 
    if (!node.x) { 
     node.x = (i + 1) * 40; 
     node.y = (depth + 1) * 40; 
     if (depth <= 1) { 
      node.links.each(function(d, i2) { 
       setPosition(d, i2, depth + 1); 
      }); 
     } 

    } 

}; 
nodes.each(setPosition); 

// Update inserted elements with computed positions 
nodes.attr('transform', function(d) { 
    return 'translate(' + d.x + ', ' + d.y + ')'; 
}); 

links.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; 
}); 
+3

उदाहरण के लिए धन्यवाद, फिल! मैं कुछ ऐसा ही कर रहा था। यह लेआउट एल्गोरिदम बाहर निकलता है जिसे मैं वास्तव में ग्राफवीज़ में लागू करना चाहता था। इसमें पाइथन बाइंडिंग है, लेकिन वे काम नहीं करते हैं।इसके बजाए मैंने निम्नलिखित किया: 1) डीओटी भाषा में फॉर्म ग्राफ़ (http://www.graphviz.org/content/dot-language) 2) ग्राफ़विज़ के डॉट कमांड को कमांडलाइन के माध्यम से ग्राफ पास करें, जो लेआउट और रखता है (एक्स, वाई) डीओटी में निर्देशांक 3) जावास्क्रिप्ट ऑब्जेक्ट्स में सुधार डीओटी, पेज में एम्बेड करें 4) डीओटी में (एक्स, वाई) निर्देशांक के अनुसार नोड्स रखने के लिए डी 3 का उपयोग करें। यह बहुत बड़े ग्राफ के साथ वास्तव में अच्छी तरह से काम करता है। –

7

इस उदाहरण के रूप में: "Force Directed Trees" दिखाता है एक चाल है कि अक्सर काम करता है

यहाँ कोड मैं jsFiddle में प्रयोग किया जाता है। उदाहरण में बल की दिशा का व्यवहार प्रत्येक टिक पर समायोजित किया जाता है ताकि लिंक की दिशा के आधार पर नोड थोड़ा ऊपर या नीचे आ जाए। जैसा कि दिखाया गया है कि यह पेड़ के लिए अच्छा काम करेगा, लेकिन मुझे पता चला है कि यह विश्वकोश ग्राफ के लिए सहनशील रूप से अच्छी तरह से काम करता है। कोई वादा नहीं, लेकिन यह मदद कर सकता है।

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