與您的代碼的問題是,佈局戰略正在重新評估每次圖表呈現。通常情況下,當第一次渲染圖表時,渲染時間爲〜100ms並不成問題,但如果您需要平滑的平移/縮放,則會成爲問題。
我想出的解決方案是'緩存'佈局的結果,以便在圖表放大時不重新評估。但是,縮放操作完成後,將重新評估佈局以消除衝突。
首先,縮放事件的處理以開啓緩存行爲/關:
var returnCachedLayout = false;
var zoomBeh = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([0, 500])
.on("zoomstart", function() {
returnCachedLayout = true;
zoom()
})
.on("zoom", zoom)
.on("zoomend", function() {
returnCachedLayout = false;
zoom()
})
則該策略適用於使用緩存:
var strategyCache = function (strategy) {
var cachedLayout;
var cache = function(layout) {
if (!returnCachedLayout) {
cachedLayout = strategy(layout);
// determine the offset applied by the layout
for (var i = 0; i< layout.length; i++) {
cachedLayout[i].dx = layout[i].x - cachedLayout[i].x;
cachedLayout[i].dy = layout[i].y - cachedLayout[i].y;
}
} else {
// update the location of each label, including the offset
for (var i = 0; i< layout.length; i++) {
cachedLayout[i].x = layout[i].x - cachedLayout[i].dx;
cachedLayout[i].y = layout[i].y - cachedLayout[i].dy;
}
}
return cachedLayout;
};
return cache;
};
// construct a strategy that uses the "greedy" algorithm for layout, wrapped
// by a strategy that removes overlapping rectangles.
var strategy = strategyCache(fc.layout.strategy.removeOverlaps(fc.layout.strategy.greedy()));
這是一個有點棘手因爲您不能僅僅從緩存中重新渲染標籤,因爲縮放行爲會導致這些點移動。這就是偏移量也被存儲起來的原因,因此它可以被重新應用到新位置的標籤上。
無論如何,這裏有一個完整的例子:
https://jsfiddle.net/qrpr0wre/
我會尋找讓這個「第一類」 d3fc標籤佈局的即將特點。
你能提供一個更完整和可運行的例子來展示你的問題嗎? – ColinE
Hi @ColinE - 我無法發佈實際的代碼,因爲它嵌入到一個更大的Sencha ExtJS UI系統中,但我試圖展示代碼的簡化版本以顯示我如何使用d3fs。感謝您的幫助! –
我認爲這需要一些工作來解決 - 佈局計算大約需要100ms,這總是會讓你的變焦變得「跳躍」。我在這裏提出了一個問題(https://github.com/d3fc/d3fc-label-layout/issues/24),並會嘗試找到一個體面的解決方案。 – ColinE