Reputation: 555
I've been practicing using D3.js by making a simple scatter plot with some dummy data. Unfortunately after spending an hour of googling and looking at examples, I still can't figure out why my labels are not rendering. Could someone point me in the right direction on what I'm doing wrong?
I'm assuming the text is not rendering because when I put in dummy numbers for the X and Y attributes, I still don't get the labels to render on the page.
const points = [
[1,2],
[2,4],
[3,6],
[4,8],
[5,10]
]
const w = 500
const h = 500
const maxX = d3.max(points, (d) => d[0]);
const maxY = d3.max(points, (d) => d[1]);
console.log(maxX, maxY);
const scaleX = d3.scaleLinear()
.domain([0, maxX])
.range([0, w]);
const scaleY = d3.scaleLinear()
.domain([0, maxY])
.range([0,h]);
const svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h)
;
svg.selectAll("circle")
.data(points)
.enter()
.append('circle')
.attr('cx',(d) => scaleX(d[0]))
.attr('cy',(d) =>h - scaleY(d[1]))
.attr('r', 5)
.attr('fill', 'black')
// adding axae
const xAxis = d3.axisBottom(scaleX);
const yAxis = d3.axisLeft(scaleY);
svg.append("g")
.attr("transform", "translate(0," + (h -20) + ")")
.call(xAxis);
svg.append("g")
.attr("transform", "translate(" + 20 + ", 0)")
.call(yAxis);
// adding labels
svg.selectAll("text")
.data(points)
.enter()
.append("text")
.text((d) => (d[0] + "," + d[1]))
.attr("x", (d) => scaleX(d[0] + 10))
.attr("y", (d) => scaleY(d[1]))
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<script src='app.js'></script>
</body>
</html>
Upvotes: 0
Views: 61
Reputation: 8301
The code was almost correct, whenever you want to insert(enter) some nodes you must check if there is no selection corresponding to that.
As you have already rendered the axes, so there are already text nodes in my chart but i wanted to create an empty selection. Always use a unique indentifier for that
Replace // adding labels
svg.selectAll("text")
with // adding labels
svg.selectAll(".mylables")
Change x and y coordinate as below, you can tweek accordingly.
.attr("x", (d) => scaleX(d[0]) + 10)
.attr("y", (d) => h - scaleY(d[1]))
const points = [
[1, 2],
[2, 4],
[3, 6],
[4, 8],
[5, 10]
]
const w = 500
const h = 500
const maxX = d3.max(points, (d) => d[0]);
const maxY = d3.max(points, (d) => d[1]);
console.log(maxX, maxY);
const scaleX = d3.scaleLinear()
.domain([0, maxX])
.range([0, w]);
const scaleY = d3.scaleLinear()
.domain([0, maxY])
.range([0, h]);
const svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
svg.selectAll("circle")
.data(points)
.enter()
.append('circle')
.attr('cx', (d) => scaleX(d[0]))
.attr('cy', (d) => h - scaleY(d[1]))
.attr('r', 5)
.attr('fill', 'black')
// adding axae
const xAxis = d3.axisBottom(scaleX);
const yAxis = d3.axisLeft(scaleY);
svg.append("g")
.attr("transform", "translate(0," + (h - 20) + ")")
.call(xAxis);
svg.append("g")
.attr("transform", "translate(" + 20 + ", 0)")
.call(yAxis);
// adding labels
svg.selectAll(".mylabels")
.data(points)
.enter()
.append("text")
.style('class', 'mylables')
.text((d) => {
debugger;
return (d[0] + "," + d[1])
})
.attr("x", (d) => scaleX(d[0]) + 10)
.attr("y", (d) => h - scaleY(d[1]))
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<script src='app.js'></script>
</body>
</html>
Upvotes: 1