2012-01-05 15 views
66

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

इस उदाहरण में, http://jsfiddle.net/xReHA/, मैं सभी लिंक और नोड्स को फीका करने में सक्षम हूं, फिर कनेक्टेड लिंक में फीका है, लेकिन, अब तक, मैं जुड़े हुए नोड्स में सुंदर ढंग से फीका नहीं कर पाया वर्तमान में mouseover'd नोड का।

function fade(opacity) { 
    return function(d, i) { 
     //fade all elements 
     svg.selectAll("circle, line").style("opacity", opacity); 

     var associated_links = svg.selectAll("line").filter(function(d) { 
      return d.source.index == i || d.target.index == i; 
     }).each(function(dLink, iLink) { 
      //unfade links and nodes connected to the current node 
      d3.select(this).style("opacity", 1); 
      //THE FOLLOWING CAUSES: Uncaught TypeError: Cannot call method 'setProperty' of undefined 
      d3.select(dLink.source).style("opacity", 1); 
      d3.select(dLink.target).style("opacity", 1); 
     }); 
    }; 
} 

मैं एक Uncaught TypeError: Cannot call method 'setProperty' of undefined त्रुटि हो रही है जब मैं एक तत्व मैं source.target से लोड पर अस्पष्टता सेट करने का प्रयास:

इस कोड से महत्वपूर्ण कार्य है। मुझे संदेह है कि यह नोड को डी 3 ऑब्जेक्ट के रूप में लोड करने का सही तरीका नहीं है, लेकिन लिंक के लक्ष्य या स्रोत से मेल खाने वाले लोगों को खोजने के लिए मुझे फिर से नोड्स पर फिर से घुमाने के बिना इसे लोड करने का कोई और तरीका नहीं मिल रहा है। प्रदर्शन को उचित रखने के लिए, मैं आवश्यकतानुसार सभी नोड्स पर फिर से शुरू नहीं करना चाहता हूं।

मैं http://mbostock.github.com/d3/ex/chord.html से लिंक fading का उदाहरण ले लिया:

enter image description here

हालांकि, कि कैसे जुड़ा बच्चे नोड्स को बदलने के लिए नहीं दिखाती है।

कैसे हल करने या इस को सुधारने के लिए किसी भी अच्छा सुझाव जिस upvoted हो जाएगा :)

उत्तर

86

त्रुटि है, क्योंकि आप डेटा वस्तुओं (d.source और d.target) के बजाय डोम तत्वों के साथ जुड़े चयन कर रहे हैं उन डेटा ऑब्जेक्ट्स।

आप लाइन काम कर रहे प्रकाश डाला है, लेकिन मैं शायद इस तरह, एक एकल पुनरावृत्ति में अपने कोड गठबंधन होगा: क्योंकि जो आप के लिए पड़ोसियों पता करने की जरूरत

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

पड़ोसी नोड्स हाइलाइट करना कठिन है प्रत्येक नोड। यह जानकारी आपके वर्तमान डेटा संरचनाओं के साथ निर्धारित करना इतना आसान नहीं है, क्योंकि आपके पास नोड्स की एक सरणी और लिंक की एक सरणी है। एक दूसरे के लिए डीओएम भूल जाओ, और खुद से पूछें कि आप कैसे निर्धारित करेंगे कि दो नोड्स a और b पड़ोसियों हैं?

function neighboring(a, b) { 
    // ??? 
} 

ऐसा करने के लिए एक महंगा तरीका लिंक का सब कुछ खत्म पुनरावृति और देखने के लिए अगर वहाँ एक लिंक ए और बी से कनेक्ट करती है है:।

function neighboring(a, b) { 
    return links.some(function(d) { 
    return (d.source === a && d.target === b) 
     || (d.source === b && d.target === a); 
    }); 
} 

(मतलब यह है कि लिंक अनिर्दिष्ट हैं आप केवल अग्रेषित पड़ोसियों को हाइलाइट करना चाहते हैं, फिर OR के दूसरे भाग को खत्म करना चाहते हैं।)

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

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

अब आप कह सकते हैं:

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

और इस तरह, अब आप सही ढंग से नोड पर पुनरावृति और अद्यतन कर सकते हैं उनके अस्पष्टता:

node.style("opacity", function(o) { 
    return neighboring(d, o) ? 1 : opacity; 
}); 

(तुम भी चाहते हो सकता है विशेष रूप से माउस कवर लिंक, या तो linkedByIndex में प्रत्येक नोड के लिए स्वयं-लिंक सेट करके, या शैली की गणना करते समय या d के लिए परीक्षण करके या सीधे उपयोग करके ए! महत्वपूर्ण सीएसएस :hover शैली।)

आखिरी बात जो मैं आपके कोड में बदलूंगा वह अस्पष्टता के बजाय भरने वाली अस्पष्टता और स्ट्रोक-अस्पष्टता का उपयोग करना है, क्योंकि ये बहुत बेहतर प्रदर्शन प्रदान करते हैं।

+1

यह महान @mbostock काम करता है, बहुत बहुत धन्यवाद: डी मैंने आपके समाधान के साथ [jsfiddle] (http://jsfiddle.net/xReHA/1/) अपडेट किया है। –

+1

लिंक पर शैली के लिए एक अनावश्यक कॉल हटा दी गई: http://jsfiddle.net/xReHA/2/ –

+0

माइक, वह समाधान बस सुंदर था। मैं तो बस कह रहा हूं'। – Vivek

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