Below example try to put node from top to bottom but it overlapped each other now.
test()
function test() {
var nodes = [
{"Name":"A","Count":10},
{"Name":"B","Count":8},
{"Name":"C","Count":6},
{"Name":"D","Count":5},
{"Name":"E","Count":4},
{"Name":"F","Count":4},
{"Name":"G","Count":2},
{"Name":"H","Count":7},
]
var width = 600
var height = 600
var margin = 100
var color = d3.scaleOrdinal(d3.schemeCategory10)
let extentCount = d3.extent(nodes, d => d.Count)
let maxRadius = 50
let yScale = d3.scaleLinear()
.domain(extentCount)
.range([height - maxRadius, maxRadius])
let rScale = d3.scaleSqrt()
.domain(extentCount)
.range([5, maxRadius])
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin + margin)
.attr("height", height + margin + margin)
.attr("class", "bubble")
.style('border','2px solid red')
.style('background','#ececec')
var g = svg.append("g")
.attr('transform', `translate(${margin},${margin})`)
var simulation = d3.forceSimulation(nodes)
//.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(0).strength(1))
.force("forceX", d3.forceX().strength(.051).x(width/2))
.force("forceY", d3.forceY().strength(.051).y(d => yScale(d.Count)))
.force('collision', d3.forceCollide().radius(d => rScale(d.Count)))
simulation.stop()
var node = g.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) {
return `translate(${d.x},${d.y})`;
});
node.append("circle")
.attr("r", d => rScale(d.Count))
.style("fill", function(d,i) {
return color(i);
});
node.append("text")
.attr("dy", ".2em")
.style("text-anchor", "middle")
.text(function(d) {
return d.Name.substring(0, rScale(d.Count) / 3);
})
.attr("font-family", "sans-serif")
.attr("font-size", function(d){
return rScale(d.Count)/5;
})
.attr("fill", "white");
node.append("text")
.attr("dy", "1.3em")
.style("text-anchor", "middle")
.text(function(d) {
return d.Count;
})
.attr("font-family", "Gill Sans", "Gill Sans MT")
.attr("font-size", function(d){
return d.r/5;
})
.attr("fill", "white");
function ticked() {
node
.attr("cx", function(d){ return d.x; })
.attr("cy", function(d){ return d.y; })
}
simulation.on("tick",ticked)
simulation.nodes(nodes)
//simulation.force("link").links(links)
simulation.alpha(1).restart()
}
<script src="http://d3js.org/d3.v7.min.js" charset="utf-8"></script>
SVG <g>
elements have no cy
or cx
attributes. Inside the tick
function, it should be:
node.attr("transform", function(d) {
return `translate(${d.x},${d.y})`;
});
Here's your code with that change:
test()
function test() {
var nodes = [{
"Name": "A",
"Count": 10
},
{
"Name": "B",
"Count": 8
},
{
"Name": "C",
"Count": 6
},
{
"Name": "D",
"Count": 5
},
{
"Name": "E",
"Count": 4
},
{
"Name": "F",
"Count": 4
},
{
"Name": "G",
"Count": 2
},
{
"Name": "H",
"Count": 7
},
]
var width = 600
var height = 600
var margin = 100
var color = d3.scaleOrdinal(d3.schemeCategory10)
let extentCount = d3.extent(nodes, d => d.Count)
let maxRadius = 50
let yScale = d3.scaleLinear()
.domain(extentCount)
.range([height - maxRadius, maxRadius])
let rScale = d3.scaleSqrt()
.domain(extentCount)
.range([5, maxRadius])
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin + margin)
.attr("height", height + margin + margin)
.attr("class", "bubble")
.style('border', '2px solid red')
.style('background', '#ececec')
var g = svg.append("g")
.attr('transform', `translate(${margin},${margin})`)
var simulation = d3.forceSimulation(nodes)
//.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(0).strength(1))
.force("forceX", d3.forceX().strength(.051).x(width / 2))
.force("forceY", d3.forceY().strength(.051).y(d => yScale(d.Count)))
.force('collision', d3.forceCollide().radius(d => rScale(d.Count)))
simulation.stop()
var node = g.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node");
node.append("circle")
.attr("r", d => rScale(d.Count))
.style("fill", function(d, i) {
return color(i);
});
node.append("text")
.attr("dy", ".2em")
.style("text-anchor", "middle")
.text(function(d) {
return d.Name.substring(0, rScale(d.Count) / 3);
})
.attr("font-family", "sans-serif")
.attr("font-size", function(d) {
return rScale(d.Count) / 5;
})
.attr("fill", "white");
node.append("text")
.attr("dy", "1.3em")
.style("text-anchor", "middle")
.text(function(d) {
return d.Count;
})
.attr("font-family", "Gill Sans", "Gill Sans MT")
.attr("font-size", function(d) {
return d.r / 5;
})
.attr("fill", "white");
function ticked() {
node.attr("transform", function(d) {
return `translate(${d.x},${d.y})`;
});
}
simulation.on("tick", ticked)
simulation.nodes(nodes)
//simulation.force("link").links(links)
simulation.alpha(1).restart()
}
<script src="http://d3js.org/d3.v7.min.js" charset="utf-8"></script>