斯科特的答案是確保初始化只發生一次的一種方法。
不過,我更喜歡處理這個更D3-IC方式:
var svg = d3.select(selector)
.selectAll('svg')
.data([ dataFromTSV ]); // 1 element array -> 1 svg element
// This will be empty if the `svg` element already exists.
var gEnter = svg.enter()
.append('svg')
.append('g');
gEnter.append(...); // Other elements to be appended only once like axis
svg.attr('width', ...)
.attr('height', ...);
// Finally, working with the elements which are surely in the DOM.
var g = svg.select("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.selectAll(...).attr(...);
這種方法在the reusable charts example的source code例證。
我喜歡這種方法,因爲它通過隱藏掉初始化和更新的邏輯使得代碼很聲明和真正的可視化。
我想修改原始例如:http://jsfiddle.net/8Axn7/5/到http://jsfiddle.net/3Ztt8/
無論是圖例和圖表是從svgElem
與數據的一個單一的元素定義爲:
var svgElem = d3.select("#multiLinegraph").selectAll('svg')
.data([cities]);
// ...
var svg = svgElem.select('g');
// ...
var city = svg.selectAll(".city")
.data(
function (d) { return d; },
function (d) { return d.name; } // Object consistency
);
// ...
var legend = svg.selectAll('g.legend')
.data(
function(d) { return d; },
function (d) { return d.name; } // Object consistency
);
此外,靜態屬性僅在元素輸入(或退出)時設置一次,而更新屬性在每次更新時設置(轉換):
gEnter.append("g")
.attr("class", "y multiLineaxis")
.append('text')
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Requests (#)");
svg.select('g.y.multiLineaxis').transition().call(yAxis);
在我看來,代碼完全遵循enter-update-exit循環。
所以它正確地檢查選擇,但我仍然有退出的問題( ) 方法。 var legend = svg.selectAll('g') \t .data(cities) \t .enter(); \t \t legend.exit()。remove();這仍然「返回方法沒有退出」在我的控制檯 – CQM 2013-02-13 21:29:46
這是我的代碼http://jsfiddle.net/ericps/8Axn7/ – CQM 2013-02-13 23:44:19
@CQM如果你可以簡化你的代碼,並顯示錯誤,我認爲這將有助於兩個我們。例如,那裏的大部分內容(複雜數據,圖例,文本等)與問題無關。簡化這個問題,如果你沒有發現問題分享小提琴,我會看看。我上面提到的關於退出的文檔也是一個很好的資源。他們展示了一些可能有用的簡單例子。 – 2013-02-14 02:22:35