2016-01-20 60 views
1

假設我有一個名爲state的2d數組,看起來像[[0,1,0],[1,1,0],[1,2,1]]。這個陣列的成員不斷更新。我已經成功地D3與渲染下面的代碼陣列中的每個成員:D3和更新多維數組的元素

function view(state) 
    const vis = d3.select('body') 
       .selectAll('div') 
       .data(state) 
       .enter() 
        .append('div') 
        .attr('style', 'display: flex') 
        .selectAll('span') 
        .data((d,i) => d) 
        .enter() 
        .append('span') 
        .text(d => d) 
    return vis 
} 

現在考慮這個view函數被調用每一個我state變化的時間。我如何才能讓D3重新渲染自上一次渲染後發生更改的元素?目前,該頁面最初呈現,但D3從不重新渲染任何元素,儘管在每次狀態更改時調用了view函數。

如果你想看到完整的源代碼,我張貼here

回答

1

呀來處理,你需要利用enter你正在做創建新的元素和exit除去這種情況任何不在當前數組中的元素。

我會建議你做這種方式:

function view(state) 
    var visData = d3.select('body') 
       .selectAll('div') 
       .data(state, function(d){/*uniquely identify each element in array*/return d;}); 

    const vis = visData.enter() 
        .append('div') 
        .attr('style', 'display: flex') 
        .selectAll('span') 
        .data((d,i) => d) 
        .enter() 
        .append('span') 
        .text(d => d); 
    //remove the unnecessary data divs. 
    visData.exit().remove(); 

    return vis 
} 

而且在輸入exit read

0

您有2情況下,當你想使您的數據:當你添加新的視圖元素(div的,跨度和文本)以及何時更新數據(文本)。在你的代碼中,你只完成了第一步。你應該做第二個。

d3.js提供了兩種情況的選擇。當你寫

var div = d3.select('body').selectAll('div'); 

你得到什麼已經存在你的看法。但如果您添加.enter(),即

var div = d3.select('body').selectAll('div').enter(); 

它已經是第二種情況。你得到了尚不存在的東西,並且應該被創建。

由於您的數據正在改變,您應該將代碼分爲兩部分:視圖創建,視圖更新。

這裏是a JSFiddle example它是如何爲你做的代碼。這個例子可以改進,創建/更新代碼段可以分開並放到相應的功能see there

無論如何,我鼓勵您閱讀d3.js的general update pattern