[英]Circles overlapping after transition with D3.pack
I have a JSON file which I reorganize using the d3.nest() function, which then is used to transition to a different state. 我有一个JSON文件,可以使用d3.nest()函数进行重组,然后将其用于转换为其他状态。
However, when I do the transition, the circles in the top hierarchies overlap any which way, and their movement isn't very elegant (they appear and disappear our of nowehere). 但是,当我执行过渡时,顶层层次结构中的圆圈会以任何方式重叠,并且它们的运动也不是很优雅(它们出现并消失了我们现在的位置)。 I managed to keep the top nodes on top by using a moveToFront() function, as was recommended on another question. 我设法通过使用moveToFront()函数将顶部节点保持在顶部,这是另一个问题的建议。 This works great for the top nodes, but it doesn't work for every layer. 这对于顶部节点非常有用,但并不是对每个图层都有效。 I made the circles semi-transparent so it's easier to see what's going on. 我将圆圈设为半透明,因此更容易了解发生了什么。
I'm also trying to add labels but it completely messes up, no matter what I seem to do. 我也试图添加标签,但是无论我做什么,它都完全混乱了。 I'm thinking maybe because the order is messed up? 我在想也许是因为订单搞砸了?
Here is my code for the function in question. 这是我所讨论功能的代码。 I also put three JSON file samples representing the three hierarchies I'm using. 我还放置了三个JSON文件样本,分别代表我正在使用的三个层次结构。
If anybody can help, it would be greatly appreciated! 如果有人可以帮助,将不胜感激!
function update(i, duration) {
var delay = 0;
var root = changehierarchy(childdata, i);
var focus = root;
var nodes = pack.nodes(root);
var v = [root.x, root.y, root.r * 2 + margin];
var k = diameter / v[2]; view = v;
var vis = svg.selectAll('circle')
.data(nodes, function(d) { return d.name; });
//.sort(function (a, b) { return a.depth < b.depth ? -1 : 1; })
// update
vis.data(nodes)
.transition()
.each("start", function(d){ d3.select(this).moveToFront(); })
.duration(duration)
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.attr('transform', function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; })
.style("fill", function(d) { return d.children ? color(d.depth) : d.color; })
.style("opacity", function(d) { return d.children ? 0.4 : 1; } )
.attr('r', function(d) { return d.r; });
//enter
vis.data(nodes)
.enter()
.append('circle')
.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; })
.attr("r", function(d) { return d.r * k; })
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.style("fill", function(d) { return d.children ? color(d.depth) : d.color; })
.style("opacity", function(d) { return d.children ? 0.4 : 1; } );
//exit
vis.exit()
.transition()
.duration(duration)
.style('opacity', 0)
.remove();
var node = svg.selectAll("circle,text");
d3.select("body")
.style("background", color(-1));
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
d3.selection.prototype.appendText = function() {
var text = svg.selectAll("text")
.data(nodes, function(d) { return d.name; });
text.enter().append("text")
.attr("class", "label")
.style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; })
.style("display", function(d) { return d.parent === root ? "inline" : "none"; })
.text(function(d) { return d.name; });
};
};
JSON Files : First hierarchy JSON文件:第一层级
{
"name":"POPULATION (n=8)",
"children":[
{
"name":1,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":50
},
{
"name":2,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":49
},
{
"name":3,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":48
},
{
"name":4,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":47
},
{
"name":5,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":46
},
{
"name":6,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":45
},
{
"name":7,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":44
},
{
"name":8,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":43
}
]
}
Second hierarchy 第二等级
{
"name":"POPULATION (n=8)",
"children":[
{
"name":"Event A is true",
"children":[
{
"name":1,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":50
},
{
"name":2,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":49
},
{
"name":3,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":48
},
{
"name":4,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":47
}
]
},
{
"name":"Event A is false",
"children":[
{
"name":5,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":46
},
{
"name":6,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":45
},
{
"name":7,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":44
},
{
"name":8,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":43
}
]
}
]
}
Third hierarchy 第三等级
{
"name":"POPULATION (n=8)",
"children":[
{
"name":"Event B is true",
"children":[
{
"name":"Event A is true",
"children":[
{
"name":1,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":50
},
{
"name":2,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is true",
"color":"#944dff",
"size":49
}
]
},
{
"name":"Event A is false",
"children":[
{
"name":5,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":46
},
{
"name":6,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is true",
"color":"#FFFFFF",
"size":45
}
]
}
]
},
{
"name":"Event B is false",
"children":[
{
"name":"Event A is true",
"children":[
{
"name":3,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":48
},
{
"name":4,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is true",
"eventB":"Event B is false",
"color":"#944dff",
"size":47
}
]
},
{
"name":"Event A is false",
"children":[
{
"name":7,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":44
},
{
"name":8,
"name1":"Total",
"name2":"POPULATION (n=8)",
"eventA":"Event A is false",
"eventB":"Event B is false",
"color":"#FFFFFF",
"size":43
}
]
}
]
}
]
}
The problem is, you're incorectly using vis.data(...)
by calling it 3 times for a single update. 问题是,您不正确地使用vis.data(...)
并对其进行了3次调用vis.data(...)
一次更新)。 Only the first data()
call is necessary, and it's also one place where you, correctly provided the 2nd argument, ie function(d) { return d.name; }
只有第一个data()
调用是必需的,它也是您正确提供第二个参数的地方,即function(d) { return d.name; }
function(d) { return d.name; }
. function(d) { return d.name; }
。
(I've never tested this, but there's a chance that things would work ok if you added added that 2nd argument to the two other data()
calls, but that would be inappropriate as well) (我从未测试过此方法,但是如果您在其他两个data()
调用中添加了第二个参数,则有可能一切正常,但这也是不合适的)
I replaced the two calls to data()
with the appropriate thing. 我用适当的东西替换了对data()
的两次调用。 I also swapped the positions (ie the sequential order) of the enter and update blocks. 我还交换了enter和update块的位置(即顺序)。
There's a chance the entering transition still wouldn't be quite right after this, but start from this: 在此之后,进入过渡的机会仍然不太正确,但是从这里开始:
var vis = svg.selectAll('circle')
.data(nodes, function(d) { return d.name; });
// enter (it's not necessary to assign to 'var visEnter', but it's
// available if you need to work more with that selection)
var visEnter = vis.enter()
.append('circle')
.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; })
.attr("r", function(d) { return d.r * k; })
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.style("fill", function(d) { return d.children ? color(d.depth) : d.color; })
.style("opacity", function(d) { return d.children ? 0.4 : 1; } );
// update
vis
.transition()
.each("start", function(d){ d3.select(this).moveToFront(); })
.duration(duration)
.attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
.attr('transform', function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; })
.style("fill", function(d) { return d.children ? color(d.depth) : d.color; })
.style("opacity", function(d) { return d.children ? 0.4 : 1; } )
.attr('r', function(d) { return d.r; });
//exit
vis.exit()
.transition()
.duration(duration)
.style('opacity', 0)
.remove();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.