2013-08-13 10 views
25

FooTable jquery plugin tarafından kullanılmak üzere d3 içeren bir tablo oluşturuyorum ve bu, başlık satırında bazı veri özelliklerine sahip olmayı gerektirir. Ancak, tüm sütunlar tüm veri özelliklerine sahip değildir ve bunu yapmanın bir yolu olup olmadığını merak etmemektedir.d3 koşullu olarak veri özniteliği ekleme

Bu yaklaşım, tüm olası veri niteliklerini ekleyerek ve biraz boşluk bırakarak çalışır, ancak eminim ki bu iyi bir uygulama değildir.

var th = d3.select(selection).select("thead").selectAll("th") 
      .data(colspec) 
      .enter().append("th") 
      .text(function(d) { return d["data-name"]; }) 
      .attr("data-class", function(d) { 
       if ("data-class" in d) { 
        return d["data-class"]; 
       } else { 
        return ""; 
       } 
      }) 
      .attr("data-hide", function(d) { 
       if ("data-hide" in d) { 
        return d["data-hide"]; 
       } else { 
        return ""; 
       } 
      }) 
      .attr("data-ignore", function(d) { 
       if ("data-ignore" in d) { 
        return d["data-ignore"]; 
       } else { 
        return ""; 
       } 
      }) 

     etc. 

colspec örnek:

[{"data-name": "username"}, {"data-name": "Date Joined", "data-hide": "true"}] 

Şu alma:

<th data-class="" data-hide="true" data-ignore="" data-type="">Joined</th> 

<th data-hide="true" >Joined</th> 

herhangi bir öneriniz ister misiniz?

+0

+ 1'lediniz * Yani – Joum

+0

FooTable için * alanı gösterme, değil mi? – Joum

+0

O zeki olmayı denemeyin (henüz!) Yukarıdaki yorum eklendi. – PhoebeB

cevap

26

.each() için iyi bir aday gibi görünüyor: Tek tek öğeler kapsamı her öğe için niteliklerin bir demet anlamaya çalışıyorum daha mantıklı içerken

var th = d3.select(selection).select("thead").selectAll("th") 
     .data(colspec) 
    .enter().append("th") 
     .text(function(d) { return d["data-name"]; }) 
     // now address each item individually 
     .each(function(d) { 
      var header = d3.select(this); 
      // loop through the keys - this assumes no extra data 
      d3.keys(d).forEach(function(key) { 
       if (key != "data-name") 
        header.attr(key, d[key]); 
      }); 
     }); 

Sık sık .each kullanın. Sen gerekmez

 .each(function(d) { 
      var header = d3.select(this); 
      ['data-class', 'data-hide', 'data-ignore'].forEach(function(key) { 
       if (key in d) 
        header.attr(key, d[key]); 
      }); 
     }); 
+1

Oh bu çok zekice! Teşekkürler. – PhoebeB

+0

Neden .each içinde bir forEach'a ihtiyacınız var? – Kraken

+0

.each, veri nesneleri (satırlar) arasında döngü yaparken, bu örnekte, her bir öğeye (cols) uygulanacak öznitelikler arasında döngü yaparken. – nrabinowitz

6

.filter() işlevini, yalnızca nitelikleri ayarlamanız gereken seçimin alt kümesinde çalışmak için kullanabilirsiniz.

var th = d3.select(selection).select("thead").selectAll("th") 
     .data(colspec) 
     .enter().append("th") 
     .text(function(d) { return d["data-name"]; }); 
th.filter(function(d) { return ("data-class" in d); }) 
     .attr("data-class", function(d) { 
      return d["data-class"]; 
     }); 
+0

Filtre fikri daha az zorlayıcı olmasına rağmen, altı kez (veri nitelikleri sayısı) elemanlar arasında dolaşmaktan kaçınmayı umuyordum. Tek geçişte satır içi yapmanın bir yolu yok mu? – PhoebeB

+0

Başka bir yaklaşım, sadece anahtarlama ve öznitelik ayarını yapan her elemanın bir işlevini çağırmak olabilir. Bu şekilde, her bir öğeye yalnızca bir kez dokunursunuz. –

44

: Eğer nesneler ilave veriler hakkında endişeleniyorsanız özellikle niteliklerin kısa listesi için

, bunun yerine her şeyin istenilen anahtarların döngü muhtemelen daha kolay her() veya filter() ... 'ı çağırın. attr() işlevi bunu dahili olarak yapar. Sadece yerine bir değerin bir fonksiyonu olan diyoruz ve bu işlev her datum için istenen değer döndürmek varsa, ya da boş niteliği, belli bir datum için istenen şöyle değilse:

... 
.attr('data-class', function(d) { 
    return 'data-class' in d ? d['data-class'] : null; 
}); 

sizin fonksiyon döner olursa null, özellik eklenmedi. Hatta şöyle işlevlerine attr isimleri bir harita sağlayarak bir çağrıda birkaç özelliklerini birleştirebilirsiniz:

... 
.attr({ 
    'data-class': function(d) { 
     return 'data-class' in d ? d['data-class'] : null; 
    }, 
    'data-hide': function(d) { 
     return 'data-hide' in d ? d['data-hide'] : null; 
    }, 
    'data-ignore': function(d) { 
     return 'data-ignore' in d ? d['data-ignore'] : null; 
    } 
}); 

yoksa benim gibi ve oldukça çok türü olmaz, sen özelliğin listesini azaltabilir uygun harita haline isimleri: belirli bir hücre veri yok olduğunda soru düz,, tablonun _minified_ versiyonunu istiyorum sahipsek sadece beni tanıştırmak için

... 
.attr(['data-class', 'data-hide', 'data-ignore'].reduce(function(result, attr) { 
    result[attr] = function(d) { 
     return attr in d ? d[attr] : null; 
    } 
    return result; 
}, {})); 
+8

+1, bir null özniteliğinin eklenmediğini belirtmek için + – Breiz

+0

Bu, veriye dayalı oluşturma için küçük değişiklikler varsa iyi çalışır. Bazı veri anahtarlarına göre tamamen farklı bir nesne oluşturmak istiyorsanız, bence .each() daha kısadır. – bryanph