I just finished crafting a dynamic line chart with d3.js within a React environment. However, I am now looking to add some personalized touches to enhance its appearance. Could you kindly review the details and code

I want to create a line chart using React and D3, similar to the one depicted in this image.

Presently, I have partially implemented the chart with the code provided below. You can see it here.

The code snippet I've developed so far is outlined as follows -

import React, { Component } from "react";
import * as d3 from "d3";

const width = 400;
const height = 350;
const margin = { top: 20, right: 8, bottom: 20, left: 35 };

// Rest of the code...</questionbody>
<exquestionbody>
<div class="question">
                
<p>I am aiming to construct a line chart utilizing React and D3 like the design displayed below.
<a href="https://i.stack.imgur.com/xqvB0.png" rel="nofollow noreferrer">Desired line chart layout</a></p>

<p>I already have a chart created with the code I've written
<a href="https://i.stack.imgur.com/pNOBI.png" rel="nofollow noreferrer">Current line chart progress</a></p>

<p>The current code implementation is as follows -</p>

<p><div>
<div>
<pre class="lang-js"><code>import React, { Component } from "react";
import * as d3 from "d3";

const width = 400;
const height = 350;
const margin = { top: 20, right: 8, bottom: 20, left: 35 };

class LineChart extends Component {
  state = {
    line: []
  };

  xAxis = d3.axisBottom();
  yAxis = d3.axisLeft();

  static getDerivedStateFromProps(nextProps, prevState) {
    const { data } = nextProps;
    console.log("test", data);
    if (!data) return {};

    const yScale = d3.scaleLinear().range([height - margin.bottom, margin.top]);

    const xScale = d3
      .scaleBand()
      .domain(data.map(d => d.price))
      .range([margin.left, width - margin.right])
      .padding(1);

    // set domains on the scales
    const demandMax = d3.extent(data, d => d.demand);
    const priceMax = d3.extent(data, d => d.price);
    yScale.domain(demandMax);

    const lineGenerator = d3
      .line()
      .x(d => xScale(d.price))
      .y(d => yScale(d.demand));

    const line = [
      {
        fill: "none",
        path: lineGenerator(data),
        stroke: "steelblue"
      }
    ];

    return { line, xScale, yScale, data };
  }

  componentDidUpdate() {
    this.xAxis.scale(this.state.xScale);
    d3.select(this.refs.xAxis).call(this.xAxis);
    this.yAxis.scale(this.state.yScale);
    d3.select(this.refs.yAxis).call(this.yAxis);
  }

  render() {
    console.log(this.state.line);
    console.log(this.state.data);
    return (
      <svg width={width} height={height}>
        {this.state.line.map((d, i) => (
          <path key={i} d={d.path} stroke={d.stroke} fill={d.fill} />
        ))}
        <g ref="xAxis" transform={`translate(0, ${height - margin.bottom})`} />
        <g ref="yAxis" transform={`translate(${margin.left}, 0)`} />
      </svg>
    );
  }
}

export default LineChart;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

Now, I intend to incorporate functionality where circles encompass all points, initially displaying an area with dotted lines for one point with values inside a rectangle. Upon hovering over other points, the dotted lines correspond to those points. How can I achieve this using D3 in React? I'm struggling to find a solution.

Answer №1

Unfortunately, I don't have the ability to test your code to confirm that it functions exactly as you desire. However, it should be quite close for you to easily integrate it into your existing code.

For creating circles, you can consider implementing something like this:

<g transform={/* Add appropriate translate here */}>
  {data.map((d, i) => {
    return <circle
      key={i}
      cx={this.state.xScale(d.price)}
      cy={this.state.yScale(d.demand)}
      r={5}
      style={{
        fill: 'white',
        stroke: 'black'
      }}
    />
  })}
</g>

This section should be placed after the other g elements within your svg element.

To implement dotted lines, you need to listen for the mousemove event, update your state accordingly, and draw the lines based on the updated coordinates. Initially, add an event listener to capture mouse movements and store the coordinates in your state:

<svg 
  [your existing attributes]
  ...
  ref="svg" onMouseMove={(
    const xy = d3.mouse(this.refs.svg)
    // Update your state with the x and y coordinates from the xy array.
  )})>
  ...
  [your existing jsx]
</svg>

Don't forget to include a mouseout or mouseleave event listener to reset the stored coordinates in your state.

Then, whenever there are valid xy coordinates in your state, you can simply add paths within another g element:

{if (this.state.xy) {
  return <g>
      <path
        d={`M{margin.left},${this.state.xy[1]}L${this.state.xy[0]},${this.state.xy[1]}`}
        style={ fill: 'none', strokeDasharray: '5,5', strokeWidth: 2 }
      />
      <path
        d={`M{this.state.xy[0]},${height - margin.bottom}L${this.state.xy[0]},${this.state.xy[1]}`}
        style={ fill: 'none', strokeDasharray: '5,5', strokeWidth: 2 }
      />
    </g>
} else {
  return null
}}

Since I am unable to provide a functional example, you will need to adapt and merge this information into your project manually.

Furthermore, some of your positioning may be unconventional. Although I believe I've addressed it, exact confirmation is not guaranteed.

I trust that these suggestions prove helpful!

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 is the proper way to store the output in a variable? Angular and XLSX

I am attempting to read an Excel file from an input using Angular and convert the data into an array of objects. Here is how my components are structured: import * as XLSX from 'xlsx'; import { Injectable } from '@angular/core'; @Injec ...

Is it possible to trigger a re-render of a child component from its parent component in React without altering its props?

The issue at hand My parent component (X) is responsible for managing numerous states and child components. Within these children, there is an animated component (Y) - an avatar with various facial expressions that change in sync with its dialogue. Curr ...

Exploring IP geolocation integration within Rails 3

I am looking to add a dynamic feature to my homepage that will display the location object closest to the reader's physical location. Currently, I have a Location model with longitude and latitude fields. My goal is to retrieve the location model obj ...

Tips for ensuring all my onclick event are clickable in iOS browser

Currently, I am developing a web page using HTML5 and JQuery Mobile. I have encountered an issue where the onclick function does not work on iOS device browsers. Is there a way to change all onclick events to be accessible through tapping instead? This wou ...

User interface for modifying options in a dropdown menu

I seem to be facing a terminology dilemma. Currently, I have a database with values stored in a table that need to be displayed in a select drop-down on a web interface. The technology stack includes SQL Server, ColdFusion, and JavaScript, mainly jQuery. ...

React Animation Library With Smooth Initial Render and No Dependency on External Props

I'm currently implementing a Modal component within my app, utilizing Portals. My goal is for the Modal to smoothly fade in when it is rendered and fade out when it is no longer displayed. Upon examining the documentation for react-transition-group, ...

encountering a glitch during the electron.js build process with nextjs

When attempting to build Electron.js with Next.js, I keep encountering this persistent error. I have updated my packages and reinstalled node modules multiple times, but I am still unable to resolve it. C:\Users\Himanshu\Desktop\claros& ...

Tips for accessing the firebase user's getIdToken method in Next.js after a page reload

Currently, I am developing a Next.js project and implementing user authentication using Firebase's signInWithPhoneNumber method for phone number verification. After successful verification, I receive a Firebase user with the getIdToken method to retri ...

Error: Unable to find the transport method in Socket.io

I recently implemented user side error logging on my website to track errors. I have noticed that sometimes it logs a specific error related to socket.io code: TypeError: this.transport is undefined This error seems to only occur for users using Firefox ...

Ways to stop users from navigating back in react-router-dom

I'm currently implementing react-router-dom for navigation in my reactjs application. I am looking for a way to disable the ability for users to go back to the login screen after they have successfully logged in. I want to prevent users from going bac ...

Retrieve the properties of all post components in NextJS

Transitioning my blog from Jekyll to NextJS has brought up a challenge - how can I retrieve all posts in one unified list? Although most resources suggest parsing markdown files and extracting front matter, my posts heavily rely on schema.org attributes a ...

Retrieving Vue data from parent components in a nested getter/setter context

<template> <div id="app"> {{ foo.bar }} <button @click="meaning++">click</button> <!--not reactive--> <button @click="foo.bar++">click2</button> </div> </templ ...

Is there a way to easily open the RSS link XML Element in a separate browser tab or window?

I have been exploring RSS and creating titles with links. However, when clicking on the link it opens in the same window. I would like it to open in a new window instead. Can someone please advise me on how to achieve this? <a href="http://www.google ...

After the custom drop down is opened and closed, the form input in React becomes unresponsive

Having trouble with a custom drop-down component in a form? I've been struggling to identify the issue all day. I've tried various solutions like using useRef and leveraging defaultValue from SO answers. The text input for 'Menu Name' ...

What is the correct method for closing a style element in Nextjs JSX?

Having trouble adding some unique styling to a jsx component. The code snippet below is throwing an error when compiled. import Card from "./card"; export default function CardRow(){ return( <> <div> <Card> ...

Unable to retrieve the complete count of invitations made by a user

My goal is to retrieve the invites of the author of a specific command within one server. I have experimented with various solutions, but many appear outdated or incorrect. Here is my current approach: exports.run = async (client, message, args) => { ...

``Trouble with React Dropdown menu option selection"

I am encountering challenges with implementing a dropdown menu list for my react app. The issue at hand is that I have an API where one of the keys (key3) has values separated by commas that I wish to display in my dropdown list. The structure of the API ...

Having trouble establishing a connection to the back-end server with minikube

I am currently facing an issue with deploying an application in minikube locally. While I can successfully connect to the front-end when minikube is running, I encounter connectivity problems with the back end. Below are the yaml files that I am using: I ...

At what point does the event loop in node.js stop running?

Could you please enlighten me on the circumstances in which the event loop of node.js terminates? How does node.js determine that no more events will be triggered? For instance, how does it handle situations involving an HTTP client or a file reading app ...

What could be the reason my homing missile algorithm is not functioning properly?

The code I'm currently using for my projectile was heavily inspired by an answer I found on a game development forum, but it's not working as expected. Most of the time, the initial direction of the projectile is perpendicular to the target inste ...