Implementation Of amCharts In React

Introduction

 
What is React?

ReactJs is bascially an open-source JavaScript library, used to build user interfaces for specific applications on a single page. It is used for web and mobile app view layer management. We can also create reusable components of the UI in react.

NOTE: ReactJS is only a frontend library and not the whole framework, which deals with the View component of MVC (Model – View – Controller).
ReactJS was developed by Jordan Walke, a software engineer working at Facebook. Facebook implemented ReactJS in 2011 in its newsfeed section, but it was released to the public in May 2013. After the implementation of ReactJS, Facebook’s UI underwent drastic improvement. This resulted in satisfied users and a sudden boost in its popularity.  

Features

    One-way data binding with props:

     Properties (props) are passed to a component as an attribute from parent component.  
  1. function Welcome(props) {  
  2.   return <h1>Hello, {props.name}</h1>;  
  3. }  
   States in components
   States hold values throughout the component and can be passed to child components through props: 
  1. class ParentComponent extends React.Component {  
  2.   state = { color: 'green' };  
  3.   render() {  
  4.     return (  
  5.       <ChildComponent color={this.state.color} />  
  6.     );  
  7.   }  
  8. }  
    Virtual DOM
   
The "virtual Document Object Model" or "virtual DOM" is another notable feature. React creates a cache for the data structure in the memory, calculates the resulting differences and then effectively updates the browser's DOM. This enables the programmer to write code as if the page is displayed as a whole for each change, while the React libraries only make changes in subcomponents.
 

    Testability

React views can be used as functions of the state (state is an object which determines how a component will render and behave). Thus, we can easily manipulate with state of the components which we pass to the ReactJS view and take a look at the output and triggered actions, events, functions, etc. This makes React applications quite easy to test and debug
      

BENEFITS

  1. Single Page Application.
  2. Entire page remains same but only few components change.
  3. Code is easy to scale and maintain.
  4. More functionalities as HTML is created from JS
  5. Isomorphic Rendering(Server side rendering)
  6. Blazing speed

What is amCharts?

A go-to library for data visualization. You can use amCharts if you need a simple yet powerful and flexible drop-in data visualization solution. amCharts 4 includes both charts and geographical maps.

Benefits of Charts over Grid

  1. Increasing precision when graphs are large.
  2. Enhancing the perception of small differences.
  3. Assisting the comparison of values along the categorical scale.
  4. Narrowing the focus to a specific area. 

Final Output

Implementation of amCharts in React
 
Live Preview With Code
 
https://codesandbox.io/s/km8kwx0ylv
 

Implementation

 
Create a React app

To create a React app you must have Node 8.10.0 or later installed on your local machine.

You can download Node.Js from here ( https://nodejs.org/en/download/current/ )
 
To create a new app, you have to run one of the following commands:
  1. npx create-react-app my-app  
OR
  1. npm init react-app my-app  
OR
  1. yarn create react-app my-app  
After creating your app, you have to run the following commands:
  1. cd chartapp    
  2.     
  3. npm install    
  4.     
  5. npm start    

Install amCharts

  1. npm install @amcharts/amcharts4   

Create Data Source

In this example I have used .JSX file that exports data for our chart, you can use Web API, JSON File or any other data source.

In this data source, I have created a const variable named SalesData, which is exported as a default. We will use this variable in our Chart component.
  1. const SalesData = [{  
  2.     "date""2013-01-16",  
  3.     "market1": 71,  
  4.     "market2": 75,  
  5.     "sales1": 5,  
  6.     "sales2": 8  
  7. }, {  
  8.     "date""2013-01-17",  
  9.     "market1": 74,  
  10.     "market2": 78,  
  11.     "sales1": 4,  
  12.     "sales2": 6  
  13. }, {  
  14.     "date""2013-01-18",  
  15.     "market1": 78,  
  16.     "market2": 88,  
  17.     "sales1": 5,  
  18.     "sales2": 2  
  19. }, {  
  20.     "date""2013-01-19",  
  21.     "market1": 85,  
  22.     "market2": 89,  
  23.     "sales1": 8,  
  24.     "sales2": 9  
  25. }, {  
  26.     "date""2013-01-20",  
  27.     "market1": 82,  
  28.     "market2": 89,  
  29.     "sales1": 9,  
  30.     "sales2": 6  
  31. }, {  
  32.     "date""2013-01-21",  
  33.     "market1": 83,  
  34.     "market2": 85,  
  35.     "sales1": 3,  
  36.     "sales2": 5  
  37. }, {  
  38.     "date""2013-01-22",  
  39.     "market1": 88,  
  40.     "market2": 92,  
  41.     "sales1": 5,  
  42.     "sales2": 7  
  43. }, {  
  44.     "date""2013-01-23",  
  45.     "market1": 85,  
  46.     "market2": 90,  
  47.     "sales1": 7,  
  48.     "sales2": 6  
  49. }, {  
  50.     "date""2013-01-24",  
  51.     "market1": 85,  
  52.     "market2": 91,  
  53.     "sales1": 9,  
  54.     "sales2": 5  
  55. }, {  
  56.     "date""2013-01-25",  
  57.     "market1": 80,  
  58.     "market2": 84,  
  59.     "sales1": 5,  
  60.     "sales2": 8  
  61. }, {  
  62.     "date""2013-01-26",  
  63.     "market1": 87,  
  64.     "market2": 92,  
  65.     "sales1": 4,  
  66.     "sales2": 8  
  67. }, {  
  68.     "date""2013-01-27",  
  69.     "market1": 84,  
  70.     "market2": 87,  
  71.     "sales1": 3,  
  72.     "sales2": 4  
  73. }, {  
  74.     "date""2013-01-28",  
  75.     "market1": 83,  
  76.     "market2": 88,  
  77.     "sales1": 5,  
  78.     "sales2": 7  
  79. }, {  
  80.     "date""2013-01-29",  
  81.     "market1": 84,  
  82.     "market2": 87,  
  83.     "sales1": 5,  
  84.     "sales2": 8  
  85. }, {  
  86.     "date""2013-01-30",  
  87.     "market1": 81,  
  88.     "market2": 85,  
  89.     "sales1": 4,  
  90.     "sales2": 7  
  91. }]  
  92. export default SalesData;  

Create a Component for Chart

Create a Component for Sales Chart. It’s good to use separate folder for Charts, Components, Forms, Etc. For code structure.

First, we have to import amCharts libraries in our component.
  1. import * as am4core from "@amcharts/amcharts4/core";    
  2. import * as am4charts from "@amcharts/amcharts4/charts";    
  3. import am4themes_animated from "@amcharts/amcharts4/themes/animated";   

Second, we have to import data for our chart in our component. Path varies based on where you have created your data source.

  1. import SalesData from '../../Data/SalesData'   
Third, create chart and add data.
 
componentDidMount() is a lifecycle method, which calls after the component loads. In the code example below we have set the theme, creating chart and setting datasource.
 
am4core.useTheme() Themes in amCharts 4 are much more than just collections of appearance settings. They can change the way a chart acts, looks, and even modify and create chart objects. Plus, you can apply several themes to a single chart such as Material, Dark, Frozen etc. 
 
am4core.create() is a function to create chart, we have to pass id of the div in which chart will render as a first parameter, and type of chart as a second parameter. In this example I have used XYChart but you can use other chart as well like Pie Chart, Map Chart, Radar Chart, TreeMap and Gauge Chart. 
 
chart.data "data" is a property of amCharts in which we assign a varible that holds data. It can be an array or json or object based on the type of charts you have used.
 
  1. componentDidMount() {        
  2.         
  3.         // Use theme    
  4.         am4core.useTheme(am4themes_animated);        
  5.               
  6.         // Create Chart    
  7.         let chart = am4core.create("SalesChart", am4charts.XYChart);  // here Saleschart is the ID of a div       
  8.         
  9.         // Add data        
  10.         chart.data = SalesData;       
  11. }  
Fourth, Define Series, Axes, Cursor, Legend and Scrollbar. 
 
chart.xAxes.push(new am4charts.DateAxis()); To create a X-Axis of Date Type.
chart.yAxes.push(new am4charts.ValueAxis()); To create Y-Axis  of Value type. You can create multiple Y-Axis as well for each series.
 
chart.series.push(new am4charts.ColumnSeries()); To create a column series; for example, target sales in the current example.
 
chart.series.push(new am4charts.LineSeries()); To create a line series like "Market Days" in the current example
 
Finally the complete component will look like this.
  1. import React, { Component } from 'react'  
  2. import * as am4core from "@amcharts/amcharts4/core";  
  3. import * as am4charts from "@amcharts/amcharts4/charts";  
  4. import am4themes_animated from "@amcharts/amcharts4/themes/animated";  
  5. import SalesData from '../../Data/SalesData'  
  6.   
  7. export default class Sales extends Component {  
  8.   
  9.     componentDidMount() {  
  10.   
  11.         am4core.useTheme(am4themes_animated);  
  12.   
  13.         let chart = am4core.create("SalesChart", am4charts.XYChart);  
  14.   
  15.         // Add data  
  16.         chart.data = SalesData;  
  17.   
  18.         // Create axes  
  19.         let dateAxis = chart.xAxes.push(new am4charts.DateAxis());  
  20.         //dateAxis.renderer.grid.template.location = 0;  
  21.         //dateAxis.renderer.minGridDistance = 30;  
  22.   
  23.         let valueAxis1 = chart.yAxes.push(new am4charts.ValueAxis());  
  24.         valueAxis1.title.text = "Sales";  
  25.   
  26.         let valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());  
  27.         valueAxis2.title.text = "Market Days";  
  28.         valueAxis2.renderer.opposite = true;  
  29.         valueAxis2.renderer.grid.template.disabled = true;  
  30.   
  31.         // Create series  
  32.         let series1 = chart.series.push(new am4charts.ColumnSeries());  
  33.         series1.dataFields.valueY = "sales1";  
  34.         series1.dataFields.dateX = "date";  
  35.         series1.yAxis = valueAxis1;  
  36.         series1.name = "Target Sales";  
  37.         series1.tooltipText = "{name}\n[bold font-size: 20]${valueY}M[/]";  
  38.         series1.fill = chart.colors.getIndex(0);  
  39.         series1.strokeWidth = 0;  
  40.         series1.clustered = false;  
  41.         series1.columns.template.width = am4core.percent(40);  
  42.   
  43.         let series2 = chart.series.push(new am4charts.ColumnSeries());  
  44.         series2.dataFields.valueY = "sales2";  
  45.         series2.dataFields.dateX = "date";  
  46.         series2.yAxis = valueAxis1;  
  47.         series2.name = "Actual Sales";  
  48.         series2.tooltipText = "{name}\n[bold font-size: 20]${valueY}M[/]";  
  49.         series2.fill = chart.colors.getIndex(0).lighten(0.5);  
  50.         series2.strokeWidth = 0;  
  51.         series2.clustered = false;  
  52.         series2.toBack();  
  53.   
  54.         let series3 = chart.series.push(new am4charts.LineSeries());  
  55.         series3.dataFields.valueY = "market1";  
  56.         series3.dataFields.dateX = "date";  
  57.         series3.name = "Market Days";  
  58.         series3.strokeWidth = 2;  
  59.         series3.tensionX = 0.7;  
  60.         series3.yAxis = valueAxis2;  
  61.         series3.tooltipText = "{name}\n[bold font-size: 20]{valueY}[/]";  
  62.   
  63.         let bullet3 = series3.bullets.push(new am4charts.CircleBullet());  
  64.         bullet3.circle.radius = 3;  
  65.         bullet3.circle.strokeWidth = 2;  
  66.         bullet3.circle.fill = am4core.color("#fff");  
  67.   
  68.         let series4 = chart.series.push(new am4charts.LineSeries());  
  69.         series4.dataFields.valueY = "market2";  
  70.         series4.dataFields.dateX = "date";  
  71.         series4.name = "Market Days ALL";  
  72.         series4.strokeWidth = 2;  
  73.         series4.tensionX = 0.7;  
  74.         series4.yAxis = valueAxis2;  
  75.         series4.tooltipText = "{name}\n[bold font-size: 20]{valueY}[/]";  
  76.         series4.stroke = chart.colors.getIndex(0).lighten(0.5);  
  77.         series4.strokeDasharray = "3,3";  
  78.   
  79.         let bullet4 = series4.bullets.push(new am4charts.CircleBullet());  
  80.         bullet4.circle.radius = 3;  
  81.         bullet4.circle.strokeWidth = 2;  
  82.         bullet4.circle.fill = am4core.color("#fff");  
  83.   
  84.         // Add cursor  
  85.         chart.cursor = new am4charts.XYCursor();  
  86.   
  87.         // Add legend  
  88.         chart.legend = new am4charts.Legend();  
  89.         chart.legend.position = "top";  
  90.   
  91.         // Add scrollbar  
  92.         chart.scrollbarX = new am4charts.XYChartScrollbar();  
  93.         chart.scrollbarX.series.push(series1);  
  94.         chart.scrollbarX.series.push(series3);  
  95.         chart.scrollbarX.parent = chart.bottomAxesContainer;  
  96.   
  97.         this.chart = chart;  
  98.     }  
  99.   
  100.     componentWillUnmount() {  
  101.         if (this.chart) {  
  102.             this.chart.dispose();  
  103.         }  
  104.     }  
  105.     render() {  
  106.         return (  
  107.             <div>  
  108.                 <div id="SalesChart" style={{ width: "100%", height: "500px" }}></div>  
  109.             </div>  
  110.         )  
  111.     }  
  112. }  

Import Chart Component on Your Page,

  1. import React, { Component } from 'react';  
  2. import logo from './logo.svg';  
  3. import './App.css';  
  4. import SalesChart from './Components/Charts/Sales';  
  5.   
  6. class App extends Component {  
  7.   render() {  
  8.     return (  
  9.       <div className="App">  
  10.         <header className="App-header">  
  11.           <img src={logo} className="App-logo" alt="logo" width="200" height="200" />  
  12.           <SalesChart />  
  13.         </header>  
  14.       </div>  
  15.     );  
  16.   }  
  17. }  
  18.   
  19. export default App;