1 回答

TA貢獻1827條經驗 獲得超9個贊
我不確定我是否正確理解了您的問題。但我會嘗試在這里提供一個答案。
簡短的回答是:不,您正在測試的假設不正確,因為它假設.append()
修改了現有選擇。無論您附加到什么,area
仍然是 a 的選擇。g
area
由于您對附加SVG
.
D3 選擇方法通常是可鏈接的,因為它們經常用于返回選擇。通過返回一個選擇,可以對返回的值使用另一種選擇方法,從而允許鏈接。
但是選擇方法返回的選擇并不總是相同元素的選擇——也就是說,它可能是不同的選擇。
如果使用.style()
, .attr()
, .each()
, .call()
, .on()
, .raise()
,.html()
等.text()
方法設置屬性、樣式等,則返回值是原始選擇本身。通??捎糜诜祷禺斍斑x擇的方法是那些修改有關選擇的內容的方法。如果不設置值,其中許多方法可用于返回值而不是 selection。
如果使用 .append()
, .enter()
, .exit()
, .merge()
, .filter()
, .select()
,.selectAll()
等方法,則返回值是不同的選擇。
使用鏈定義變量時,賦值為鏈中最后一項的返回值。
最后,不能更改 D3 選擇:
選擇是不可變的。所有影響選擇哪些元素(或其順序)的選擇方法都會返回一個新選擇,而不是修改當前選擇。(來源)
一旦我們將選擇定義為由某些元素組成,我們就無法更改它。我們只能用不同的選擇重新定義一個變量。
D3v3 在這方面略有不同,但不是為了您的問題
現在,看看你對這條線的初步評估:
var svg = d3.select('body').append('svg')
還有你的解釋:
我將選擇 [the] 'body' 并附加 [a] 'svg'。并將其存儲為一個名為
svg
.
您的解釋是正確的,讓我們打破鏈接并使用兩個變量來實現相同的目的,以查看您正在使用的兩個選擇:
var body = d3.select("body") // returns a selection of the body
var svg = body.append("svg") // returns a selection of a newly created svg
body仍然是身體的選擇 - 附加的東西body不會改變這body是身體的選擇。然后我們svg用來存儲新的選擇:一個新附加的 SVG 的選擇。將任何項目附加到svg以后不會更改svg為svg.
應用上述所有內容,我們可以看到一種方法,例如:
var area = svg.append('g') // returns a selection of a new g element, stored as `area`
area.append('path') // returns a selection of a new created path element, but you don't store this reference, nothing is done with it.
area.attr('d', somePathData) // attempting to modify a g element instead of a path.
這不會像您期望的那樣工作,area仍然是一個g元素的選擇:您將它定義為這樣并且沒有重新定義area為一些不同的選擇。.append()創建一個新選擇 - 除了創建路徑之外您不使用的選擇。
如您所述,如果我們將path選擇存儲在一個新變量中,代碼將按預期工作:
var area = svg.append('g') // returns a selection of a new g element
var path = area.append('path') // returns a selection of a new path element
path.attr('d', somePathData) // modifies a path element
最后,如果我們不再需要修改路徑,我們就不需要使用變量來存儲它,我們可以這樣做:
var area = svg.append('g') // returns a selection of a new g element
area.append('path') // returns a selection of a new path element
.attr('d', somePathData) // modifies the selection of the path element
添加回答
舉報