How To Implement Line Chart Using Vega In React

Introduction

This article demonstrates how to create and use a line chart using vega in reactjs. This article starts with the introduction of the react-vega package. After that, it demonstrates how vega json file works for creating any chart using its json formatted data.

What is Vega?

Vega is a visualization grammar, a declarative language for creating, saving, and sharing interactive visualization designs.With Vega, you can describe the visual appearance and interactive behavior of a visualization in a JSON format, and generate web-based views using Canvas or SVG.

Reference from: Vega

To achieve this feature we will use a npm package npm i react-vega. Using this you can modify the json file and create it according to your requirement.

Prerequisites

  • Basic knowledge of ReactJS
  • Visual Studio Code
  • Node and NPM installed

Step 1. Install NPM dependencies Create a React.js Project

Let's create a new React project by using the following command.

npx create-react-app react-linechart

Step 2. Install NPM dependencies

npm i react-vega

Step 3. Creating a Component

Now go to the src folder and create a new folder and inside in it create a component, 'line-chart.js'. Add the following code to this component.

import React, { useState } from "react";
import { Vega } from 'react-vega';
import "./_linechart.css";
import linecharttimeline from "./linecharttimeline.json";
import linechart180days from "./linechart180days.json";
import linechart30days from "./linechart30days.json";
import linechartLTM from "./linechartLTM.json";

const LineChart = () => {
  const [dateFormat, setdateFormat] = useState("%Y");
  const [stockPriceData, setstockPriceData] = useState(linecharttimeline);
  const stockPrice30Days = linechart30days;
  const stockPrice180Days = linechart180days;
  const stockPriceLTM = linechartLTM;
  const stockPrice=[
    {
      "name": "source_0",
      "values": stockPriceData
    },
    {
      "name": "data_0",
      "source": "source_0",
      "transform": [
        {"type": "formula", "expr": "toDate(datum[\"date\"])", "as": "date"}
      ]
    }
  ]

  const lineSpec ={
    "$schema": "https://vega.github.io/schema/vega/v5.json",
    "description": "Google's stock price over time.",
    "background": "#2e2e38",
    "padding": 5,
    "width": 700,
    "height": 240,
    "style": "cell",
    "data": stockPrice,
    "marks": [
      {
        "name": "pathgroup",
        "type": "group",
        "from": {
          "facet": {
            "name": "faceted_path_main",
            "data": "data_0",
            "groupby": ["status_mean"]
          }
        },
        "encode": {
          "update": {
            "width": {"field": {"group": "width"}},
            "height": {"field": {"group": "height"}}
            
          }
        },
        "marks": [
          {
            "name": "marks",
            "type": "line",
            "style": ["line"],
            "sort": {"field": "datum[\"date\"]"},
            "from": {"data": "faceted_path_main"},
            "encode": {
              "update": {
                 "tooltip": {"signal": "'Stock Price: '+datum.value+' '+(utcFormat(datum[\"date\"], '%d %b %Y'))"},
                "t":"",
                "stroke": {"scale": "color", "field": "status_mean"},
                "description": {
                  "signal": "\"date: \" + (utcFormat(datum[\"date\"], '%Y')) + \"; Price(USD): \" + (format(datum[\"value\"], \"\")) + \"; Stock Price: \" + (isValid(datum[\"status_mean\"]) ? datum[\"status_mean\"] : \"\"+datum[\"status_mean\"])"
                },
                "x": {"scale": "x", "field": "date"},
                "y": {"scale": "y", "field": "value"},
                "defined": {
                  "signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"value\"]) && isFinite(+datum[\"value\"])"
                }
              }
            }
          }
        ]
      }
    ],
    "scales": [
      {
        "name": "x",
        "type": "utc",
        "domain": {"data": "data_0", "field": "date"},
        "range": [0, {"signal": "width"}]
      },
      {
        "name": "y",
        "type": "linear",
        "domain": {"data": "data_0", "field": "value"},
        "range": [{"signal": "height"}, 0],
        "nice": true,
        "zero": false
      },
      {
        "name": "color",
        "type": "ordinal",
        "domain": {"data": "data_0", "field": "status_mean", "sort": true},
        "range": ["#ff736a"]
      }
    ],
    "axes": [
      {
        "scale": "y",
        "orient": "left",
        "gridScale": "x",
        "grid": true,
        "tickCount": {"signal": "ceil(height/40)"},
        "domain": false,
        "labels": false,
        "aria": false,
        "maxExtent": 0,
        "minExtent": 0,
        "ticks": false,
        "zindex": 0
      },
      {
        "scale": "x",
        "orient": "bottom",
        "grid": false,
        "domain": false,
        "format":dateFormat,
        "ticks": false,
        "labelFlush": true,
        "labelOverlap": true,
        "tickCount": {"signal": "ceil(width/60)"},
        "zindex": 0
      },
      {
        "scale": "y",
        "orient": "left",
        "grid": false,
        "title": "Price(USD)",
        "labelOverlap": true,
        "tickCount": {"signal": "ceil(height/60)"},
        "zindex": 0,
        "titleColor":"white"
      }
    ],
    "legends": [
      {"stroke": "color", "direction": "horizontal","titleOrient":"left","symbolFillColor":"#ff736a","labelColor":"#2e2e38","title":"Stock price","titleColor":"white","labelBaseline":"alphabetic" }
    ],
    "config": {
      "axis": {"labelColor": "white","domain": false, "grid": false, "ticks": false},
      "legend": {"title": "This is the Title","orient": "bottom", "symbolType": "circle"},
      "style": {"cell": {"stroke": null}}
    }
  }

  const onOptionChangeHandler = (event) => {
    setdateFormat(getLabelFormat(event.target.value));
  }
  
  const getLabelFormat = (chartMode) => {
    setstockPriceData([]);
    switch (chartMode) {
      case "30":
        setstockPriceData([...stockPrice30Days]);
        return "%m/%d";
      case "180":
        setstockPriceData([...stockPrice180Days]);
        return "%b %Y";
      case "LTM":
        setstockPriceData([...stockPriceLTM]);
        return "%b %Y";
      default:
        setstockPriceData([...stockPriceData]);
        return "%Y";
    }
  };
  return (
    <>
        <select onChange={onOptionChangeHandler} name="cars" id="cars">
            <option value="10Years">10 Years</option>
            <option value="30">30 Days</option>
            <option value="180">180 Days</option>
            <option value="LTM">LTM</option>
        </select>
        <Vega spec={lineSpec} actions={false}/>
    </>
        
  );
};

export default LineChart;

Step 3. Create a new component for a sortable list

Create a new JSON file, 'linecharttimeline.json'. Add the following code to this file.

[
  {"date": 1491177600000, "value": 65.55},
  {"date": 1424649600000, "value": 44.15},
  {"date": 1506902400000, "value": 74.61},
  {"date": 1552521600000, "value": 114.59},
  {"date": 1462838400000, "value": 51.02},
  {"date": 1389225600000, "value": 35.53},
  {"date": 1571270400000, "value": 139.69},
  {"date": 1434672000000, "value": 46.1},
  {"date": 1455235200000, "value": 50.5},
  {"date": 1460592000000, "value": 55.36},
  {"date": 1417564800000, "value": 48.08},
  {"date": 1634688000000, "value": 307.41},
  {"date": 1357862400000, "value": 26.83},
  {"date": 1398124800000, "value": 39.99},
  {"date": 1502928000000, "value": 72.4},
  {"date": 1519603200000, "value": 95.42},
  {"date": 1587945600000, "value": 174.05},
  {"date": 1570060800000, "value": 136.28},
  {"date": 1592870400000, "value": 201.91},
  {"date": 1424390400000, "value": 43.855},
  {"date": 1556755200000, "value": 126.21},
  
]

Step 4. Add the below code in App.js file

import './App.css';
import LineChart from './line-chart/linechart';

function App() {
  return (
    <LineChart/>
  );
}

export default App;

Step 5. Output

Now, run the project by using the 'npm start' command, and check the result.

implement line chart using Vega in React

implement line chart using Vega in React

implement line chart using Vega in React

Summary

In this article, we learned how to create a line chart using Vega library in ReactJS application.