an example我们可以点击一个圆圈查看内圈。{ 还有不同的力布局示例。
是否可以使用力布局,并且它的每个节点将/可以是具有内力布局的圆? 因此,它将作为无限缩放(带有额外的数据加载)用于这些圆圈。
欢迎任何想法/例子。
答案 0 :(得分:1)
我会像这样解决这个问题:构建一个强制导向的布局,从其中一个教程开始(也许是this one,因为它构建了一些使用圆形打包进行初始化的东西)。添加D3的缩放行为。
var force = d3.layout.force()
// force layout settings
var zoom = d3.behavior.zoom()
// etc.
到目前为止,这么好。除了力布局喜欢在[width/2, height/2]
附近闲逛,但如果你以[0, 0]
为中心,它会使缩放变得更容易。与geometric zooming战斗一段时间直到你意识到这个问题确实需要semantic zooming。实现语义缩放。去喝杯咖啡。
找出圆圈大小与缩放级别之间的关系,让您知道何时需要揭开下一个级别。像这样:
// expand when this percent of the screen is covered
var coverageThreshold = 0.6;
// the circles should be scaled to this size
var maxRadius = 20;
// the size of the visualization
var width = 960;
// which means this is the magic scale factor
var scaleThreshold = maxRadius / (coverageThreshold * width)
// note: the above is probably wrong
现在,实现空间数据过滤器。当你缩小时,你基本上想要隐藏任何缩小视图的数据点,这样你就不会浪费gpu时间来计算它们的表示。此外,找出一种算法,确定用户放大的节点。这很可能使用Voronoi tessalation。学习比你想象的更多几何方法。
我们需要解决的另一个数学问题。我们将让子节点取代父节点,因此我们需要根据父节点的总大小来扩展它们的大小。这将是烦人的,需要一些调整才能正确,除非你知道正确的算法......我没有。
// size of the parent node
var parentRadius = someNumberPossiblyCalculated;
// area of the parent node
var parentArea = 2 * Math.PI * parentRadius;
// percent of the the parent's area that will be covered by children
// (here be dragons)
var childrenCoverageRatio = 0.8;
// total area covered by children
var childrenArea = parentArea * childrenCoverageArea;
// the total of the radiuses of the children
var childTotal = parent.children
.map(radiusFn)
.reduce(function(a, b) { return a + b; });
// the child radius function
// use this to generate the child elements with d3
// (optimize that divide in production!)
var childRadius = function(d) {
return maxRadius * radiusFn(d) / childTotal;
};
// note: the above is probably wrong
好的,现在我们已准备好制作魔法酱。在zoom
处理程序中,针对您的参考点检查d3.event.scale
。如果用户放大了它,请快速执行以下步骤:
force.tick()
几次,让孩子们分开一点好的,现在我们有一个很小的力量布局和缩放。当您放大时,您将达到某个阈值,希望可视化代码自动计算。当你这样做时,你放大的节点会“爆炸”到它的所有组成节点。
现在弄清楚如何构建代码,以便您可以“重置”事物,以允许您继续放大并让它再次发生。这可能是递归的,但将比例缩小几个数量级并同时通过反向因子扩展SVG元素可能更清晰。
现在 缩小 。首先,你需要一个明显的缩放阈值用于反向过程,控制中的滞后效应,如果有人骑着鼠标滚轮,它将有助于防止跳跃式可视化。你放大并扩展,然后你必须再缩小一点再再缩合。
好的,当你达到缩小阈值时,你只需删除子元素并将父元素添加回子元素位置的质心。
var parent.x = d3.mean(parent.children, function(d) { return d.x; });
var parent.y = d3.mean(parent.children, function(d) { return d.y; });
此外,当你缩小时,开始显示你在放大时隐藏的那些节点。
正如@Lars所说,这可能需要一段时间。