我有一個可重複使用的圖表上的方法,如果它通過d3.select('#id')
選擇或通過d3.selectAll('.class')
選擇傳遞值的數組可傳遞選擇並返回一個值。我目前正在用context._groups[0] instanceof NodeList
審覈已通過的論點,但使用未記錄的屬性會感覺有點脆弱,因爲這可能會在將來的版本中發生變化。是否有更多內置的方式來確定選擇是來自select
還是selectAll
?檢查是否d3.select或d3.selectAll
selection.size()
在這裏沒有幫助,因爲它只告訴我們選擇的結果,而不是它如何被調用。編輯: 這是使用的上下文。我使用的是Mike Bostock的reusable chart pattern,這個實例包含一個獲取/設置甜甜圈標籤的方法。
對我來說,這個API的用法跟在principle of least astonishment之後,因爲它是我期望返回結果的方式。
var donut = APP.rotatingDonut();
// set label for one element
d3.select('#donut1.donut')
.call(donut.label, 'Donut 1')
d3.select('#donut2.donut')
.call(donut.label, 'Donut 2')
// set label for multiple elements
d3.selectAll('.donut.group-1')
.call(donut.label, 'Group 1 Donuts')
// get label for one donut
var donutOneLabel = d3.select('#donut1').call(donut.label)
// donutOnelabel === 'Donut 1'
// get label for multiple donuts
var donutLables = d3.selectAll('.donut').call(donut.label)
// donutLabels === ['Donut 1', 'Donut 2', 'Group 1 Donuts', 'Group 1 Donuts']
和內部方法定義:
App.rotatingDonut = function() {
var label = d3.local();
function donut() {}
donut.label = function(context, value) {
var returnArray;
var isList = context._groups[0] instanceof NodeList;
if (typeof value === 'undefined') {
// getter
returnArray = context.nodes()
.map(function (node) {return label.get(node);});
return isList ? returnArray : returnArray[0];
}
// settter
context.each(function() {label.set(this, value);});
// allows method chaining
return donut;
};
return donut
}
非常好的和有趣的問題。我寫了一個答案,這不是你所期望的答案。如果有人證明我錯了,我會很樂意刪除它。 –
只是一個好奇心:*爲什麼*你這樣做?爲什麼不簡單地向函數傳遞第二個參數,告知方法的類型?你看,這是一個很有希望成爲[XY問題]的候選人(https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) –
我已更新我的文章以提供全文上下文。這裏的目標是找到實現這種getter/setter方法的「最類似d3」的方式。 「最好」的答案將是d3爲其中一種方法做同樣的事情的一個例子。 –