d3.js - JavaScript için d3'te, verileriniz için farklı elemanları nasıl oluşturursunuz?


Örneğin, bir HTML <table> içinde, bir <tr> <th> ve <td> içerebilir. Veriyi, çift sütunları <th> ve tek sütunları <td> olarak oluşturacak şekilde bir satır seçimine nasıl bağlarsınız?

Cevap #1

Yani, bu da mükemmel görünmüyor, ama her zaman html() yöntemi var.

var d = [['a','b','c','d']];

var r = d3.select('#myTable').selectAll('tr')
    .data(d);

r.enter().append('tr').html(function(d) {
    var i, s = '';
    for (i = 0; i < d.length; i += 1) {
        s += (i%2===0) ? '<th>' : '<td>';
        s += d[i];
        s += (i%2===0) ? '</th>' : '</td>';
    }
    return s;
});

Cevap #2

Anladığım kadarıyla, haklısınız - bunu standart D3 ifadesi içinde yapmanın bir yolu yok. Muhtemelen, selection.append() bir fonksiyon alabilir hale geldiğinde bu mümkün olacaktır:

selection.ekle(isim)

Belirtilen adla yeni bir öğe ekler... Adın sabit olarak belirtilmesi gerekir, ancak gelecekte mevcut öğelerin eklenmesine veya adı dinamik olarak oluşturmak için bir fonksiyon kullanılmasına izin verebiliriz.

Umarım böyle bir işlev, standart (data, index) argümanlarını alır ve bu problemi çözer. Aksi takdirde, şu anda, tek bir .enter() seçimi üzerinden farklı elemanlar oluşturmamın bir yolu göremiyorum - .enter() yalnızca .append, .insert ve .select'i destekler, bunların hiçbiri bir işlev argümanı alamaz.

Verileri tuple'lara dönüştürüp .enter() seçimine çift ekleme yaparak istediğiniz şeyin bir kısmını alabilirsiniz, burada gösterildiği gibi: http://jsfiddle.net/xuJ6w/4/

// munge data
var tuples = data.map(function(row) {
    var newRow = [],
        x;
    // create array of objects
    for (x=0; x<row.length; x+=2) {
        newRow.push({
            label: row[x],
            value: row[x+1]               
        })
    }
    return newRow;
});

var rows = d3.select('table').selectAll('tr')
    .data(tuples);

rows.enter().append('tr');
    
var cellPairs = rows.selectAll('.cell')
    .data(function(d) { return d; });
    
var entry = cellPairs.enter();
entry.append('th')
    .attr('class', 'cell')
    .text(function(d) {
        return d.label;
    });
entry.insert('td', 'th + th')
    .attr('class', 'cell')
    .text(function(d) {
        return d.value;
    });

Ama görebileceğiniz gibi, güncelleme çağrıldığında:

cellPairs
    .style('background', '#CCC');

Sadece en son eklenen düğümler güncelleniyor, bu yüzden veriler tam olarak bağlanmadı.