2012-11-12 6 views
12

मैं जहां वे हर जगह गहराई बदलती है और न चाबियों का एक ही सेट नेस्टेड JSON संरचनाओं की एक सरणी है:रिकर्सिवली (या पुनरावर्तक) d3.js के साथ एक नेस्टेड HTML तालिका बनाते हैं?

[ 
    { 
     "name":"bob", 
     "salary":10000, 
     "friends":[ 
      { 
       "name": "sarah", 
       "salary":10000 
      }, 
      { 
       "name": "bill", 
       "salary":5000 
      } 
     ] 
    }, 
    { 
     "name":"marge", 
     "salary":10000, 
     "friends":[ 
      { 
       "name": "rhonda", 
       "salary":10000 
      }, 
      { 
       "name": "mike", 
       "salary":5000, 
       "hobbies":[ 
        { 
         "name":"surfing", 
         "frequency":10 
        }, 
        { 
         "name":"surfing", 
         "frequency":15 
        } 
       ] 
      } 
     ] 
    }, 
    { 
     "name":"joe", 
     "salary":10000, 
     "friends":[ 
      { 
       "name": "harry", 
       "salary":10000 
      }, 
      { 
       "name": "sally", 
       "salary":5000 
      } 
     ] 
    } 
] 

मैं डी 3 उपयोग करने के लिए इस रूप में नेस्टेड एचटीएमएल टेबल प्रस्तुत करना चाहता था। उदाहरण के लिए दोस्तों के कॉलम में नाम दिखाए जाने वाले टेबल होंगे, और पंक्ति में संदर्भित व्यक्ति के दोस्तों का वेतन होगा। कभी-कभी इन तालिकाओं में से एक में उप-तालिका का एक और स्तर होगा।

मुझे लगता है कि ऐसा करने का तरीका बार-बार टेबल बनाना है। मैंने एक पायथन प्रोग्राम लिखा है जो इस तरह एक JSON संरचना लेता है, और तालिकाओं के भीतर तालिकाओं को प्रस्तुत करता है, और ऐसा करने का सबसे आसान तरीका पुनरावर्ती था। मैं d3.js दस्तावेज पर देखता हूं वहां .each() चीज है जिसे आप कॉल कर सकते हैं, जो मुझे यकीन है कि मुझे क्या चाहिए, मुझे बस थोड़ा बढ़ने की आवश्यकता है (https://github.com/mbostock/d3/wiki/Selections#wiki-each)।

तो क्या डी 3 में ऐसा करने का एक अच्छा तरीका है? मुझे तालिका के 0 डीके रूप में डेटा के 2 डी मैट्रिक्स को प्रस्तुत करने के लिए यह शानदार उदाहरण मिला। उस ट्यूटोरियल के साथ मैं तालिका के रूप में प्रस्तुत इस डेटा-स्ट्रक्चर का बाहरी स्तर प्राप्त करने में सक्षम था, लेकिन मैं आवश्यकतानुसार स्तरों में बार-बार कैसे जा सकता हूं, इस बारे में अटक गया हूं, क्योंकि अब वे तालिका में "ऑब्जेक्ट" के रूप में दिखाई देते हैं चूंकि मैं उन्हें सामान्य तारों और संख्याओं से अलग तरीके से इलाज नहीं कर रहा हूं।

इसके अलावा मुझे यह प्रश्न/उत्तर भी मिला जो मेरे प्रश्न के समान है, लेकिन मैं वास्तव में यह नहीं समझता कि जावास्क्रिप्ट कितनी अच्छी तरह से समझ रहा है कि रिकर्सन कहां/कैसे हो रहा है और मेरी जरूरतों को पूरा करने के लिए समाधान को पढ़ा गया है: How do I process data that is nested multiple levels in D3?। डी 3 में जेएसओएन डेटा-स्ट्रक्चर्स जैसे नेस्टेड पेड़ को पुनरावर्तित या पुन: संसाधित करने पर ट्यूटोरियल के लिए कोई सलाह या पॉइंटर्स बहुत सराहना की जाएगी!

उत्तर

18

एक रिकर्सिव फ़ंक्शन शायद अच्छा दृष्टिकोण होगा। एक संभावित कार्यान्वयन के लिए नीचे कोड देखें (मान लें कि आपका डेटा jdata में संग्रहीत है)। कुछ स्पष्टीकरण के लिए कोड में टिप्पणियाँ देखें और एक जीवित संस्करण के लिए इस सार देखें: http://bl.ocks.org/4085017

d3.select("body").selectAll("table") 
    .data([jdata]) 
    .enter().append("table") 
    .call(recurse); 

function recurse(sel) { 
    // sel is a d3.selection of one or more empty tables 
    sel.each(function(d) { 
    // d is an array of objects 
    var colnames, 
     tds, 
     table = d3.select(this); 

    // obtain column names by gathering unique key names in all 1st level objects 
    // following method emulates a set by using the keys of a d3.map() 
    colnames = d              // array of objects 
     .reduce(function(p,c) { return p.concat(d3.keys(c)); }, []) // array with all keynames 
     .reduce(function(p,c) { return (p.set(c,0), p); }, d3.map()) // map with unique keynames as keys 
     .keys();              // array with unique keynames (arb. order) 

    // colnames array is in arbitrary order 
    // sort colnames here if required 

    // create header row using standard 1D data join and enter() 
    table.append("thead").append("tr").selectAll("th") 
     .data(colnames) 
     .enter().append("th") 
     .text(function(d) { return d; }); 

    // create the table cells by using nested 2D data join and enter() 
    // see also http://bost.ocks.org/mike/nest/ 
    tds = table.append("tbody").selectAll("tr") 
     .data(d)       // each row gets one object 
     .enter().append("tr").selectAll("td") 
     .data(function(d) {     // each cell gets one value 
      return colnames.map(function(k) { // for each colname (i.e. key) find the corresponding value 
      return d[k] || "";    // use empty string if key doesn't exist for that object 
      }); 
     }) 
     .enter().append("td"); 

    // cell contents depends on the data bound to the cell 
    // fill with text if data is not an Array 
    tds.filter(function(d) { return !(d instanceof Array); }) 
     .text(function(d) { return d; }); 
    // fill with a new table if data is an Array 
    tds.filter(function(d) { return (d instanceof Array); }) 
     .append("table") 
     .call(recurse); 
    });  
} 
+0

आईटी जावास्क्रिप्ट फ़ाइल में अवैध वर्ण हैं! क्या मुझे वास्तव में लगभग 8000 लाइनों में इस चर को प्रतिस्थापित करने की आवश्यकता है? वास्तव में? wtf – msqar

+3

@msqar - नहीं, आपको बस यह निर्दिष्ट करने की आवश्यकता है कि यह यूटीएफ -8 है: https://github.com/mbostock/d3/wiki/Upgrading-to-3.0 देखें। आपको एक डॉक्टरेट की आवश्यकता है, एक <मेटा वर्णसेट = "यूटीएफ -8"> टैग, और आपकी स्क्रिप्ट को इस तरह शामिल करने की आवश्यकता है: dja

+0

अच्छा लग रहा है। सरणी सरणी के बारे में क्या? @nautat – bumpkin