I'm trying to change the alignment of the circle so that I can see the text in the middle Just like in this image.
I need help on how to align all the circles towards the circumference of the outer circle. I tried to add the text but it is overlapping with the circle in the center. Is it possible to change the alignment of the circle?
My code is mentioned below.
var root = {
"name": "flare",
"threat_level": "High",
"size": 15000,
"children": [{
"name": "Ghost",
"threat_level": "High",
"size": 1200
},
{
"name": "Wiper",
"threat_level": "Medium",
"size": 1330
},
{
"name": "PowerLiks",
"threat_level": "Medium",
"size": 1333
},
{
"name": "Fareit",
"threat_level": "Medium",
"size": 1300
},
{
"name": "Tribe",
"threat_level": "High",
"size": 1330
},
{
"name": "Oilrig",
"threat_level": "High",
"size": 1330
}
]
}
var svg = d3.select("svg"),
margin = 20,
diameter = +svg.attr("width"),
g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
const color = (type) => type == 'High' ? '#F72047' : (type == 'Medium' ? '#FFFFFF' : '#fff0') //colorScale
var defs = svg.append("defs");
var levels = ['High', 'Medium', 'Low']
levels.forEach((d) => {
//Create a radial Sun-like gradient
defs.append("radialGradient")
.attr("id", "sun-gradient_" + d)
.selectAll("stop")
.data([{
offset: "0%",
color: "#1A1D27"
},
{
offset: "80%",
color: "#1A1D27"
},
{
offset: "100%",
color: d == 'High' ? "#CB1F40" : "#959595"
}
])
.enter().append("stop")
.attr("offset", function (d) {
return d.offset;
})
.attr("stop-color", function (d) {
return d.color;
});
// .interpolate(d3.interpolateHcl);
})
var pack = d3.pack()
.size([diameter - margin, diameter - margin])
.padding(50);
root = d3.hierarchy(root)
.sum(function (d) {
return d.size;
})
.sort(function (a, b) {
return b.value - a.value;
});
var focus = root,
nodes = pack(root).descendants(),
view;
var circle = g.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("class", function (d) {
return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root";
})
.style("fill", (d) => `url(#${'sun-gradient_' + d.data.threat_level})`)
.style('stroke', (d) => color(d.data.threat_level))
.style('stroke-width', 1)
.on("click", function (e, d) {
if (focus !== d) zoom(d);
e.stopPropagation();
});
var text = g.selectAll("text")
.data(nodes)
.enter().append("text")
.attr("class", "label")
.text(function (d) {
return d.parent === root ? d.data.name : d.data.size;
})
.style('font-family', 'Metropolis Bold')
.style('font-size', (d) => d.parent === root ? '12px' : '24px')
.style('text-anchor', 'middle')
.style('fill', (d) => d.parent === root ? '#FFFFFF' : '#F72047')
.style('text-transform', 'uppercase')
var node = g.selectAll("circle,text");
svg
.style("background", color(-1))
.on("click", function () {
zoom(root);
});
zoomTo([root.x, root.y, root.r * 2 + margin]);
function zoom(d) {
var focus0 = focus;
focus = d;
var transition = d3.transition()
.duration(750)
.tween("zoom", function (d) {
var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]);
return function (t) {
zoomTo(i(t));
};
});
transition.selectAll("text")
.filter(function (d) {
return d.parent === focus || this.style.display === "inline";
})
.style("fill-opacity", function (d) {
return d.parent === focus ? 1 : 0;
})
.on("start", function (d) {
if (d.parent === focus) this.style.display = "inline";
})
.on("end", function (d) {
if (d.parent !== focus) this.style.display = "none";
});
}
function zoomTo(v) {
var k = diameter / v[2];
view = v;
node.attr("transform", function (d) {
return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")";
});
circle.attr("r", function (d) {
return d.r * k;
});
}
<svg width="600" height="600"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
