Can someone explain the process of locating the final data point in d3 and illustrating it using a circle and a line?

https://i.sstatic.net/0AWgj.png

I have successfully created a basic line chart in d3. My goal now is to determine the last entry point of the data and draw a circle on it, along with a dotted line similar to the image provided above.

Below is my current d3 code:

const xScale = scaleTime()
      .range([0, width])
      .domain(
        extent(data, (d: { week: any }) => {
          return d.week;
        })
      );

    const yScale = scaleLinear()
      .range([height, 0])
      .domain([
        min(data, (d: { index: number }) => {
          return d.index;
        }) - 20,
        max(data, (d: { index: number }) => {
          return d.index;
        }) + 20
      ]);

    const xAxis = axisBottom(xScale)
       .ticks(data.length);
    
    const svg = select(svgRef.current);

    svg
      .select(".x-axis")
      .style("transform", `translateY(${height}px)`)
      .call(xAxis);

    const yAxis = axisLeft(yScale);
    svg
      .select(".y-axis")
      .call(yAxis);

    const myLine = line()
      .x((d: { week: any }) => xScale(d.week))
      .y((d: { index: any }) => yScale(d.index))
      .curve(curveCardinal);

    svg
      .selectAll(".line")
      .data([data])
      .join("path")
      .attr("class", "data-circle")
      .attr("d", myLine)
      .attr("fill", "none")
      .attr("stroke", "purple")
      .attr("stroke-width", "5px");

      // To do: draw circle here
      svg
      .selectAll(".data-circle")
      .data([data])
      .append("circle")
      .attr("r", 7.5);

I have attempted to target the correct element that would allow me to identify the final entry in the array, but I keep encountering errors. It seems like there might be a simple adjustment needed.

The circle does not need to appear only on mouse hover; it should be drawn by default and adjust automatically if different data sets are loaded.

Answer №1

On each update, compute the coordinates of the point, and determine if it already exists or needs to be created:

const previousData = data[data.length-2];
const yCoord = yScale(previousData.index));
const xCoord = xScale(previousData.week));

let existingPoint = svg.select('.existing-point');
let dashedLine = svg.select('.dashed-line');
if (!existingPoint.node()) {
  existingPoint = svg.append('circle')
    .classed('existing-point', true)
    .style('fill', 'blue')
    .attr('r', 7);
  dashedLine = svg.append('line')
    .classed('dashed-line', true)
    .attr('stroke-dasharray', '3')
    .style('stroke', 'gray');
}

existingPoint
  .attr('cx', xCoord)
  .attr('cy', yCoord);

dashedLine
  .attr('x1', xCoord)
  .attr('x2', xCoord)
  .attr('y1', yCoord)
  .attr('y2', height);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be the reason behind the unexpected outcome of process.argv[3] when its value is set to '*'?

My calculator app is very straightforward: if (process.argv[3]==='+') console.log(parseInt(process.argv[2]) + parseInt(process.argv[4])); if (process.argv[3]==='-') console.log(parseInt(process.argv[2]) - parseInt(process.argv[4])); i ...

What is the best way to resume a Jquery function if it has not

How do I make my form alert re-trigger when the user clicks the button again if the input is still empty? What I've tried: After clicking the button, it checks if the inputs are empty and shows an alert. However, once the alert appears, if I click th ...

Jade: modify the text box input to show = " ..."

I am new to Jade and Html, and I am currently working on creating a form in Jade. The issue I am facing involves a simple text box that looks like this: input(type='text', name='sessionID', value = 'valueID') Whenever I want ...

Ways to resolve the issue of data not displaying on the page, even though it appears in the

I am attempting to upload an image that has been converted to a URL using Ajax. The issue I am facing is that $image = $_POST['imgData']; does not display anything, but when I check the developer tools in the network preview, the data can be seen ...

Attempting to implement form validation on my website

Recently watched a tutorial on basic form validation on YouTube, but I'm encountering an issue where the error messages from my JavaScript file are not displaying on the website during testing. I have set up the code to show error messages above the l ...

Why is the code to check if the user has scrolled to the bottom not working in Chrome but working in Microsoft Edge?

I have been using this code to determine if a user has scrolled to the bottom of a page, but I've run into some issues specifically with Google Chrome. Surprisingly, the code works flawlessly on Microsoft Edge. On Google Chrome, when I scroll to the ...

"Implementing self-referencing mongoose models in Typescript: A step-by-step guide

I have a model: const message = new mongoose.Schema({ id: { type: ObjectId, required: true }, text: { type: String }, replies: [message] }); Looking to create a document structure like this: { "id": 1, "text": "Main Message", "replies": [ ...

Angular 8 and the conundrum of date parsing issues

const timestamp = '2020-07-11T00:05:00'; const dateOfFlight = new Date(timestamp); dateOfFlight.getMonth() // The output should be 6 However, it is expected to be 7 based on the provided timestamp. ...

Whispering form using onblur and onfocus

Seeking assistance with echoing a form that includes multiple input fields. Specifically, I am attempting to utilize onblur and onfocus (refer to the conditions outlined in the code). However, I am encountering an issue where the Javascript function does ...

Transmit form data via Ajax request

Thank you for your interest. I am looking to retrieve $_POST['Division'] from a dropdown list: <select name="Division" onchange="setImage2(this);"> <option value="1">Bronze</option> <option value="2">Silver</op ...

What is the best way to remove all attributes from one interface when comparing to another?

Consider the following two interfaces: interface A { a: number; b: string; } interface B { b: string; } I am interested in creating a new type that includes all the keys from interface A, but excludes any keys that are also present in interface B. ...

Having difficulties viewing the sidemenu icon on Ionic 3, despite enabling the menu through MenuController

I am trying to show the sidemenu icon on my Home page, which users can access from the Add-Contract page. Even though I have enabled the sidemenu in home.ts using this.menu.enable(true);, the icon is not visible. However, I can still swipe and access the ...

Issues arising from code that computes percentages

I currently have three boxes in my HTML template that are meant to calculate and display various values. The first box is calculating a score, the second box represents the total amount of points possible, and the third box is supposed to show the percenta ...

Encountering issues with ASP.NET WebAPI: When using $.ajax, a 404 error occurs, while using $.getJSON results in an Uncaught

Currently, I am developing an ASP.NET web API with a C# project that I am attempting to call from JavaScript. Below is the snippet of my JavaScript code: function LoadGraph() { var file = document.getElementById("file-datas"); if ('files' in fi ...

When multi or upsert is set to true, MongoDB fails to update records and promises continue to fail

I am facing issues with updating records in MongoDB using mongoose. Although my code seems to be correct, it does not update the record as expected. Below is the code snippet: edit(req, res, next) { var WorkType = require('../models/WorkType'); ...

Retrieve the chosen selection from a dropdown menu using AngularJS and Ionic

I've been encountering some issues with the select feature in AngularJS. Despite searching extensively for solutions, none seem to be working for me. The JSON structure I'm dealing with is generated from my service.php: [ { "Name": ...

What is the best way to determine the total number of elements within this JSON data structure?

Is there a way to determine the number of elements in a JSON object using JavaScript? data = { name_data: { 35: { name: "AA", }, 47: { name: "BB", }, 48: { name: "CC", ...

What is the best approach for creating a brute-force solution for finding the smallest change algorithm

Looking for a solution to this algorithm challenge: Create a function that can determine the minimum amount of change that cannot be made with the given coins. function nonConstructibleChange(coins) { coins = coins.sort((a, b) => a - b); // O(nlogn) ...

Unspecified OrbitControls Compatibility Issue between Angular2 and Three.js

I'm running into issues trying to set up OrbitControls in my Angular2 project. I managed to display a scene with a box, but I'm struggling to move the camera. Upon investigation, I found that my OrbitComponent, responsible for defining orbit con ...

The most effective method for adding data to a <pre /> element is through VueJS

I have an electron app that executes a program and stores the output when data is received. My goal is to showcase the content of this output within an html pre element. One approach I can take is to create a variable and continuously add the output data ...