To render label on nodes, i have tried various method like this:
var labels = node.append("text")
.text(function (d) { return d.label; })
.attr('x', 6)
.attr('y', 3);
node.append("title")
.text(function (d) { return d.label; });
Or something like this:
node.append("text")
// .attr("text-anchor", "middle")
// .attr("alignment-baseline", "middle")
.text(d => d.label)
.attr('x', 6)
.attr('y', 3);
Here is my complete code:
<svg id="chart">
</svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
let drag = simulation => {
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart()
event.subject.fx = event.subject.x
event.subject.fy = event.subject.y
}
function dragged(event) {
event.subject.fx = event.x
event.subject.fy = event.y
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0)
event.subject.fx = null;
event.subject.fy = null;
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
}
let height = 600
let width = 600
let data = {
"nodes": [{
"id": "Myriel",
"label": "Myriel name"
},
{
"id": "Napoleon",
"label": "Napoleon name"
}
],
"links": [{
"source": "Myriel",
"target": "Napoleon",
"label": "hit me baby one more time"
},
{
"source": "Napoleon",
"target": "Myriel",
"label": "meaw"
}
]
}
const links = data.links.map(d => Object.create(d))
const nodes = data.nodes.map(d => Object.create(d))
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
const svg = d3.select("#chart")
.attr("viewBox", [0, 0, width, height])
// Define the arrowhead marker
svg.append("defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
// Add the links with arrowheads
const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("line")
.attr("stroke-width", 1)
.attr("marker-end", "url(#end)"); // Add the marker-end attribute to link
link.append("text")
.attr("text-anchor", "middle")
.attr("alignment-baseline", "middle")
.text(d => d.label);
const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("r", 5)
.attr("fill", () => "#" + Math.floor(Math.random() * 16777215).toString(16))
.call(drag(simulation))
// node.append("text")
// // .attr("text-anchor", "middle")
// // .attr("alignment-baseline", "middle")
// .text(d => d.label)
// .attr('x', 6)
// .attr('y', 3);
var labels = node.append("text")
.text(function (d) { return d.label; })
.attr('x', 6)
.attr('y', 3);
node.append("title")
.text(function (d) { return d.label; });
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y)
node
.attr("cx", d => d.x)
.attr("cy", d => d.y)
})
</script>
I wanted to create a graph like this:

How can I do so?
Right now, it looks something like this:

Although it is available under dom, but it's not visible. I have tried setting their position for quite a while.
As mentioned in the comments, having a
textelement as a child of acircleis invalid SVG. Instead, change your node to be agand then place both the circle and text inside of it.Here's a quick change to your code: