2013-08-29 2 views
9

मैं एक जावास्क्रिप्ट फ़ंक्शन बनाना चाहता हूं जो सामान्य डी 3 चयन ले सकता है, और इसे एसवीजी ऑब्जेक्ट में डुप्लीकेट जोड़ सकता है।डी 3: चयन के डुप्लिकेट संलग्न करें

<!DOCTYPE html> 
<meta charset="utf-8"> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

svg = d3.select("body").append("svg") 
         .attr("width", 300) 
         .attr("height", 300); 

circle = svg.append("circle") 
       .attr("cx", 100) 
       .attr("cy", 100) 
       .attr("r", 20) 

function clone_selection(x, i) { 
    for (j = 0; j < i; j++) { 
    // Pseudo code: 
    // svg.append(an exact copy of x, with all the attributes) 
    } 
} 

clone_selection(circle, 5); 
</script> 

माइक Bostock ने कहा कि यह असंभव here था, लेकिन है कि एक समय पहले किया गया था:

यहाँ एक न्यूनतम काम कर उदाहरण है।

क्या किसी के पास इस बारे में कोई नया विचार है कि यह कैसे प्राप्त किया जा सकता है? याद रखें, फ़ंक्शन clone_selection के अंदर हमें नहीं पता कि svg तत्व क्या है x में है।

+0

क्या आप ['क्लोन नोड'] (http://www.w3schools.com/jsref/met_node_clonenode.asp) जैसे कुछ ढूंढ रहे हैं? –

+2

क्या आपको एक वास्तविक क्लोन की आवश्यकता है, या तत्व काम करेंगे? – nrabinowitz

+0

दोनों टिप्पणियों के लिए धन्यवाद। यद्यपि इनमें से कोई भी सामान्य जे 3 चयन के साथ काम नहीं करता है। इस बारे में और अधिक बातचीत है [यहां] (https://github.com/mbostock/d3/pull/732#issuecomment-7390693) लेकिन मुझे लगता है कि select.clone() विधि माइक Bostock उल्लेख अभी तक लागू नहीं किया गया है। – LondonRob

उत्तर

9

यहाँ एक और संभावना है:: बातें लंबा रास्ता तय करना

यहाँ मेगावाट काम कर समाधान के साथ पूरा है। यह <use> तत्वों का उपयोग करने में समस्या को हल करता है जहां आप style या transform विशेषताओं को अलग से सेट नहीं कर सकते हैं।

मैं अद्भुत d3js पुस्तकालय देशी रूप कुछ इस तरह की सुविधा नहीं है हैरान हूँ, लेकिन यहाँ मेरी हैक है:

function clone_d3_selection(selection, i) { 
      // Assume the selection contains only one object, or just work 
      // on the first object. 'i' is an index to add to the id of the 
      // newly cloned DOM element. 
    var attr = selection.node().attributes; 
    var length = attr.length; 
    var node_name = selection.property("nodeName"); 
    var parent = d3.select(selection.node().parentNode); 
    var cloned = parent.append(node_name) 
       .attr("id", selection.attr("id") + i); 
    for (var j = 0; j < length; j++) { // Iterate on attributes and skip on "id" 
     if (attr[j].nodeName == "id") continue; 
     cloned.attr(attr[j].name,attr[j].value); 
    } 
    return cloned; 
} 
4

<use> तत्वों को इंगित करने के लिए @nrabinowitz के लिए धन्यवाद।

<!DOCTYPE html> 
<meta charset="utf-8"> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

svg = d3.select("body").append("svg") 
      .attr("width", 300) 
      .attr("height", 300); 

circle = svg.append("circle") 
      .attr("id", "circleToClone") 
      .attr("cx", 100) 
      .attr("cy", 100) 
      .attr("r", 20) 

function clone_selection(object, i) { 
    for (j = 0; j < i; j++) { 
    // Here's the solution: 
    cloned_obj = svg.append("use") 
       .attr("xlink:href","#" + object.attr("id")); 
    } 
} 

clone_selection(circle, 5); 
</script> 
+0

हम्म .. मैंने अभी परीक्षण किया है यह और यह पता चला है कि यह विधि आदर्श नहीं है, क्योंकि आप 'शैली' या 'ट्रांसफॉर्म' गुणों को' 'ऑब्जेक्ट्स पर लागू नहीं कर सकते हैं। इसका मतलब है कि आप प्रारंभिक वस्तु की असली प्रतियों के साथ अटक गए हैं। ड्राइंग बोर्ड पर वापस ... – LondonRob

+0

हम्म - मुझे पूरा यकीन है कि आप 'उपयोग' तत्व पर' fill', 'cx',' cy', आदि जैसे गुणों को ओवरराइड कर सकते हैं। मुझे आश्चर्य है कि आप 'ट्रांसफॉर्म' का उपयोग नहीं कर सकते हैं, लेकिन आप हमेशा तत्व को 'जी' में ट्रांसफॉर्म और स्टाइल के साथ लपेट सकते हैं। – nrabinowitz

+0

यह बेहतर जवाब होना चाहिए :) बहुत बहुत धन्यवाद। –

3

इस समारोह d3 के चयन की एक गहरी प्रतिलिपि बनाता है और की नकल की तत्वों का चयन देता है:

function cloneSelection(appendTo, toCopy, times) { 
    toCopy.each(function() { 
    for (var i = 0; i < times; i++) { 
     var clone = svg.node().appendChild(this.cloneNode(true)); 
     d3.select(clone).attr("class", "clone"); 
    } 
    }); 
    return appendTo.selectAll('.clone'); 
} 

डेमो here देखें।

यह फ़ंक्शन भी काम करता है यदि चयन को कॉपी में कई तत्व होते हैं।

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

करने के लिए एक उचित चीज (यदि आपको वास्तव में बहुत अधिक आईडी की आवश्यकता है) तो आईडी को केवल कॉपी करने के बाहरी तत्व पर सेट करना है, जहां आप आसानी से फ़ंक्शन को संशोधित करके इसे बदल सकते हैं: d3.select(clone).attr("class", "clone").attr("id", "clone-" + i)

0

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

d3.select("#some_id") 
     .append("div") 
     .attr("class","some_other_id") 
     .each(function(d) { 

    for (var i = 1; i < number_duplicate; i++) { 
     d3.select("#some_other_id") 
      .append("button") 
      .attr("type","button") 
      .attr("class","btn-btn") 
      .attr("id","id_here") 
      .append("div") 
      .attr("class","label") 
      .text("text_here") 


    } 
}); 

मैं एक div, do.each() बना देता हूं और प्रत्येक फ़ंक्शन में लूप डालता हूं। संख्या कुछ संख्या मुझे डुप्लिकेट की इच्छित राशि देगी।

विविधता संभव होगी, शायद काम करने के लिए एक सेकंड आदि। शायद एक गरीब आदमी का संस्करण - मैं समर्थक नहीं हूं। मैं आपकी फीड वापस सुनना चाहता हूं।