问题
I'm working on d3 to represent nodes in circles, when the size of a circle is changed then the circles around them should move away from the one's size got changed from being overlapped.
Consider the red circle above, when its size get changed then the others should move in the green arrow's direction. I tried with force simulation but I'm not able to achieve it and added the code below, I'm not sure what I'm doing wrong, can somebody help please?
https://jsfiddle.net/m6s8dk7o/29/
var w = 900,
h = 500;
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var color = d3.scaleOrdinal(d3.schemeCategory10)
var data = {
name: "root",
children: [{
label: 'RED1',
size: 20,
color: 'red'
},{
label: 'RAD2',
size: 20,
color: '#c99700'
}, {
label: 'BIL3',
size: 20,
color: '#008ce6'
}, {
label: 'EEN4',
size: 10,
color: '#007377'
}, {
label: 'INO5',
size: 40,
color: '#b4975a'
},{
label: 'RAD6',
size: 40,
color: '#c99700'
},{
label: 'BIL7',
size: 30,
color: '#008ce6'
}, {
label: 'INO8',
size: 30,
color: '#b4975a'
},{
label: 'INO9',
size: 40,
color: '#b4975a'
},{
label: 'RAD10',
size: 40,
color: '#c99700'
},{
label: 'BIL11',
size: 30,
color: '#008ce6'
}, {
label: 'INO12',
size: 30,
color: '#b4975a'
} ]
};
var add = function(){
data.children[0].size = 80;
render();
}
var reset = function(){
data.children[0].size = 20;
render();
}
var render = function(){
var simulation = d3.forceSimulation(data.children)
.force("x", d3.forceX(w / 2))
.force("y", d3.forceY(h / 2))
.force("collide", d3.forceCollide(function(d) {
return d.size + 20
}))
.stop();
for (var i = 0; i < 100; ++i) simulation.tick();
console.log(data)
let nodeLevel1 = svg.selectAll('circle')
.data(data.children, (d) => {
// Attaching key for uniqueness
console.log(d)
return d.label;
});
nodeLevel1.exit().remove();
let nodeLevel1Enter = nodeLevel1
.enter()
.append("circle")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(d) {
return d.color;
})
nodeLevel1Enter = nodeLevel1Enter
.merge(nodeLevel1)
let level1CirclesUpdate = nodeLevel1Enter
//.selectAll('circle')
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", function(d) {
return d.size
})
.style("fill", function(d) {
return d.color;
})
}
d3.select('#updatesize').on('click',function(){
add();
})
d3.select('#resetsize').on('click',function(){
reset();
})
render();
<script src="https://d3js.org/d3.v5.min.js"></script>
<a href='javascript:;' id='updatesize'>
Update red resource size
</a> |
<a href='javascript:;' id='resetsize'>
Reset red resource size
</a>
回答1:
For answer, the code is updated here jsfiddle.net/gx8q6ybd/39
来源:https://stackoverflow.com/questions/50712370/move-d3-circles-away-from-center-circle-force-layout