在d3的打包布局中是否有办法手动设置子节点的半径,其大小相对于父半径,然后让其他子节点根据剩余空间设置其半径并使用现有的“儿童人数的大小“?
我想做的是: 1.为每个节点添加一个节点到children数组,其名称与父节点相同 2.将此额外子项的半径设置为具有足够大的半径以包含文本并确保其邻居不重叠 3.在此额外节点上将fill和stroke设置为none 4.在此额外节点上将css的单击交互设置为none 5.仅使用这些额外节点来显示“他们的”名称(也就是他们的父母的名字)
结果将是一个包装圆圈,其标签有一个特别指定的空间。如果没有手动设置额外子节点的半径,这不起作用,因为它的大小是根据子节点数自动确定的。 (添加未填充/未缩放的子节点以进行补偿是非常低效的。第一次黑客攻击的第二次攻击是不值得的,我不认为)
答案 0 :(得分:1)
请检查这是否对您有所帮助。红色背景与“额外”课程的圈子是带有父母姓名的额外圈子。
var root = {
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
},
{
"name": "graph",
"children": [
{"name": "BetweennessCentrality", "size": 3534},
{"name": "LinkDistance", "size": 5731},
{"name": "MaxFlowMinCut", "size": 7840},
{"name": "ShortestPaths", "size": 5914},
{"name": "SpanningTree", "size": 3416}
]
},
{
"name": "optimization",
"children": [
{"name": "AspectRatioBanker", "size": 7074}
]
}
]
},
{
"name": "animate",
"children": [
{"name": "Easing", "size": 17010},
{"name": "FunctionSequence", "size": 5842},
{
"name": "interpolate",
"children": [
{"name": "ArrayInterpolator", "size": 1983},
{"name": "ColorInterpolator", "size": 2047},
{"name": "DateInterpolator", "size": 1375},
{"name": "Interpolator", "size": 8746},
{"name": "MatrixInterpolator", "size": 2202},
{"name": "NumberInterpolator", "size": 1382},
{"name": "ObjectInterpolator", "size": 1629},
{"name": "PointInterpolator", "size": 1675},
{"name": "RectangleInterpolator", "size": 2042}
]
},
{"name": "ISchedulable", "size": 1041},
{"name": "Parallel", "size": 5176},
{"name": "Pause", "size": 449},
{"name": "Scheduler", "size": 5593},
{"name": "Sequence", "size": 5534},
{"name": "Transition", "size": 9201},
{"name": "Transitioner", "size": 19975},
{"name": "TransitionEvent", "size": 1116},
{"name": "Tween", "size": 6006}
]
},
]
};
var addExtraNode = function(item, percentSize){
var percentSizeOfNode = percentSize || 60; //if not given it will occupy 60 percent of the space
if(!item.children){
return;
}
var totalChildSize = 0;
item.children.forEach(function(citm, index){
totalChildSize = totalChildSize + citm.size;
})
var nodeSize = (percentSizeOfNode / 50) * totalChildSize;
var name = 'NAME: '+item.name;
item.children.push({
'name': name,
'size': nodeSize,
'isextra':true
})
item.children.forEach(function(citm, index){
if(citm.children){
addExtraNode(citm, percentSize);
}
})
};
addExtraNode(root, 55);
var diameter = 500,
format = d3.format(",d");
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) { return d.size; });
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(2,2)");
var node = svg.datum(root).selectAll(".node")
.data(pack.nodes)
.enter().append("g")
.attr("class", function(d) {
if(d.isextra){
return 'extra';
}
return d.children ? "node" : "leaf node"; })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });
node.append("circle")
.attr("r", function(d) { return d.r; });
node.filter(function(d) { return !d.children; }).append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.name.substring(0, d.r / 3); });
circle {
fill: rgb(31, 119, 180);
fill-opacity: .25;
stroke: rgb(31, 119, 180);
stroke-width: 1px;
}
.leaf circle {
fill: #ff7f0e;
fill-opacity: 1;
}
text {
font: 10px sans-serif;
}
.extra circle{
fill:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
答案 1 :(得分:0)
这个答案是我现在使用的解决方案,并以Ganesh提供的解决方案为基础。
Ganesh解决方案摘要:
我使用Ganesh解决方案的剩余问题:
解决方案和主要发现:
我的价值函数的最终版本基于Ganesh的解决方案,如下所示:
var pack = d3.layout.pack()
.value(function(d){
if(d.isExtra){ //the property added to injected label nodes
d.value = d.parent.treeSize*100 //treeSize = size of subTree
return d.value;
}
else{
d.value = d.treeSize*100;
return d.value;
}
})
.size([width, height -100 ])
重要的是要注意,虽然我引入的新节点的值等于它的父节点乘以100,但这并不意味着它占用了圆的空间的100倍。这是因为父母的价值最终是儿童价值的总和,这意味着任何有孩子的节点都会看到总价值的增加。将标签节点的treeSize乘以显着更高的数字仅提供相应圆周大小的对数增加,同时在叶节点大小(100)和其余圆圈之间引入越来越大的间隙。