2017-03-02 19 views
0

在版本d3 v3中,我的一個常見工作流程是創建幾個svg組元素,然後爲每個g添加一些其他子元素。作爲一個例子,下面我創建了3個組元素,併爲每個組附加了一個圓。然後我用selection.each方法來更新每個圓的半徑:使用嵌套元素難以理解d3版本4選擇生命週期

var data = [2, 4, 8] 

    var g = d3.select('svg').selectAll('.g').data(data) 
    g.each(function(datum) { 
    var thisG = d3.select(this) 
    var circle = thisG.selectAll('.circle') 

    circle.transition().attr('r', datum * 2) 
    }) 

    var enterG = g.enter().append('g').attr('class', 'g') 
    enterG.append('circle') 
    .attr('class', 'circle') 
    .attr('r', function(d) { return d }) 

    g.exit().remove() 

什麼是D3 V4這樣做的正確方法?我很困惑如何最好地做到這一點。這裏是我想要的一個例子:

var data = [2, 4, 8] 

    var g = d3.select('svg').selectAll('.g').data(data) 

    g.enter() 
    // do stuff to the entering group 
    .append('g') 
    .attr('class', 'g') 
    // do stuff to the entering AND updating group 
    .merge(g) 

    // why do i need to reselect all groups here to append additional elements? 
    // is it because selections are now immutable? 
    var g = d3.select('svg').selectAll('g') 
    g.append('circle') 
     .attr('class', 'circle') 
     .attr('r', function(d) { return d }) 

    // for each of the enter and updated groups, adjust the radius of the child circles 
    g.each(function(datum) { 
    var thisG = d3.select(this) 
    var circle = thisG.selectAll('.circle') 

    circle.transition().attr('r', datum * 2) 
    }) 

    g.exit().remove() 

在此先感謝您的任何幫助,您可以提供。我已經使用了d3 v3很長一段時間,感覺很舒服。但是,我很難理解第4版中的一些不同行爲。

回答

1

我覺得你的代碼可以修改如下(未經測試,所以不確定):

var data = [2, 4, 8] 

var g = d3.select('svg').selectAll('.g').data(data); 

// do stuff to the entering group 
var enterSelection = g.enter(); 
var enterG = enterSelection.append('g') 
.attr('class', 'g'); 

//Append circles only to new elements 
enterG.append('circle') 
    .attr('class', 'circle') 
    .attr('r', function(d) { return d }) 

// for each of the enter and updated groups, adjust the radius of the child circles 
enterG.merge(g) 
    .select('.circle') 
    .transition() 
    .attr('r',function(d){return d*2}); 
g.exit().remove() 

當使用第一.selectAll,僅現有的元素被選中。然後,通過輸入,您正在創建新的元素,並生成新的選擇。當您需要全部更新時,只需將新元素和現有元素合併到一個選擇中即可。

從該選擇,我簡單地選擇所有.circle(單選擇 - 每g一種元素),然後將半徑由於該阻止我製造.each呼叫的結合API更新。我不確定這兩者如何比較,我總是這樣做。

最後,here是一個block顯示模式。

+0

非常感謝!這確實有效。合併後跟選擇是訣竅。我不知道這種模式。再次感謝! – turtle

+0

最受歡迎!我最近也遇到過這個問題 –