Cara menggunakan ANCESTORD pada JavaScript

Here's another pure method that uses element.compareDocumentPosition() and element.contains(), the former being a standards method and the latter being a method supported by most major browsers excluding Firefox:

Comparing two nodes

function getCommonAncestor(node1, node2) {
    var method = "contains" in node1 ? "contains" : "compareDocumentPosition",
        test   = method === "contains" ? 1 : 0x10;

    while (node1 = node1.parentNode) {
        if ((node1[method](node2) & test) === test)
            return node1;
    }

    return null;
}

Working demo: http://jsfiddle.net/3FaRr/ (using lonesomeday's test case)

This should be, more or less, as efficient as possible since it is pure DOM and has only one loop.


Comparing two or more nodes

Taking another look at the question, I noticed the "or more" part of the "two or more" requirement had gone ignored by the answers. So I decided to tweak mine slightly to allow any number of nodes to be specified:

function getCommonAncestor(node1 /*, node2, node3, ... nodeN */) {
    if (arguments.length < 2)
        throw new Error("getCommonAncestor: not enough parameters");

    var i,
        method = "contains" in node1 ? "contains" : "compareDocumentPosition",
        test   = method === "contains" ? 1 : 0x0010,
        nodes  = [].slice.call(arguments, 1);

    rocking:
    while (node1 = node1.parentNode) {
        i = nodes.length;    
        while (i--) {
            if ((node1[method](nodes[i]) & test) !== test)
                continue rocking;
        }
        return node1;
    }

    return null;
}

Working demo: http://jsfiddle.net/AndyE/3FaRr/1


This method collects all of element's ancestors and returns them as an array of extended elements.

Keep in mind that the body and html elements will also be included.

Syntax

element.ancestors();

Return Value

An array of HTML elements.

Example

<html>
   <head>
      <title>Prototype examples</title>
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      
      <script>
         function showElements() {
            var arr =  $('kid').ancestors();
            arr.each(function(node) {
               alert(node.nodeName + ': ' + node.innerHTML);
            });
         }
      </script>
   </head>

   <body>
      <div id = "father">
         <p id = "kid">This is first paragraph</p>
      </div>
      <br />
      
      <input type = "button" value = "showElements" onclick = "showElements();"/>
   </body>
</html>

Output

prototype_element_object.htm

Saat ini saya sedang mengerjakan percobaan silsilah kecil dan ingin menerapkan silsilah keluarga sederhana seperti pada gambar di bawah ini.

Sejauh ini hasil pencarian terbaik untuk ini hanya menghasilkan contoh di mana seorang anak hanya dapat memiliki simpul orangtua. Tetapi yang saya butuhkan adalah kemampuan untuk membuat tautan antara entitas (dari ayah ke ibu) dan tautan antara node dan tautan lainnya (dari anak ke ayah-ibu). ini.

Saya telah memilih d3.js untuk ini karena sepertinya akan mampu melakukan pekerjaan . Saya hanya tidak tahu bagaimana atau bahkan harus mulai dari mana. Tutorial tentang d3.js hanya mencakup bagan standar seperti bagan batang.

Saya berharap ada orang yang bisa membantu saya dalam hal ini.

Cara menggunakan ANCESTORD pada JavaScript

Pendekatan saya adalah sebagai berikut:

Mari kita ambil contoh yang telah Anda ilustrasikan pada gambar terlampir:

Jenny Of Oldstones juga merupakan anak dari Aegon V tetapi perbedaan antara anak ini dan anak-anak lain dari Aegon V adalah bahwa dalam kasus ini saya tidak menggambar tautan di antara itu.

Ini dilakukan dengan menetapkan simpul sebagai no_parent: true di simpul JSON Contoh:

//Here Q will not have a parent
 {
            name: "Q",
            id: 16,
            no_parent: true
 }

Dalam kode periksa fungsi _elbow_ ini melakukan pekerjaan untuk tidak menarik garis antara itu dan induknya:

if (d.target.no_parent) {
    return "M0,0L0,0";
}

Skenario berikutnya adalah hubungan antara Node Aerys II dan Rahella node ini memiliki anak-anak.

  • Saya telah membuat simpul di antara mereka yang ditandai sebagai hidden: true,
  • Saya membuat display:none untuk simpul tersebut. Tampaknya anak-anak tersebut berasal dari garis antara simpul Aerys II dan Rahella

Contoh JSON: 

//this node will not be displayed
{ name: "",
    id: 2,
    no_parent: true,
    hidden: true,
    children: [....]

    }

Dalam kode periksa tempat saya membuat persegi panjang, kode di bawah menyembunyikan simpul:

    .attr("display", function (d) {
    if (d.hidden) {
        return "none"
    } else {
        return ""
    };
})

Kode lengkap ada di sini: http://jsfiddle.net/cyril123/0vbtvoon/22/

Dalam contoh di atas, saya telah menggunakan nama simpul A/B/C ... tetapi Anda dapat mengubahnya sesuai kebutuhan Anda. Anda harus memusatkan teks.

Saya telah menambahkan komentar pada kode untuk membantu Anda memahami alur . Kalau-kalau Anda tidak jelas tentang hal apa pun, silakan komentar saya dengan senang hati akan menjelaskan.

dTree adalah pustaka sumber terbuka yang dibangun di atas D3 yang menciptakan pohon keluarga (atau grafik hierarkis serupa). 

Ini menangani bagian yang merepotkan dari menghasilkan grafik D3 secara manual dan menggunakan format data json sederhana: 

[{
  name: "Father",
  marriages: [{
    spouse: {
      name: "Mother",
    },
    children: [{
      name: "Child",
    }]
  }]
}]

Jika Anda tertarik untuk memodifikasi ini mendukung callback untuk rendering node dan event handler. Akhirnya perpustakaan pada 2016 dalam pengembangan dan permintaan tarik disambut.

PENOLAKAN: Saya penulis dTree. Saya membuat perpustakaan setelah mencari di web seperti yang Anda lakukan dan tidak menemukan apa pun yang saya sukai.

Saya tahu pertanyaan ini agak lama, tetapi jika ada yang masih tertarik, silakan lihat sampel saya di sini .

Berita tidak bagus: Penelitian yang saya lakukan menunjukkan bahwa tidak ada perpustakaan d3 out-of-the-box yang secara langsung menyelesaikan ini tanpa penyesuaian.

The good news: Ada beberapa orang lain yang telah menyelidiki hal ini dan telah menemukan beberapa titik awal yang bagus! Saya menyadari bahwa ini bukan solusi lengkap untuk seluruh tugas yang ada, tetapi tampaknya dari pertanyaan Anda, sebagian besar dari kesulitan Anda sejauh ini hanyalah mencari tahu dari mana harus memulai (mis. "Tutorial tentang d3.js hanya mencakup standar bagan seperti bagan batang. "). Dengan tidak adanya sesuatu yang lebih baik, saya setidaknya akan menanggapi bagian itu di sini.

Pertama, dalam menanggapi posting stackoverflow terkait ini dari beberapa tahun yang lalu, inanutshellus menyediakan beberapa alat d3 hebat yang are tersedia dan dapat digunakan di sini. Dengan beberapa penyesuaian/ekstensi ringan, mereka seharusnya bisa membawa Anda ke tempat yang relatif cepat. Untuk anak cucu, jawaban inanutshellus direproduksi di sini:

Ada beberapa opsi, tetapi saya yakin masing-masing akan membutuhkan sedikit kerja. Akan membantu jika ada satu standar tunggal untuk mewakili pohon keluarga di JSON. Saya baru-baru ini memperhatikan bahwa geni.com memiliki cukup API mendalam untuk ini. Mungkin pengkodean terhadap API mereka adalah ide yang bagus untuk digunakan kembali ...

- Pohon silsilah -

Pohon Silsilah mungkin cukup untuk kebutuhan Anda. Anda akan membuat tautan mertua, di mana jika Anda mengklik nama mereka, grafik akan digambar ulang sehingga Anda bisa lihat garis keturunan mereka.

- Pohon Tata Letak Braket -

Mirip dengan Pohon Silsilah, tetapi dua arah, Pohon Tata Letak Braket ini memungkinkan Anda menangani tampilan tipe "di sini adalah orang tua, kakek-nenek, anak-anak, cucu saya." Seperti Pohon Silsilah, Anda akan membuatnya individu yang dapat dihubungkan untuk memusatkan kembali braket pada simpul itu.

- Layout Berbasis Kekuatan -

Ada beberapa tata letak berbasis kekuatan yang menarik yang tampaknya menjanjikan . Lihatlah contoh a .__ ini. tata letak berbasis kekuatan dengan label pintar . Penyesuaian ke algoritma untuk bagaimana "kekuatan" ditentukan bisa membuat ini menjadi pohon yang sangat indah, dengan generasi yang lebih tua di atas atau di bawah yang lebih baru.

- Cluster Dendogram (mengapa gagal) -

Layout d3.js yang saya lihat akan cocok untuk keluarga pohon menganggap satu simpul adalah induknya, sedangkan Anda harus mewakili induk sebagai kombinasi (secara visual "T" antara) dua simpul: satu simpul yang merupakan anggota pohon Anda, dan satu mengambang simpul yang mewakili mertua. Menyesuaikan dendogram kluster untuk dilakukan ini harus layak tetapi bukan tanpa modifikasi yang signifikan.

Jika Anda - atau orang lain dalam hal ini - mengatasi ini, beri tahu saya. Saya akan. suka melihat (dan mendapat manfaat dari) pekerjaan dan mungkin dapat berkontribusi untuk itu jika layak.

Dalam hal implementasi konkret, mj8591 bertanya pertanyaan ini mengenai pohon keluarga yang sama dengan masalah yang berbeda. Namun, untungnya bagi Anda pertanyaan itu mencakup biola (semua kode js) yang memiliki sebagian besar atau semua komponen yang Anda butuhkan, dan respons dari mdml termasuk biola lain yang menambahkan "klik-klik" yang lebih terperinci untuk setiap simpul .

Sekali lagi, ini bukan sesuatu yang otomatis tetapi mudah-mudahan sumber daya ini cukup untuk membuat Anda memulai!

Saya mencoba dtree dan menyukainya. Namun, ketika Anda menambahkan beberapa generasi, tampilan horizontal dapat membuat tampilan keseluruhan sangat besar dan berat. Sebagai gantinya, saya menggunakan Reingold – Tilford Tree . Salah satu kelemahan dari pohon ini adalah setiap node hanya dapat memiliki satu orangtua: pasangan tidak dapat ditampilkan bersama satu sama lain: Untuk melewati batasan ini, saya mengubah JSON untuk menggabungkan pasangan menjadi satu entitas (mis: "suami - istri") sebelum mengirim ke pohon.