D3 datum ile veri arasındaki fark nedir?


199

Birisi D3.js'de datum () ve data () arasındaki farkı açıklayabilir mi? Her ikisinin de kullanıldığını görüyorum ve neden birini diğerinden seçmeniz gerektiğinden emin değilim?

Yanıtlar:


164

Mike'ın kendisinden doğru cevabı buldum:

D3 - JSON veri yapıları ile nasıl başa çıkılır?

Verilerinizi tek bir SVG öğesine bağlamak istiyorsanız şunu kullanın:

(...).data([data])

veya

(...).datum(data)

Verilerinizi birden çok SVG öğesine bağlamak istiyorsanız

(...).data(data).enter().append("svg")

.....


Bunun için teşekkür ederim! veri ([veri]) geçen ve dizi koymak sadece geçen hafta için anlayamadım bir hata fark etmeme yardımcı oldu! Çok teşekkür ederim ... her zaman yanlış olan aptalca şeyler.
Adam

22
data () bir birleştirme gerçekleştirir, datum () yapmaz.
s3-4v

Yalnızca, verileri bağlarken SVG öğelerinden daha fazla veri dizisi öğesi olması durumunda enter(), d3'ün dizi öğelerinin geri kalanını yeni oluşturulan SVG öğeleriyle bağlayacağını unutmayın.
aslantorret

49

Bunu biraz inceledikten sonra, burada çağırdığınızda selection.datave selection.datumbir giriş dataparametresiyle davayı kapsadıkları için SO'daki cevapların tam olmadığını gördüm . Bu senaryoda bile, seçim tek bir öğe ise birden çok öğe içeriyorsa, ikisi farklı davranır. Ayrıca, bu yöntemlerin her ikisi de seçimdeki bağlı verileri / verileri sorgulamak için herhangi bir giriş argümanı olmadan çağrılabilir, bu durumda bir kez daha farklı davranır ve farklı şeyler döndürürler.

Düzenle - Burada bu soruya biraz daha ayrıntılı bir cevap gönderdim , ancak aşağıdaki yazı iki yöntem ve birbirinden nasıl farklı oldukları ile ilgili tüm önemli noktaları ele alıyor.

Girdi argümanıdata olarak tedarik ederken

  • selection.data(data)Bir gerçekleştirmek için çalışır elemanları arasında veri-birleştirme dataoluşturulması ile sonuçlanan bir seçim ile dizi enter(), exit()ve update()sonradan üzerinde çalışabilir seçimleri. Bunun sonucu, bir dizi geçirirseniz, data = [1,2,3]her bir veri öğesini (yani veri) seçimle birleştirmeye çalışılır. Seçimdeki her öğenin yalnızca kendisine databağlı tek bir sıfır noktası öğesi olacaktır.

  • selection.datum(data)veri birleştirme işlemini tamamen atlar. Bu data, seçimdeki tüm öğelerin tamamını, veri birleştirme durumunda olduğu gibi bölmeden bir bütün olarak atar . Yani, dizinin tamamını DOM'unuzdaki data = [1, 2, 3]her DOM öğesine bağlamak istiyorsanız selection, selection.datum(data)bunu başaracaksınız.

Uyarı: Birçok kişi bununselection.datum(data)eşdeğerolduğuna inanır,selection.data([data])ancak bu yalnızcaselection tek bir öğe içeriyorsa geçerlidir . Birdenselectionfazla DOM öğesi içeriyorsa, seçimdeki her bir öğeninselection.datum(data)tamamını bağlardata. Buna karşılık,selection.data([data])sadece bütününündata içindeki ilk öğeyebağlanırselection. Bu, veri birleştirme davranışı ile tutarlıdırselection.data.

dataGirdi bağımsız değişkeni sağlamazken

  • selection.data()seçimdeki her öğe için ilişkili veriyi alır ve döndürülen bir dizi halinde birleştirir. Yani, eğer senin selectionverilerle 3 DOM öğelerini içerir "a", "b"ve "c"her sırasıyla bağlı selection.data()getiriler ["a", "b", "c"]. O eğer dikkat etmek önemlidir selectionverisi (örnek olarak) ile tek bir unsurdur "a"kendisine bağlı, sonra selection.data()geri döner ["a"]ve "a"bazı bekleyebilir olarak.

  • selection.datum()yalnızca seçimin ilk öğesine bağlı veriyi döndürmek olarak tanımlandığı için tek bir seçim için anlamlıdır . Yani yukarıdaki örnekte ve bağlı veri ile DOM öğelerinden oluşan seçim ile "a", "b"ve "c", selection.datum()sadece dönecekti "a".

Bile Not selectiontek bir öğeye sahiptir, selection.datum()ve selection.data()farklı değerler döndürür. Birincisi, seçim için ilişkili veriyi ( "a"yukarıdaki örnekte) verirken, ikincisi bir dizi içindeki bağlı veriyi ( ["a"]yukarıdaki örnekte) döndürür .

Umarım bu nasıl selection.dataveselection.datum() , hem giriş argümanı olarak veri sağlarken hem de herhangi bir girdi argümanı sağlayarak bağlı veriyi sorgularken birbirinden farklı olduğunu .

PS - Bunun nasıl çalıştığını anlamanın en iyi yolu, Chrome'da boş bir HTML belgesiyle başlamak ve konsolu açmak ve belgeye birkaç öğe eklemeyi denemek ve ardından selection.datave ile veri bağlamaya başlamaktır selection.datum. Bazen, bir şeyi "grok" yapmak, okumaktan çok daha kolaydır.


HamsterHuey bunu zaten gösterdi, ancak "referans" ın tekil ve "veri" nin çoğul olduğunu hatırlamak yararlı bir hatırlatma olabilir. Bu nedenle .datum, tek bir öğenin ilişkili bilgileri için geçerlidir.
Visio Guy

42

İşte bazı iyi bağlantılar:

İkincisi başına:

# selection.data([values[, key]])

Belirtilen veri dizisini geçerli seçimle birleştirir. Belirtilen değerler, bir sayı veya nesne dizisi veya bir değer dizisi döndüren bir işlev gibi bir veri değerleri dizisidir.

...

# selection.datum([value])

Seçilen her öğe için ilişkili verileri alır veya ayarlar. Selection.data yönteminden farklı olarak, bu yöntem bir birleştirme hesaplamaz (ve dolayısıyla enter ve exit seçimlerini hesaplamaz).


11
bu tanımları göz önüne alındığında - neden hala datum () kullanmak istediğinizi / istediğinizi karıştırıyorum
josephmisiti

İşleri daha net hale getirebilecek başka bir örnek: ngokevin.com/blog/d3 . NOTLAR: 1) Kevin'in tanımı: "Veri, elemana bağlanan verilerdir." 2) Kevin'in örneklerinde, veri kümesini "data ()" ile nasıl "birleştirdiğimizi" unutmayın ... ama bir "datum ()" referansıyla bir altkümeyi "nasıl kullanırız".
paulsm4

5

Bence HamsterHuey tarafından verilen açıklama şimdiye kadarki en iyisi. Üzerinde genişletmek ve ben arasındaki farkların az kısmında gösteren bir örnek belgeyi oluşturan farklılıkların bir görsel temsilini vermek datavedatum .

Aşağıdaki cevap, bu yöntemleri kullanmaktan türeyen bir görüştür, ancak yanılıyorsam düzeltildiğim için mutluyum.

Bu örnek aşağıda veya bu Fiddle'da çalıştırılabilir .

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}`)

bence datum bir birleşim yapmadığı için kavramak daha kolay, ama elbette bu farklı kullanım durumları olduğu anlamına geliyor.

Bana göre büyük bir fark - daha fazlası olmasına rağmen - databir kez olsun, tüm giriş / güncelleme / çıkış deseni basitleştirdiğinden, bir d3 grafiğinde güncellemeler yapmanın (canlı) doğal yoludur.

datumdiğer yandan bana statik temsiller için daha uygun görünüyor. Aşağıdaki örnekte ben orijinal dizide döngü ve böyle dizin tarafından verilere erişmek aynı sonucu elde edebilirsiniz:

data.map((n, i) => {
 el
  .append('div')
  .classed('a', true)
  .datum(data)
  .text(d => `node-${n} => data: ${d[i]}`);
});

Burada deneyin: https://jsfiddle.net/gleezer/e4m6j2d8/6/

Yine, giriş / güncelleme / çıkış deseninden gelen zihinsel yükten uzak kaldığınızda bunu kavramanın daha kolay olduğunu düşünüyorum, ancak seçimi güncellemeniz veya değiştirmeniz gerektiğinde kesinlikle başvurmanız daha iyi olacaktır .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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.