2013-01-25 24 views
3

我有這種可重複使用的模式來創建表格,受http://bl.ocks.org/3687826的啓發,我有兩個關於它的問題。使用可重複使用的圖表更新d3.js中的HTML表格

這是函數:

d3.table = function(config) { 
var columns = []; 

var tbl = function(selection) { 
if (columns.length == 0) columns = d3.keys(selection.data()[0][0]); 
console.log(columns)  

// Creating the table 
var table = selection.append("table"); 
var thead = table.append("thead"); 
var tbody = table.append("tbody"); 

// appending the header row 
var th = thead.selectAll("th") 
     .data(columns) 

th.enter().append("th"); 
    th.text(function(d) { return d }); 
th.exit().remove() 

// creating a row for each object in the data 
var rows = tbody.selectAll('tr') 
    .data(function(d) { return d; }) 

rows.enter().append("tr"); 
rows.attr('data-row',function(d,i){return i}); 
rows.exit().remove(); 

// creating a cell for each column in the rows 
var cells = rows.selectAll("td") 
     .data(function(row) { 
    return columns.map(function(key) { 
       return {key:key, value:row[key]}; 
    }); 
     }) 

cells.enter().append("td"); 
cells.text(function(d) { return d.value; }) 
    .attr('data-col',function(d,i){return i}) 
    .attr('data-key',function(d,i){return d.key}); 
cells.exit().remove(); 

return tbl; 
}; 

tbl.columns = function(_) { 
if (!arguments.length) return columns; 
columns = _; 
return this; 
}; 

return tbl; 
}; 

這個表可以被稱爲如下:

/// new table 
var t = d3.table(); 

/// loading data 
d3.csv('reusable.csv', function(error,data) { 
    d3.select("body") 
    .datum(data.filter(function(d){return d.price<850})) /// filter on lines 
    .call(t) 
}); 

其中reusable.csv文件是這樣的:

date,price 
Jan 2000,1394.46 
Feb 2000,1366.42 
Mar 2000,1498.58 
Apr 2000,1452.43 
May 2000,1420.6 
Jun 2000,1454.6 
Jul 2000,1430.83 
Aug 2000,1517.68 
Sep 2000,1436.51 

和列數可以更新

t.columns(["price"]); 
d3.select("body").call(t); 

問題在於更新時會創建另一個包含thead和tbody的表,因爲表的創建是在該函數內部。

我怎麼能說「創建表只有一次,然後更新」?

另一個問題是:我該如何過濾使用函數中的方法?

回答

4

的問題是這些三行代碼:

// Creating the table 
var table = selection.append("table"); 
var thead = table.append("thead"); 
var tbody = table.append("tbody"); 

總是追加新表,THEAD和TBODY元素到您的文檔。這裏是你如何能做到這一點條件,只有當不存在這些元素(你舉的例子同樣創建了div.header元素):

selection.selectAll('table').data([0]).enter().append('table'); 
var table = selection.select('table'); 

table.selectAll('thead').data([0]).enter().append('thead'); 
var thead = table.select('thead'); 

table.selectAll('tbody').data([0]).enter().append('tbody'); 
var tbody = table.select('tbody'); 

的全選()數據([0])。如果沒有找到,則輸入()。append()模式有條件地創建單個元素。引用的例子使用數據([true]),但任何具有單個元素的數組都可以。

要從函數中篩選嵌套的數據,更改數據通話(),並通過選擇數據的過濾子集是這樣的:

var rows = tbody.selectAll('tr').data(tbody.data()[0].filter(function(d) { 
    return d.price > 1400; 
})); 

祝你好運!

+0

很好的回答!感謝您的建議,我現在可以在所需元素內從頭創建表格。此外,如果(!arguments.length)返回行,則使用'tbl.lines = function(_){tbl.lines = function(_)}方法。 \t lines = _; 返回此; };'我現在可以像這樣過濾兩個元素:'t.columns([「price」])。lines(1400); 。d3.select( 「正文」)調用(T);'。對不起,沒有足夠的聲望來投票給你。 –

+0

只是一個建議:如果我用't.lines(d.price> 400)''過濾行,該怎麼辦? –