dom - डीओएम तत्व का उपयोग कैसे करें जो डी 3 एसवीजी ऑब्जेक्ट से संबंधित है?





svg visualization data-visualization d3.js (4)


किसी एसवीजी दस्तावेज़ में किसी भी DOM तत्व में एक ownerSVGElement गुण होगा जो उस SVG दस्तावेज़ का संदर्भ देता है।

डी 3 के चयन केवल उन पर अतिरिक्त तरीकों के साथ घोंसला वाले सरणी हैं; यदि आपके पास है। एक डीओएम तत्व .select() संपादित करें, तो आप इसे [0][0] साथ प्राप्त कर सकते हैं, उदाहरण के लिए:

var foo = d3.select(someDOM);

// later, where you don't have someDOM but you do have foo
var someDom = foo[0][0];
var svgRoot = someDom.ownerSVGElement;

नोट, हालांकि, यदि आप d3.select(this) का उपयोग कर रहे हैं तो this पहले ही डीओएम तत्व है; आपको बस इसे खोलने के लिए इसे डी 3 चयन में लपेटने की आवश्यकता नहीं है।

मैं अपने मूल बबलचार्ट्स में से एक के साथ प्रयोग करके डी 3 सीखने की कोशिश कर रहा हूं। पहला कार्य: एक बुलबुला खींचने के तरीके को समझें और इसे खींचा जा रहा है, जबकि यह शीर्ष वस्तु बन गया है। (समस्या DOM के ऑब्जेक्ट मॉडल को DOM पर मैप करने के लिए मिल रही है, लेकिन मैं वहां जाऊंगा ...)

इसे खींचने के लिए, हम केवल उनके द्वारा प्रदान किए गए कोड का उपयोग करके डी 3 के ड्रैग व्यवहार का आह्वान कर सकते हैं:

var drag = d3.behavior.drag()
    .on("dragstart", dragstart)
    .on("drag", dragmove)
    .on("dragend", dragend);

बहुत अच्छा काम करता है। अच्छी तरह से drags। अब, हम इसे सबसे ऊपर आइटम कैसे प्राप्त करते हैं? यहां "svg z-index" के लिए खोजें और यह जल्दी से स्पष्ट हो जाता है कि इंडेक्स को बदलने का एकमात्र तरीका डीओएम में ऑब्जेक्ट को आगे ले जाना है। ठीक। वे इसे आसान नहीं बनाते क्योंकि व्यक्तिगत बुलबुले में आईडी नहीं होती है, लेकिन कंसोल के साथ घूमती है, हम उन बबल ऑब्जेक्ट्स में से एक को ढूंढ सकते हैं:

$("text:contains('TimeScale')").parent()

और हम इसे युक्त svg तत्व के अंत में ले जा सकते हैं:

.appendTo('svg')

ऐसा करने के बाद इसे खींचें, और यह सबसे ज्यादा आइटम है। अब तक, बहुत अच्छा है, अगर आप पूरी तरह से डोम के भीतर काम कर रहे हैं।

लेकिन: मैं वास्तव में क्या करना चाहता हूं, जब भी कोई ऑब्जेक्ट / बबल ड्रैग किया जा रहा हो, वह स्वचालित रूप से होता है। डी 3 dragend() dragstart() और dragend() फ़ंक्शंस के लिए एक मॉडल प्रदान करता है जो हमें ड्रैगिंग प्रक्रिया के दौरान जो कुछ भी करना चाहते हैं, उसे करने के लिए हमें एक कथन एम्बेड करने की अनुमति देगा। और डी 3 d3.select(this) वाक्यविन्यास प्रदान करता है जो हमें वर्तमान में खींच रहे ऑब्जेक्ट / बबल के d3 के ऑब्जेक्ट प्रस्तुति तक पहुंचने की अनुमति देता है। लेकिन मैं उस बड़े पैमाने पर सरणी को कैसे बदल सकता हूं जो वे एक डोम तत्व के संदर्भ में लौटते हैं जिसे मैं सहभागिता कर सकता हूं - उदाहरण के लिए - इसे एसवीजी कंटेनर के अंत में ले जाएं, या डीओएम में अन्य संदर्भों को निष्पादित करें, जैसे फ़ॉर्म सबमिशन ?




यदि आप संलग्न करते हैं तो आप व्यक्तिगत तत्वों को आईडी और कक्षाएं असाइन कर सकते हैं:

node.append("circle.bubble")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return fill(d.packageName); })
.attr("id", function(d, i) { return ("idlabel_" + i)})
.attr("class", "bubble")
;

और फिर आप selectAll ("circle.bubble") के साथ कक्षा द्वारा चयन कर सकते हैं या आईडी द्वारा चयन कर सकते हैं और इस तरह के गुणों को संशोधित कर सकते हैं:

var testCircle = svg.select("#idlabel_3")
.style("stroke-width", 8);



आप चयन.नोड () विधि के माध्यम से चयन द्वारा प्रतिनिधित्व किए गए DOM तत्व पर भी प्राप्त कर सकते हैं

var selection = d3.select(domElement);

// later via the selection you can retrieve the element with .node()
var elt = selection.node();



दानमन, मार्टन और मैट के जवाब में। पाठ को सेट करने के लिए एक नोड क्लोन करना वास्तव में मेरे परिणामों में एक व्यवहार्य तरीका है।

// @param {node} node
// @return {node} empty node
function removeAllChildrenFromNode (node) {
  var shell;
  // do not copy the contents
  shell = node.cloneNode(false);

  if (node.parentNode) {
    node.parentNode.replaceChild(shell, node);
  }

  return shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = removeAllChildrenFromNode( myNode );

यह भी उन नोड्स के लिए काम करता है जो डोम में नहीं हैं जो parentNode तक पहुंचने का प्रयास करते समय शून्य लौटते हैं। इसके अतिरिक्त, यदि आपको सुरक्षित होने की आवश्यकता है तो सामग्री जोड़ने से पहले नोड खाली है, यह वास्तव में सहायक है। नीचे उपयोग मामले पर विचार करें।

// @param {node} node
// @param {string|html} content
// @return {node} node with content only
function refreshContent (node, content) {
  var shell;
  // do not copy the contents
  shell = node.cloneNode(false);

  // use innerHTML or you preffered method
  // depending on what you need
  shell.innerHTML( content );

  if (node.parentNode) {
    node.parentNode.replaceChild(shell, node);
  }

  return shell;
}

// use as such
var myNode = document.getElementById('foo');
myNode = refreshContent( myNode );

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





dom svg visualization data-visualization d3.js