WellAlly Logo
WellAlly康心伴
Development

Building a Real-Time Heart Rate Dashboard: Visualizing Live Data with React & WebSockets

Learn how to build a full-stack, real-time heart rate dashboard. Master streaming live data from a Node.js backend with WebSockets to a React frontend and visualizing it with Chart.js.

W
2025-12-18
9 min read

In the age of instant information, from live stock tickers to IoT sensor monitoring, the demand for real-time data visualization has never been higher. For developers, this presents a unique challenge: how do you efficiently push continuous data streams from a server to a client and render them in a way that is both performant and visually intuitive?

This tutorial will guide you through building a full-stack web application that does exactly that. We'll create a real-time heart rate dashboard that simulates live ECG data, streams it from a Node.js backend using WebSockets, and visualizes it on a React frontend with a dynamic, ECG-style chart.

By the end of this guide, you'll have a solid understanding of WebSocket communication and the skills to build your own real-time applications.

Prerequisites:

  • Basic understanding of JavaScript, React, and Node.js.
  • Node.js and npm installed on your machine.
  • A code editor like VS Code.

This project is more than just a technical exercise; it's a practical demonstration of how to build responsive, engaging user experiences that are becoming essential in modern web development.

Understanding the Problem

Traditional web applications rely on the client-request/server-response model of HTTP. For real-time data, this would mean constant polling from the client, which is inefficient and introduces latency.

WebSockets, on the other hand, provide a persistent, two-way communication channel between the client and the server. This allows the server to push data to the client as soon as it's available, making it ideal for applications like live charts, instant messaging, and online gaming.

Our approach will be to:

  1. Simulate Data: Create a Node.js script that generates realistic, real-time heart rate data.
  2. Stream Data: Use a WebSocket server to broadcast this data to all connected clients.
  3. Visualize Data: Build a React component that connects to the WebSocket server and renders the incoming data on a live-updating chart.

Prerequisites

Before we start, make sure you have Node.js and npm installed. You can check by running node -v and npm -v in your terminal.

Let's set up our project structure:

code
mkdir heart-rate-dashboard
cd heart-rate-dashboard
mkdir server client
Code collapsed

Step 1: Building the Node.js WebSocket Server

First, let's create our backend server that will simulate and stream the heart rate data.

What we're doing

We'll set up a simple Node.js server using the popular ws library, a lightweight and efficient WebSocket implementation for Node.js. This server will periodically generate a new heart rate data point and broadcast it to all connected clients.

Implementation

Navigate to the server directory and initialize a new Node.js project:

code
cd server
npm init -y
npm install ws
Code collapsed

Now, create a file named server.js:

code
// server/server.js
import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 8080 });

// Function to simulate a single ECG data point
const generateEcgPoint = (time) => {
    const pWave = 0.1 * Math.exp(-Math.pow((time % 1) - 0.2, 2) / 0.005);
    const qrsComplex = 0.8 * Math.exp(-Math.pow((time % 1) - 0.5, 2) / 0.003) - 0.2 * Math.exp(-Math.pow((time % 1) - 0.5, 2) / 0.01);
    const tWave = 0.2 * Math.exp(-Math.pow((time % 1) - 0.8, 2) / 0.01);
    return pWave + qrsComplex + tWave;
};

let time = 0;
const clients = new Set();

wss.on('connection', (ws) => {
    console.log('Client connected');
    clients.add(ws);

    ws.on('close', () => {
        console.log('Client disconnected');
        clients.delete(ws);
    });
});

setInterval(() => {
    const dataPoint = {
        time: new Date().toLocaleTimeString(),
        value: generateEcgPoint(time),
    };

    const data = JSON.stringify(dataPoint);

    for (const client of clients) {
        if (client.readyState === 1) { // WebSocket.OPEN
            client.send(data);
        }
    }

    time += 0.05;
}, 50);

console.log('WebSocket server started on port 8080');
Code collapsed

How it works

  • We import WebSocketServer from the ws library and create a new server on port 8080.
  • The generateEcgPoint function creates a simplified, repeating ECG-like waveform based on the current time.
  • When a new client connects, we log the connection and add the client to a Set.
  • Every 50 milliseconds, we generate a new data point, stringify it, and broadcast it to every connected client.
  • If a client disconnects, we remove them from our set of active clients.

To run the server, execute:

code
node server.js
Code collapsed

You should see "WebSocket server started on port 8080" in your terminal.

Step 2: Creating the React Frontend

Now, let's build the client-side application that will receive and visualize the data.

What we're doing

We'll use Create React App to set up our project and install chart.js and react-chartjs-2 for data visualization. We'll create a component that establishes a WebSocket connection to our server and updates a line chart in real-time with the incoming data.

Implementation

Navigate to the client directory and create a new React app:

code
cd ../client
npx create-react-app .
npm install chart.js react-chartjs-2
Code collapsed

Now, replace the content of src/App.js with the following:

code
// client/src/App.js
import React, { useState, useEffect, useRef } from 'react';
import { Line } from 'react-chartjs-2';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

const App = () => {
  const [data, setData] = useState({
    labels: [],
    datasets: [
      {
        label: 'Heart Rate',
        data: [],
        borderColor: 'rgb(255, 99, 132)',
        backgroundColor: 'rgba(255, 99, 132, 0.5)',
      },
    ],
  });

  const ws = useRef(null);

  useEffect(() => {
    ws.current = new WebSocket('ws://localhost:8080');

    ws.current.onopen = () => console.log('WebSocket connection opened');
    ws.current.onclose = () => console.log('WebSocket connection closed');

    ws.current.onmessage = (event) => {
      const newDataPoint = JSON.parse(event.data);
      setData((prevData) => {
        const newLabels = [...prevData.labels, newDataPoint.time];
        const newData = [...prevData.datasets.data, newDataPoint.value];

        // Keep the chart to a manageable size
        if (newLabels.length > 50) {
          newLabels.shift();
          newData.shift();
        }

        return {
          ...prevData,
          labels: newLabels,
          datasets: [
            {
              ...prevData.datasets,
              data: newData,
            },
          ],
        };
      });
    };

    return () => {
      ws.current.close();
    };
  }, []);

  const options = {
    scales: {
      y: {
        beginAtZero: true,
        suggestedMax: 1,
        suggestedMin: -0.5,
      },
    },
    animation: false,
  };

  return (
    <div style={{ width: '80%', margin: 'auto' }}>
      <h1>Real-Time Heart Rate Monitor</h1>
      <Line data={data} options={options} />
    </div>
  );
};

export default App;
Code collapsed

How it works

  • We import the necessary components from react-chartjs-2 and chart.js.
  • We use the useState hook to manage the chart's data.
  • The useEffect hook is used to establish the WebSocket connection when the component mounts.
  • When a message is received from the server, we parse the JSON data and update our component's state, which in turn re-renders the chart.
  • To prevent the chart from becoming cluttered, we limit the number of data points displayed to the most recent 50.
  • The options object for the chart disables animations for a smoother real-time feel and sets the scale of the y-axis.

Putting It All Together

With both the server and client running, you can now see the real-time dashboard in action.

  1. Start the server: In the server directory, run node server.js.
  2. Start the client: In the client directory, run npm start.

Your browser should open to http://localhost:3000 and display a live-updating ECG-style chart.

Security Best Practices

For a production application, it's crucial to secure your WebSocket connection. This involves:

  • Using wss://: The secure version of WebSockets, wss://, uses SSL/TLS encryption. You would need to set up a secure HTTPS server and pass it to your WebSocket server.
  • Origin Validation: Validate the Origin header on the server to ensure that connections are only accepted from trusted domains.
  • Authentication: Implement an authentication mechanism, such as token-based authentication, to verify the identity of connecting clients.

Production Deployment Tips

When deploying a WebSocket application, consider the following:

  • Hosting: Choose a hosting provider that supports WebSocket connections, such as Heroku or a cloud provider like AWS or Google Cloud.
  • Reverse Proxy: Use a reverse proxy like Nginx to handle SSL termination and load balancing.
  • Scalability: For a large number of concurrent connections, consider a more robust solution like Socket.IO, which offers features like automatic reconnection and fallback to long-polling.

Alternative Approaches

While WebSockets are an excellent choice for real-time data streaming, other technologies to consider include:

  • Server-Sent Events (SSE): A simpler, one-way communication protocol where the server can push data to the client.
  • WebRTC: Primarily for peer-to-peer communication, but can also be used for real-time data transfer.
  • MQTT: A lightweight messaging protocol often used in IoT applications.

Conclusion

You've successfully built a full-stack, real-time data visualization dashboard! You've learned how to:

  • Set up a Node.js WebSocket server to stream data.
  • Connect a React application to a WebSocket server.
  • Visualize real-time data using Chart.js.

This project serves as a strong foundation for building more complex real-time applications. You can now explore sending data from the client to the server, implementing user authentication, or even connecting to a real hardware heart rate monitor.

Resources

#

Article Tags

reactnodejswebsocketsdatavisualizationfullstacktutorial
W

WellAlly's core development team, comprised of healthcare professionals, software engineers, and UX designers committed to revolutionizing digital health management.

Expertise

Healthcare TechnologySoftware DevelopmentUser ExperienceAI & Machine Learning

Found this article helpful?

Try KangXinBan and start your health management journey

© 2024 康心伴 WellAlly · Professional Health Management