2013-01-22 75 views
3

我遇到D3 joins問題。我在泡泡圖上創建了一些圈子。當用戶點擊「顯示爲地圖」按鈕時,我想將圓形轉換爲地圖,然後爲每個地圖添加一個標籤。D3.js:如何在數據已綁定時追加元素?

當前點擊處理程序移動圓圈OK,然後給我一個JavaScript錯誤,而不是添加標籤:Uncaught TypeError: Object [object SVGCircleElement]... has no method 'append'。我知道這是因爲我的連接語法不正確,但我該如何解決它?

我可以找到添加新D3元素的所有示例,用於綁定新數據的情況 - 而不是當已有數據已綁定數據的情況下。

這是我創建的圈子代碼:

var circle = g.selectAll('.city') 
    .data(data).enter() 
    .append('circle') 
    .attr('class', 'city') 
    .attr('r', rfunc).attr("cy", 0) 
    .attr("cx", function(d, i) { 
     return rdist(d['dist']); 
    }).attr("transform", function(d, i) { 
     return "rotate(" + d.radial_pos + " 0 0)"; 
    }); 

這是我的點擊處理程序:

d3.select("#layout_geo").on("click", function() { 
    // Move the circles - this works OK. 
    var circles = d3.selectAll(".city") 
    .transition() 
    .duration(1300) 
    .attr('cx', function(d) { 
     return merc([d['lon'], d['lat']])[0] - 350; 
    }).attr('cy', function(d) { 
     return merc([d['lon'], d['lat']])[1] - 280; 
    }); 
    // How to add text to each circle? 
    circles.append('text') 
     .attr('class', 'background') 
     .text(function(d) { 
     console.log(d.name + ', ' + d.city); 
      return d.name + ', ' + d.city; 
     }) 
     .attr('cx', function() { 
     return ???; 
     }).attr('cy', function() { 
     return ???; 
     }); 
    }); 

回答

3

這裏的問題是,circles是不正常的選擇,但一個transition。他們有一個方便的remove()函數來允許刪除項目,但不添加更多元素的append

另一個問題是,附加元素<text>內部一個<circle>屬性不正確的SVG。在這種情況下,您需要將<text><circle>放入g元素like this內。在代碼中的相應變化將是:

d3.select("#layout_geo").on("click", function() { 
    // Assign the seleciton to circles 
    var circleG = d3.selectAll(".city"); 

    circleG.transition() 
     .duration(1300) 
     .attr('transform', 'translate(-100, -50)'); // Ignoring the rotation. 

    // And append text to the selection 
    circleG.append('text') 
     .attr('class', 'background') 
     .attr('dx', '1em') 
     .text(function(d) { 
      console.log(d.name + ', ' + d.city); 
      return d.name + ', ' + d.city; 
     }); 
    }); 

注意旋轉失去了<circle>元素同時改變transform屬性。它可以通過保存using two nested g elements with rotation on the outer one.

+0

謝謝。不幸的是,代碼不再產生錯誤,但它也不會將任何內容附加到DOM。這很奇怪,因爲它正在寫入控制檯,但這些元素並沒有出現在DOM中。 – Richard

+0

啊,我明白了。對不起這是我的錯。實際上,添加一個''元素_inide_一個''元素將不起作用,我認爲不符合SVG標準。在這種情況下,您需要將''和''放入'g'元素[像這樣](http://jsfiddle.net/VbUza/)。如果那是你正在尋找的東西,我會更新答案。請注意,''元素上的'rotation'丟失了,但是可以通過使用[兩個嵌套的g元素在外部元素上旋轉]來實現(http://www.w3.org/TR/SVG/coords。 HTML#TransformAttribute)。 –

+0

這是一個很好的答案,謝謝!真的幫助我瞭解了小組如何在SVG中工作。 – Richard