Bar Chart with React

Radzion
5 min readJan 2, 2019

--

In this story, we are going to make React component that will be available as an NPM module so we can reuse it in different projects. We will cover a lot of concepts here, and you find this story useful if you think about creating a chart component or build a library. All code you can find in the repository.

increaser-chart by Increaser.

Plan

First, we are going to bootstrap the project and create the specification for our library. Then we will implement the demo page that will show the functionality of our component and a function for test data generation. Ather that we can start the development of the bar chart. First, we will create a layout of the component. And then we will add bars, labels and custom scroll. Finally, we will deploy a demo page and publish an NPM module.

Project Setup

Create-react-app is a great tool for bootstrapping the front-end project, and I always use it for new ones. However, since we want to make an NPM module, we need a different starter. After some research, I found a tool, named create-react-library that using create-react-app to run the demo and rollup to build our library. To start a new project, we will type these commands:

$ npm install -g create-react-library
$ create-react-library increaser-charts
$ cd increaser-charts

After initializing our project, we will install the only additional library we will need.

$ npm install --save styled-components

And add additional fields in the rollup.config.js file.

...
external: ['styled-components'],
globals: { 'styled-components': 'styled' }
}

First, we will run rollup to watch our src module and automatically recompile it into dist whenever we make changes.

$ npm start

The second part will be running the example create-react-app that’s linked to the local version of our module. In another tab:

$ cd example
$ npm start

Specification

You may notice that when you are using third-party React components your code editor autofill names of parameters, and you can go to the definition of a component to see properties and their types. This happening because most of libraries export file with declarations. Let’s also create one.

To make this file be published on NPM together with the code, we need to edit package.json.

{
...
"typings": "./index.d.ts",
"files": ["dist", "index.d.ts"],
...
}

With this file in place, when we are using the library, we are going to see hint like this.

when typing properties

Demo Page

When we are using create-react-library, we have two projects. One with demo page that we are using for development of our component and other is library itself. First, we are going to develop a demo page with all parameters available to change in UI, so that we can comfortably develop and test our library.

Demo page will have a container for chart and panel where we can change parameters of the library. To change them we need two components: Switch for boolean parameters, and Slider for parameters such as bar width and space. And since they only required for demo page, we will install material-ui in the demo project.

$ cd example
$ npm install --save @material-ui/core @material-ui/lib

Generating Mock Data

In the constructor of the demo page and on change of some parameters we will create mock data. The function will receive the number of bars we want to generate and should they include a label or not. To define the height of the bar we will use a function, that will return normally distributed random number.

BarChart Layout

We will start development of BarChart by creating the basic layout of the component. Let’s start with index.js. At the root component, we are rendering DataContainer that contains Bars and Labels and Scroller container. Before rendering them, we need to take the width of the root container since this value required for Bars, Labels, and Scroller.

Bars and labels will be placed absolutely inside of DataContainer. The important point is that we render only part of data that will be visible to a user.

Check this commit to see all changes.

Bars

We will use SVG to render bars. This way each bar will be represented as a rect element with an appropriate color.

Now, having Bar component, we can update index.js. We will add code to render bars and to calculate new offset that used for animation we will add getDerivedStateFromProps method.

Check this commit to see all changes.

Labels

Before rendering labels, we will check that bars have at least one label. If there are some labels, we will place them each one right under the appropriate bar. If we are selecting some bar, we will change its styles appropriately.

Check this commit to see all changes.

Scroller

The last feature we will have in the library is Scroller. This element will show which part of the bars currently viewed. Also, we can use it to scroll bars. When user mouseDown on scroll we will call appropriate action and then we will watch for document mouseUp event to tell root component about changes on x. Then in root component, we will apply logic to change offset and therefore change the position of both scroll and bars.

Final index.js:

Check this commit to see all changes.

Conclusion

Now we can deploy our library to NPM and demo to GitHub pages by typing these commands:

$ npm publish --access-public
$ npm run deploy

I already integrated this chart in my app — increaser.org, and it looks like this:

Reach the next level of focus and productivity with increaser.org.

Increaser

--

--