David Reke
David Reke

Reputation: 555

Why are labels/text not rendering on this d3.js scatter plot?

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

Answers (1)

Jasdeep Singh
Jasdeep Singh

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

Related Questions