与您的代码的问题是,布局战略正在重新评估每次图表呈现。通常情况下,当第一次渲染图表时,渲染时间为〜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