Adakah yang bisa menjelaskan perbedaan antara datum () dan data () di D3.js? Saya melihat keduanya digunakan dan saya tidak yakin mengapa Anda harus memilih yang satu dari yang lain?
Adakah yang bisa menjelaskan perbedaan antara datum () dan data () di D3.js? Saya melihat keduanya digunakan dan saya tidak yakin mengapa Anda harus memilih yang satu dari yang lain?
Jawaban:
Saya menemukan jawaban yang benar di sini dari Mike sendiri:
D3 - bagaimana menangani struktur data JSON?
Jika Anda ingin mengikat data Anda ke elemen SVG tunggal, gunakan
(...).data([data])
atau
(...).datum(data)
Jika Anda ingin mengikat data Anda ke beberapa elemen SVG
(...).data(data).enter().append("svg")
.....
enter()
, d3 akan mengikat elemen array lainnya dengan elemen SVG yang baru dibuat.
Setelah melihat ini sedikit, saya telah menemukan bahwa jawaban di sini pada SO tidak lengkap karena mereka hanya membahas kasus ketika Anda memohon selection.data
dan selection.datum
dengan data
parameter input . Bahkan dalam skenario itu, keduanya berperilaku berbeda jika seleksi adalah elemen tunggal versus ketika mengandung banyak elemen. Selain itu, kedua metode ini juga dapat dipanggil tanpa argumen input apa pun untuk meminta data / datum terikat dalam seleksi, dalam hal ini mereka sekali lagi berperilaku berbeda dan mengembalikan hal-hal yang berbeda.
Sunting - Saya memposting jawaban yang sedikit lebih terperinci untuk pertanyaan ini di sini , tetapi posting di bawah ini cukup banyak menangkap semua poin kunci mengenai dua metode dan bagaimana mereka berbeda satu sama lain.
Saat memasok data
sebagai argumen input
selection.data(data)
akan berusaha melakukan penggabungan data antara elemen-elemen data
array dengan seleksi yang menghasilkan pembuatan enter()
, exit()
dan update()
seleksi yang selanjutnya dapat Anda operasikan. Hasil akhir dari ini adalah jika Anda meneruskan dalam array data = [1,2,3]
, upaya dilakukan untuk bergabung dengan setiap elemen data individu (yaitu datum) dengan seleksi. Setiap elemen dari seleksi hanya akan memiliki satu elemen datum yang data
terikat padanya.
selection.datum(data)
melewati proses penggabungan data sekaligus. Ini hanya menetapkan keseluruhan data
untuk semua elemen dalam pemilihan secara keseluruhan tanpa membaginya seperti dalam kasus data-bergabung. Jadi jika Anda ingin mengikat seluruh array data = [1, 2, 3]
ke setiap elemen DOM di Anda selection
, maka selection.datum(data)
akan mencapai ini.
Peringatan: Banyak orang percaya itu
selection.datum(data)
setara denganselection.data([data])
tetapi ini hanya benar jikaselection
mengandung satu elemen . Jikaselection
mengandung beberapa elemen DOM, makaselection.datum(data)
akan mengikat keseluruhandata
untuk setiap elemen tunggal dalam seleksi. Sebaliknya,selection.data([data])
hanya mengikat keseluruhandata
elemen pertama diselection
. Ini konsisten dengan perilaku data-joinselection.data
.
Saat memasok tidak ada data
argumen input
selection.data()
akan mengambil datum terikat untuk setiap elemen dalam seleksi dan menggabungkannya ke dalam array yang dikembalikan. Jadi, jika Anda selection
menyertakan 3 elemen DOM dengan data "a"
, "b"
dan "c"
terikat masing-masing, selection.data()
kembali ["a", "b", "c"]
. Penting untuk dicatat bahwa jika selection
merupakan elemen tunggal dengan (sebagai contoh) datum "a"
terikat padanya, maka selection.data()
akan kembali ["a"]
dan tidak "a"
seperti yang diperkirakan beberapa orang.
selection.datum()
hanya masuk akal untuk satu seleksi karena didefinisikan sebagai mengembalikan datum yang terikat ke elemen pertama seleksi. Jadi dalam contoh di atas dengan pemilihan yang terdiri dari elemen DOM dengan datum terikat "a"
, "b"
dan "c"
, selection.datum()
hanya akan kembali "a"
.
Perhatikan bahwa meskipun
selection
memiliki elemen tunggal,selection.datum()
danselection.data()
mengembalikan nilai yang berbeda. Yang pertama mengembalikan datum terikat untuk seleksi ("a"
dalam contoh di atas) sedangkan yang terakhir mengembalikan datum terikat dalam array (["a"]
dalam contoh di atas).
Semoga ini membantu memperjelas bagaimana selection.data
dan selection.datum()
berbeda satu sama lain ketika memberikan data sebagai argumen input dan ketika meminta datum terikat dengan tidak memberikan argumen input.
PS - Cara terbaik untuk memahami cara kerjanya adalah mulai dengan dokumen HTML kosong di Chrome dan membuka konsol dan mencoba menambahkan beberapa elemen ke dokumen dan kemudian mulai mengikat data menggunakan selection.data
dan selection.datum
. Terkadang, jauh lebih mudah untuk "grok" sesuatu dengan melakukan daripada membaca.
Berikut ini beberapa tautan bagus:
Diskusi yang bagus tentang D3 "data ()": Memahami bagaimana D3.js mengikat data ke node
Per yang terakhir:
# selection.data([values[, key]])
Bergabung dengan array data yang ditentukan dengan pilihan saat ini. Nilai yang ditentukan adalah larik nilai data, seperti larik angka atau objek, atau fungsi yang mengembalikan larik nilai.
...
# selection.datum([value])
Mendapat atau menetapkan data terikat untuk setiap elemen yang dipilih. Berbeda dengan metode selection.data, metode ini tidak menghitung gabungan (dan dengan demikian tidak menghitung masuk dan keluar dari pilihan).
Saya pikir penjelasan yang diberikan oleh HamsterHuey adalah yang terbaik sejauh ini. Untuk memperluas dan memberikan representasi visual dari perbedaan, saya membuat dokumen sampel yang menggambarkan setidaknya sebagian dari perbedaan antara data
dan datum
.
Jawaban di bawah ini lebih merupakan pendapat yang berasal dari menggunakan metode ini, tetapi saya senang bisa diperbaiki jika saya salah.
Contoh ini dapat dijalankan di bawah atau di Fiddle ini .
const data = [1,2,3,4,5];
const el = d3.select('#root');
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node => data: ${d}`);
const join= el
.selectAll('div.b')
.data(data);
join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)
Saya pikir itu datum
lebih mudah untuk dipahami karena tidak bergabung, tetapi tentu saja ini juga berarti memiliki kasus penggunaan yang berbeda.
Bagi saya satu perbedaan besar - walaupun ada lebih banyak - adalah kenyataan bahwa itu data
adalah cara alami untuk melakukan pembaruan (langsung) pada grafik d3, karena keseluruhan pola masuk / perbarui / keluar membuatnya mudah, setelah Anda mendapatkannya.
datum
di sisi lain menurut saya lebih cocok untuk representasi statis. Dalam contoh di bawah ini misalnya saya bisa mencapai hasil yang sama dengan pengulangan pada array asli dan mengakses data dengan indeks seperti ini:
data.map((n, i) => {
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node-${n} => data: ${d[i]}`);
});
Cobalah di sini: https://jsfiddle.net/gleezer/e4m6j2d8/6/
Sekali lagi, saya pikir ini adalah cara yang lebih mudah untuk dipahami karena Anda terbebas dari beban mental yang datang dari pola masuk / perbarui / keluar, tetapi segera setelah Anda perlu memperbarui atau mengubah pilihan Anda pasti akan lebih baik menggunakan .data()
.
const data = [1,2,3,4,5];
const el = d3.select('#root');
el
.append('div')
.classed('a', true)
.datum(data)
.text(d => `node => data: ${d}`);
const join= el
.selectAll('div.b')
.data(data);
join
.enter()
.append('div')
.classed('b', true)
.text((d, i) => `node-${i + 1} => data: ${d}`)
/* Ignore all the css */
html {
font-family: arial;
}
.l {
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
margin: 10px 0;
}
.l-a {
background: #cf58e4;
}
.l-b {
background: #42e4e4;
}
.a {
border-bottom: 2px solid #cf58e4;
}
.b {
border-bottom: 2px solid #42e4e4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.6.0/d3.min.js"></script>
<div style="margin-bottom: 20px;">
<span class="l l-a"></span> .datum() <br />
<span class="l l-b"></span> .data()
</div>
<div id="root"></div>