我正在尝试使用可缩放的旭日形图来可视化一个大型数据库。我的 json 的较低层级有太多子级,因此文本标签在外边缘非常混乱且不可读。
我可以根据绝对深度级别打开或关闭标签,但这意味着这些标签永远不会显示,即使我放大。
我的问题是,如何计算特定缩放级别的“相对”深度,然后根据它显示标签?
据我所知, d.depth 仅表示绝对水平。
我正在尝试使用可缩放的旭日形图来可视化一个大型数据库。我的 json 的较低层级有太多子级,因此文本标签在外边缘非常混乱且不可读。
我可以根据绝对深度级别打开或关闭标签,但这意味着这些标签永远不会显示,即使我放大。
我的问题是,如何计算特定缩放级别的“相对”深度,然后根据它显示标签?
据我所知, d.depth 仅表示绝对水平。
我假设您正在使用 Jason Davies 的示例。
他脚本中的相关代码是
function click(d) {
path.transition()
.duration(duration)
.attrTween("d", arcTween(d));
// Somewhat of a hack as we rely on arcTween updating the scales.
text.style("visibility", function(e) {
return isParentOf(d, e) ? null : d3.select(this).style("visibility");
})
.transition()
.duration(duration)
.attrTween("text-anchor", function(d) {
return function() {
return x(d.x + d.dx / 2) > Math.PI ? "end" : "start";
};
})
.attrTween("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1;
return function() {
var angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate("
+ (y(d.y) + padding) + ")rotate("
+ (angle > 90 ? -180 : 0) + ")";
};
})
.style("fill-opacity", function(e) {
return isParentOf(d, e) ? 1 : 1e-6;
})
.each("end", function(e) {
d3.select(this).style("visibility",
isParentOf(d, e) ? null : "hidden");
});
}
请注意其中一些函数是如何引用两个不同的数据对象的,d
而e
. 这是因为,除非它被内部函数屏蔽,否则d
点击函数内部是被点击元素的数据对象——成为圆心的对象。
如果他为数据对象 ( ) 赋予内部函数一个不同的名称function(e){}
,则该数据对象与正在更改属性的单个元素关联。因此,他能够调用比较两个数据对象的函数,以确定给定元素是否应该在该缩放级别隐藏。
你想做同样的事情,除了如果它是中心轮的父级,你不仅要隐藏文本,如果它的后代太深,你也会隐藏它。所以你想要这样的东西:
if (e.depth > d.depth + 3) return "hidden";
添加代码的位置取决于样式选择——Jason Davies 实际上在三个点更改文本不透明度或可见性:可见性在转换之前和之后设置(在“结束”事件期间),不透明度在两者之间淡化。您希望您的标签在单击时弹出和弹出,还是希望它们淡入和淡出?
我还不能发表评论,如果你在他身边寻找戴维斯的代码并找到对这个答案没有帮助的缩小版本,这里有一些你可能会发现有用的东西 - 完整版本移到这里:https:/ /code.google.com/p/testprogramming/source/browse/trunk/javascript/svg/d3/test/wheel.js?r=394&spec=svn394
上述答案中缺少所有重要的功能 isParentOf ,必须从完整版本中收集。
-- 附加信息:如果您想根据“缩放”级别显示标签,同样重要的是要注意旭日形不使用 .zoom() 函数,您必须手动查找路径。在我的情况下,我想隐藏顶部缩放级别的所有标签,但如果选择了任何其他级别,则显示它们。为此,我在开头隐藏文本,然后每次单击我使用以下测试
var text = g.append("text")
.attr("class","mylabel")
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return y(d.y); })
.attr("dx", "4") // left - margin for text
.attr("dy", ".25em") // vertical-align of text in cell
.text(function(d) { return (d.name == 'root') ? ('') : d.name; })
.attr("font-size", function(d) { return d.ci_type === 'type' ? 12 : 10}) //font-size of text
//.attr("visibility",function(d) { return d.dx < 0.009? "hidden" : "visible"}) // hide text of labels of partitions less than 2%
.attr("visibility", "hidden") // hide labels at root level - starting level
function click(d) {
// fade out all text elements
text.transition().attr("opacity", 0);
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
.attr("x", function(d) { return y(d.y); })
}
});
// if the vis is at the 'root' level hide text, otherwise show <! here is the test!
var str = d.name;
var patt = 'root';
var atRoot = (str === patt) ? true : false ;
//console.log(atRoot);
//console.log( d.name ) ;
text.attr("visibility",function(d) { return atRoot ? "hidden" : "visible"})
// end of click
}