D3 Scatterplot tooltip assistance please

Hi there, if it is at all possible for anyone to suggest how I can modify code to display the tooltip correctly, the dataset is being accessed by code but when I hover over the plot the consoles the position in the array. also i think the tooltip position is not working either. Below is the code. https://codepen.io/RDL123/pen/bGXMvNJ

Blockquote

Blockquote

Blockquote

do we still post code in blockquotes?

// Load the data using XMLHttpRequest
const req = new XMLHttpRequest();
req.open('GET', 'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json', true);
req.send();
req.onreadystatechange = function() {
  if (req.readyState === XMLHttpRequest.DONE) {
    if (req.status === 200) {
      const dataset = JSON.parse(req.responseText);
      console.log(dataset);
      console.log("First Item in dataset", dataset[0]);
      draw(dataset);
    }
  }
};

  // Create Tooltip
    const tooltip = d3.select("body")
      .append("div")
      .attr("class", "tooltip")
      .attr("id", "tooltip")
      .style("opacity", 0)
      .style("position", "absolute")
    .style("background-color", "white")
    .style("border", "1px solid black")
    .style("padding", "5px")
    .style("border-radius", "4px")
    .style("pointer-events", "none");
function draw(dataset) {
  console.log("Dataset structure:", dataset);  // This should show an array of objects
  console.log("1st item in dataset:", dataset[0]); // This should show an object with keys like Time, Place, etc.
    const w = 1400;
    const h = 700;
    const padding = 50;
// Define the time parser for yScale (mm:ss format)
  const timeParser = d3.timeParse("%M:%S");
// Define xScale to work directly with year values
const xScale = d3.scaleLinear()
  .domain([d3.min(dataset, d => d.Year), d3.max(dataset, d => d.Year)])
  .range([padding, w - padding]);
const yScale = d3.scaleTime()
    .domain([
      d3.min(dataset, (d) => timeParser(d.Time)), // Parse "mm:ss" strings to Date objects
      d3.max(dataset, (d) => timeParser(d.Time))
    ])
    .range([h - padding, padding]);
// Create SVG
    const svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h)
    .attr("class", "graph")
// Add Title and Subtitle
    svg.append("text")
      .text("Doping in Professional Bicycle Racing")
      .attr('text-anchor', 'middle')
      .attr('x', w / 2)
      .attr('y', 20 + padding)
      .style('font-size', '40px')
      .attr('id', 'title');

    svg.append("text")
      .text("35 Fastest times up Alpe d'Huez")
      .attr('text-anchor', 'middle')
      .attr('x', w / 2)
      .attr('y', 70 + padding)
      .style('font-size', '30px')
      .attr('id', 'subTitle');
 const xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y"));
    //const yAxis = d3.axisLeft(yScale);
    const yAxis = d3.axisLeft(yScale)
  .tickFormat(d3.timeFormat("%M:%S")); // Format ticks as "mm:ss"

    svg.append("g")
      .attr("transform", `translate(0, ${h - padding})`)
      .attr('id', 'x-axis')
      .call(xAxis);
svg.append("g")
  .attr("transform", `translate(${padding}, 0)`)
  .attr("id", "y-axis")
  .call(yAxis);
svg.selectAll("circle")
  .data(dataset)
  .enter()
  .append("circle")
  .attr("cx", (d) => xScale(d.Year))
  .attr("cy", (d) => yScale(timeParser(d.Time)))
  .attr("r", 5)
  .attr("class", "dot")
  .attr("data-xvalue", (d) => d.Year)
  .attr("data-yvalue", (d) => d.Time)
  .style("fill", (d) => d.Doping ? "red" : "blue")
  .on("mouseover", function(event, d) {
     console.log("Hovered data:", d);
    tooltip.style("opacity", 1)  // Make tooltip visible
      .html(`
        <strong>${d.Name}</strong>: ${d.Nationality}<br/>
        <strong>Year:</strong> ${d.Year}<br/>
        <strong>Time:</strong> ${d.Time}<br/>
        ${d.Doping ? `<strong>Doping:</strong> ${d.Doping}` : "No Doping"}
      `)
      .attr("data-year", d.Year)
      .style("left", `${event.pageX + 10}px`)
      .style("top", `${event.pageY - 28}px`);
  })
  .on("mouseout", function() {
    tooltip.style("opacity", 0);  // Hide tooltip
  });
// Add Legend
    svg.append("text")
      .attr('x', w - padding)
      .attr('y', h - padding + 30)
      .text('Legend');
    
    // Legend for Doping Status
  const legend = svg.append("g")
    .attr("id", "legend")
    .attr("transform", `translate(${w - 200},${h - 200})`);

  legend.append("rect")
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", 20)
    .attr("height", 20)
    .attr("fill", "red");

  legend.append("text")
    .attr("x", 30)
    .attr("y", 15)
    .text("Doping Allegations");

  legend.append("rect")
    .attr("x", 0)
    .attr("y", 30)
    .attr("width", 20)
    .attr("height", 20)
    .attr("fill", "blue");

  legend.append("text")
    .attr("x", 30)
    .attr("y", 45)
    .text("No Doping Allegations");
}

no, no blockquote, a code block.

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Hi @Ray3

All years on the x-axis show 1970

Happy coding

i fixed that yeah it still didnt solve the issue. that occured after many attempts to fix the tooltip

I’m able to access the data in the tooltip area like this:

dataset[d].Year

I hope this helps!

I am not able to access the tooltip info. I am only able to access the tooltip position in the array.

Not sure I understand, but I changed these lines:

console.log("Hovered data:", d);
<strong>Year:</strong> ${d.Year}<br/>

console.log("Hovered data:", dataset[d].Year);
<strong>Year:</strong> ${dataset[d].Year}<br/>

And now the year shows up.

Does this help?

This makes alot of difference. Thank you so much. Let me try it out. I changed plenty other d.year and scales and axis`.

1 Like

You are a moonument amongst statues, u are kite amongst leaves, u are a tornado in the wind. I was trying for so long lol, coding? uhm just btw all the data points dont produce a tooltip for some reason.

1 Like

the tooltip is produced for all data points but the tooltip is still appearing the top left corner.

However, you’re now passing all the tooltip tests.

You’re failing these now:

  1. The data-xvalue and data-yvalue of each dot should be within the range of the actual data and in the correct data format. For data-xvalue, integers (full years) or Date objects are acceptable for test evaluation. For data-yvalue (minutes), use Date objects.
  1. The data-yvalue and its corresponding dot should align with the corresponding point/value on the y-axis.

Maybe because of this change?