Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

React Scatter Charts

LightningChart JSReact Scatter Charts

ArticleUnleashing the power of scatter charts: visualizing relationships and correlations in data using React

Continue Reading

React Scatter Charts

In today’s data-driven world, the ability to effectively visualize and interpret data is crucial for businesses across various industries. Whether you are analyzing complex datasets, tracking trends, or discovering patterns, charts and visualizations play a vital role in simplifying how we understand values and transform them into information and knowledge.

Among the wide range of available charting options, scatter charts stand out as a powerful tool for visualizing relationships and correlations within data points.

In this article, we will explore the fascinating world of scatter charts and delve into how you can create stunning scatter charts using the React framework, a popular JavaScript library for building user interfaces.

A scatter chart, also known as a scatter plot or scatter graph, is a type of chart that displays individual data points on a two-dimensional coordinate system. Unlike traditional line or bar charts that focus on showing trends or comparisons, scatter charts excel in revealing relationships and patterns between variables.

Each data point on the scatter chart represents the values of two variables. That is one variable plotted along the horizontal X-axis and the other one plotted along the vertical Y-axis.

The position of each data point on the chart is determined by the respective values of the variables it represents. By visually examining the distribution and clustering of data points, we can gain insights into the correlation, concentration, or dispersion of the variables.

React scatter charts are particularly useful for identifying trends, outliers, clusters, and even for detecting anomalies within datasets.

How to create React scatter charts?

Now that we understand the significance of scatter charts, let us explore how we can harness the power of LightningChart JS, a high-performance JavaScript charting library, to create stunning scatter charts using React.

Before diving into the code, we need to ensure that our development environment is properly set up. We will install the necessary dependencies, including React and LightningChart JS, and set up a new React project.

You will need to have Node => 14 on your local development machine (but not required on the server). To create a new app, use the below command:

npm init react-app my-new App

Add the node-modules (LCJS Library) into the node-modules folder. Install the LCJS library using the below command:

npm install @arction/lcjs

Create a component folder in the src folder and create a new file with JS extension in the same folder (you can name it whatever you like. In this example, I have named it as “Chart”).

Import the LightningChart JS library and React components.

import {lightningChart} from '@arction/lcjs'
import React, {useRef, useEffect} from 'react'

Create a scatter chart using react components and LightningChart functions.

const Chart = (props) => {
    const {data, id} = props
    const chartRef = useRef(undefined)
  
    useEffect(() => {
      const chart = lightningChart().ChartXY({container: id})
      const series = chart.addPointSeries()
      chartRef.current = {chart, series}

    }, [id])
  
    useEffect(() => {
      const components = chartRef.current
      if (! components) return
      const {series} = components
      series.add(data)
    
    }, [data, chartRef])
  
    return 
} export default Chart

App.js

For the implementation, I will be dropping the scatter chart component inside my ‘App.js.’ and I am setting the data as an array. The type of the array would be the type I defined in the scatter component and will hold the X value and Y value for the scatter chart.

This could be easily extracted as a CSV or JSON and the data can be shared across multiple components if needed. As for the ‘Scatter chart,’ I will pass the visual setting I set in the scatter component, look.

import React, { useEffect, useState } from 'react';
import './App.css'
import Chart from '. /Component/Chart'

const App = (props) => {
  const [data1, setData1] = useState([])
  useEffect(() => {
    const interval1 = setInterval(() => {
      setData1([
        {x: 0, y: Math.random() * 100},
        {x: 1, y: Math.random() * 100},
        {x: 2, y: Math.random() * 100},
        {x: 3, y: Math.random() * 100},
        {x: 4, y: Math.random() * 100},        
      ])
    }, 3000)
    return () => {
      clearInterval(interval1)
    }
  }, [])

  return 
} export default App

And we can run the app using the below commands:

npm install 
npm start

To run the app in the development mode, open http://localhost:3000 to view it in the browser. The page will reload if you make any edits. You will also see any errors in the console.

npm test

To launch the test runner in the interactive watch mode, see the section about running tests for more information.

npm run build

Builds the app for production to the build folder.

It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes. So, now your app is ready to be deployed!

LightningChart JS has multiple types of scatter charts, let’s explore them all in more detail:

  1. Large scatter chart
  2. 3D scatter chart
  3. Realtime 3D scatter chart
  4. Confidence ellipse chart
  5. Flow cytometry chart
  6. 3D confidence Ellipsoid chart

Large Scatter Chart

This example highlights the visualization of a scatter chart with a large data set (1 million data points). LightningChart JS has highly innovated the possibilities of data visualization on the web.

Previously, scatter chart visualizations were realistically possible to only process limited ranges of some hundred thousand data points. Back then, scatter charts required complicated development efforts to enable any zooming or panning interactions with a barely satisfactory performance.

Now, with LightningChart JS it is possible to easily visualize more than million data points in a scatter chart. These amount of data points are loaded in less than a second and the result is unlike anything seen before. For instance, UI interactions such as like zooming and panning can be done by the user instantaneously.

Additionally, when LightningChart JS scatter charts are compared to other charting solutions, the usage is ridiculously simple. Let’s see:

With SVG/Canvas-based drawing, users have severe limitations with processing large amounts of data as these technologies do not scale well.

Instead, with LightningChart JS, this processing takes about 100 milliseconds to load and is immediately available with lightning-fast reactions. Definitely a great experience for end-users!

Here is how simple the creation of a million points scatter chart is with LightningChart JS:

const chart = lightningChart().ChartXY()
const series = chart.addPointSeries(). add (
    new Array (1000000). fill (). map ((_) => ({
        x: Math.random(),
        y: Math.random(),
    })),
)

If the user wants to change the point shape and set the shape size in the chart, use this code:

const pointSeries = chart
  .addPointSeries({ pointShape: PointShape.Square })
  .setPointSize(1)
The below code draws the ellipse or visualizes the confidence ellipse with polygon series. The data cursor does not perform well with scatter charts in millions of data points range that is the reason we the set cursor as false.
const polygonSeries = chart
  .addPolygonSeries()
  .setCursorEnabled(false);

The below code is for to colouring the scatter chart points:

polygonSeries
            .setFillStyle(new SolidFill({ color: ColorCSS('gray').setA(30)}))
            .setStrokeStyle(
                new SolidLine({
                    thickness: 1,
                    fillStyle: new SolidFill({ color: ColorCSS('white')}),
                }),
            )

Final Output

3D Scatter chart

3D React scatter charts are also known as Scatter Graphs, Scatter Series, Point Graphs, Scatter diagrams, or Scattergram. This example shows a simple 3D Point Graph with points drawn using 3D Point Series to visually represent the data points or ‘markers’.

The point graph is a type of chart or mathematical diagram drawn on a Cartesian coordinate system and represents the relationship between two variables. This type of series does not contain the visual representation of lines for the connection of data points but only data ‘markers’. The chart can be created with a few simple lines of code:

const chart3D = lightningChart(). Chart3D ()
const series = chart3D.addPointSeries()

Use the below code to set the axis title for the 3D chart. Using getDefaultAxisX(), getDefaultAxisY(), and getDefaultAxisZ() methods, the user can set the title for each axis as well.

chart3D.getDefaultAxisX().setTitle('Axis X')
chart3D.getDefaultAxisY().setTitle('Axis Y')
chart3D.getDefaultAxisZ().setTitle('Axis Z')

Use the below code to create a point series for rendering Y coordinates.

const pointSeriesMaxCoords = chart3D.addPointSeries().setName('Max coords')
pointSeriesMaxCoords.setPointStyle(
    new PointStyle3D.Triangulated({
        fillStyle: pointSeriesMaxCoords.getPointStyle().getFillStyle(),
        size: 10,
        shape: 'sphere',
    }),
)

Use the below code to Create another Point Series for rendering other Y coordinates than Max.

const pointSeriesOtherCoords = chart3D.addPointSeries({ automaticColorIndex: 2 }).setName('Below Max')
pointSeriesOtherCoords.setPointStyle(
    new PointStyle3D.Triangulated({
        fillStyle: pointSeriesOtherCoords.getPointStyle().getFillStyle(),
        size: 5,
        shape: 'cube',
    }),
)

The series accepts points in format {x: number, y: number, z: number}. Any number of points can be added with a single call.

// Single point.
series.add({x: 50, y: 60, z: 40})

// Multiple points at once.
series.add([
    {x: 55, y: 60, z: 40},
    {x: 60, y: 62, z: 40},
    {x: 65, y: 65, z: 50},
])

Final Output:

Realtime 3D Scatter Chart

Example highlighting the use of 3D point series in a high-performance application, with constantly changing data. This example of 3D realtime React scatter charts can be created with a few simple lines of code.

Import the LightningChart JS library using node.

const lcjs = require('@arction/lcjs')

Below is the code for initializing the chart:

const chart3D = lightningChart(). Chart3D ({
    theme: Themes.darkGold,
})

Use the below code to set the axis title for the RealTime 3D chart. By using getDefaultAxisX(), getDefaultAxisY(), and getDefaultAxisZ() methods, the user can set the title for each axis as well.

chart3D.getDefaultAxisX().setTitle('Axis X')
chart3D.getDefaultAxisY().setTitle('Axis Y')
chart3D.getDefaultAxisZ().setTitle('Axis Z')

Set static Axis intervals.

set Interval  method allows us to set the distance between Tick Marks on Axis. Lightningchart JS provides two more types of axis interval configurations: stop axis scrolling, and animation with specified milliseconds.

chart3D.forEachAxis((axis) => axis.setInterval({start: 0, end: 100}))

To Create a Point Cloud Series (variant optimized for rendering minimal detail geometry):

const pointSeries3D = chart3D.addPointSeries({type: PointSeriesTypes3D.Pixelated }).setPointStyle((style) => style.setSize(5))

Example data generation configuration. Amount of data visible at a time.

const pointBatchSize = 10000

Amount of unique data sets.

const uniqueDataSetsCount = 5

Visible duration of each data set in milliseconds.

const frameDurationMs = 100

Set title for the chart:

chart3D.setTitle(`3D Realtime Point Series (${pointBatchSize} data points per frame) `)

Generate Data:

new Promise ((resolve, reject) => {
    const dataSets = []
    for (let iDataset = 0; iDataset  {
    let iDataSet = 0
    let lastSwitch
    const switchDataSet = () => {
        iDataSet = (iDataSet + 1) % uniqueDataSetsCount
        const data = dataSets[iDataSet]
        pointSeries3D
            . clear ()
            . add(data)
        lastSwitch = Date.now()
    }
    switchDataSet()
    const checkRegularDataSetSwitch = () => {
        if (Date.now() - lastSwitch >= frameDurationMs) {
            switchDataSet()
        }
        requestAnimationFrame(checkRegularDataSetSwitch)
    }
    checkRegularDataSetSwitch()
})

Final Output:

Confidence Ellipse Chart

This example shows how a confidence ellipse can be drawn inside a scatter chart with LightningChart JS. Confidence ellipses are used especially with statistic chart applications.

A common usage, for example, is the 95% confidence ellipse, which visualizes the area that contains 95% of samples, which makes it easier for the user to understand which points are outliers.

There are several ways of defining and calculating the shape of different confidence ellipses – traditionally in 2D applications they are rotated ellipses with width and height. However in some cases they might not actually be ellipses geometrically but more complex shapes instead.

LightningChart JS currently does not come with any routine for calculating a confidence ellipse shape. However, about any kind of confidence, the ellipse shape can be visualized using the PolygonSeries. Here’s how to create the series and the chart using LightningChart JS:

const chart = lightningChart()
    .ChartXY({
        theme: Themes.darkGold,
    })
    .setTitle('Scatter chart + confidence Ellipse')

Create point series for visualizing scatter points:

const pointSeries = chart.addPointSeries({ pointShape: PointShape.Circle }).setPointSize(3).setName('Scatter series')

The below code visualizes the confidence ellipse with the polygon series. The routine for calculation of confidence ellipse coordinates from the scatter data set is not currently included in LightningChart JS!

const polygonSeries = chart
  .addPolygonSeries()
  .setCursorEnabled(false);

LightningChart JS provides the data in JSON format. The below code is Fetching example data from JSON Asset.

fetch (document.head.baseURI + 'examples/assets/0015/data-confidenceEllipseXY.json')
    . then((r) => r.json())
    . then((data) => {
        const { scatterPoints, confidenceEllipsePolygonCoords } = data

        // Add data to series.
        pointSeries.add(scatterPoints)
        polygonSeries
            . add(confidenceEllipsePolygonCoords)
            .setFillStyle(new SolidFill({ color: ColorCSS('gray').setA(30)}))
            .setStrokeStyle(
                new SolidLine({
                    thickness: 1,
                    fillStyle: new SolidFill({ color: ColorCSS('white')}),
                }),
            )
    })
PolygonSeries can be used to draw any non-complex polygon shape (polygon that does not intersect with itself) inside XY charts. It is configured by supplying a list of {x: number, y: number} coordinates. Here’s an example of a visualization of a polygon inside a ChartXY.
const polygonSeries = chart.addPolygonSeries()
const polygonFigure = polygonSeries.add([
    {x: 0, y: 0},
    {x: 5, y: 10},
    {x: 10, y: 15},
    {x: 15, y: 5},
    {x: 10, y: -5},
    {x: 5, y: -2},
])

Final Output:

Flow Cytometry Chart

Flow cytometry is an everyday method in research and clinical practices for analyzing individual cells within heterogeneous samples (like blood samples, for example).

It is based on observing the behavior of pointed light and can rapidly analyze multiple parameters from each cell. In this example, all the samples are displayed in a single chart which displays the following information:

  • Forward scatter (FSC). This is measured based on how much light is scattered along the path of the light source.
  • Side scatter (SSC). This is measured based on how much light is scattered at a ninety-degree angle relative to the light source.

Each point in the chart is one sample. When multiple samples have the same SSC and FSC measurement, the point color is adjusted (red = most overlapping samples).

In practice, the data from flow cytometry is filtered through several steps that each look at the relationship between some data attributes. This example is just 1 of these steps.

As an example of this filtering, some applications might select some valid range of FSC/SSC values that will be considered in later analysis steps.

Flow Cytometry And LightningChart

The go-to framework for visualizing flow cytometry is “R“, a software environment for statistical computing and graphics. Here are some scenarios where we believe LightningChart is a strong alternative:

  1. Real-time data

LightningChart excels at fast changes to datasets. If your application continuously receives data, especially with high rates like several times in a second, LightningChart JS is what you need.

  1. Data interactions

In some cases, users might need the ability to interact with data (panning, zooming, cursor, etc.). In many statistical tools, these kinds of features do not exist since only a minority would have a use for them. Additionally, even if present they might not perform too well, especially with large data sets.

  1. Deployment on the Internet

R is a statistical programming language and in most cases, users will install it on their own computer and directly interact with datasets and create data visualization applications.

LightningChart JS, on the other hand, is a web library. LC JS projects can be conveniently embedded inside web pages, mobile, and even desktop applications. The below code is to create a scatter chart:

const chart = lightningChart()
    .ChartXY({
        theme: Themes.darkGold,
    })
    .setTitle('Flow Cytometry Visualization')
    .setMouseInteractions(false)
    .setPadding(0)

Configure axis x and axis y for the charts.

In the below code using the getDefaultAxisX() method, the user can configure the axis by setting the interval title for the chart. The method setMouseInteractions() is used for scrolling enable or disable for axis but for now, in this example, we are disabling mouse interactions.

setThickness() is constructing a new Line Style object based on this one but with modified thickness. -1 can be used to signify the smallest available thickness. With most features, this will result in slightly better GPU performance, but a less detailed line.

const axisX = chart
    .getDefaultAxisX()
    .setInterval({start: 1.3, end: 10})
    .setTitle('FSC-A (10⁶)')
    .setMouseInteractions(false)
    .setThickness(60)

const axisY = chart
    .getDefaultAxisY()
    .setInterval({start: -0.2, end: 1.8})
    .setTitle('SSC-A (10⁶)')
    .setMouseInteractions(false)
    .setThickness(80)

The below code is for creating point series, configuring the points, and coloring the points using setPointFillStyle (). setIndividualPointValueEnabled() is used for Enabling or disabling individual point value attributes. When enabled, each added data point can be associated with a numeric value attribute.

.setIndividualPointValueEnabled(true)
    .setPointSize(2)
    .setCursorResultTableFormatter((builder, _, __, ___, dp) => builder.addRow(`value: `, dp.value?.toFixed(2)))
    .setPointFillStyle(
        new PalettedFill({
            lookUpProperty: 'value',
            lut: new LUT ({
                interpolate: true,
                steps: [
                    {value: 0, color: ColorRGBA(0, 0, 0, 0)},
                    {value: 1, color: ColorRGBA(0, 0, 255)},
                    {value: 10, color: ColorRGBA(50, 50, 255)},
                    {value: 50, color: ColorRGBA(0, 255, 0)},
                    {value: 100, color: ColorRGBA(255, 255, 0)},
                    {value: 150, color: ColorRGBA(255, 0, 0)},
                ],
            }),
        }),
    )

LightningChart JS provides the data in JSON for format. The below code is a Fetching example data from a JSON Asset.

fetch (document.head.baseURI + 'examples/assets/0019/flowCytometryChart-data.json')
    . then((r) => r.json())
    . then((data) => {
        
        const columns = data.data.length
        const rows = data.data[0]. length

        const pxLocationAxisStart = translatePoint(
            {x: axisX.getInterval(). start, y: axisY.getInterval(). start},
            {x: axisX, y: axisY },
            chart.engine.scale,
        )
        const pxLocationAxisEnd = translatePoint(
            {x: axisX.getInterval(). end, y: axisY.getInterval(). end},
            {x: axisX, y: axisY },
            chart.engine.scale,
        )
        const pxAxisSize = {
            x: Math.ceil(pxLocationAxisEnd.x - pxLocationAxisStart.x),
            y: Math.ceil(pxLocationAxisEnd.y - pxLocationAxisStart.y),
        }

        const pointSize = 2
        const horizontalPadding = Math.max(pxAxisSize.x - columns * pointSize, 0)
        const verticalPadding = Math.max(pxAxisSize.y - rows * pointSize, 0)
        chart.setPadding({
            left: horizontalPadding / 2,
            right: horizontalPadding / 2,
            top: verticalPadding / 2,
            bottom: verticalPadding / 2,
        })
        const points = []
        data.data.forEach((column, iColumn) => {
            column.forEach((sample, iRow) => {
                if (! sample) return
                points.push({
                    x: data.x.start + (iColumn * (data.x.end - data.x.start)) / data.data.length,
                    y: data.y.start + (iRow * (data.y.end - data.y.start)) / data.data[0]. length,
                    value: sample,
                })
            })
        })
        pointSeries.add(points)
    })

Final Output:



This post first appeared on Arction Ltd - Webgl Charts Library, please read the originial post: here

Share the post

React Scatter Charts

×

Subscribe to Arction Ltd - Webgl Charts Library

Get updates delivered right to your inbox!

Thank you for your subscription

×