Building a Recharts Dashboard with Cube
Adnan Rahić
Posted on March 31, 2022
This guest post was written by Julien Bras. He's an Innovation Team Leader at @Wiiisdom. You can get in touch with him through his website or Twitter.
Great job, developer. You’ve nearly finished your first major React-based project for that new customer.
But now you’re asked to add a dashboard to show sales revenues or user retention percentage. You know it will take you weeks with traditional methods—computing the data to share, building an endpoint to expose the right data, handling it on the front-end side, presenting it correctly, tweaking the metrics. Isn’t there a more straightforward way?
Yes, there is.
This tutorial will show you how to build a dashboard using Recharts, a React library that offers you a set of chart components to speed up the creation of a dashboard, and Cube, a Headless BI tool that allows you to expose your application database via a set of APIs. The combination will allow you to play with your data and simply copy/paste the generated dashboard code content to your React application.
Here is the expected result of this tutorial:
Introducing Cube
Cube positions itself as “Headless BI for building
data applications.” The tool acts as a bridge between the data that is stored, generally in a database (PostgreSQL, MySQL, etc.), and your front-end application that is consuming an API.
Cube is available in two flavors: an open-source product, generally named Cube.js, which you must host yourself; and Cube Cloud, an enterprise-ready service with high availability and scalability. Both options provide the same features.
Introducing Recharts
Recharts is a React library designed to help you create nice charts. By providing an expanded set of pre-existing charts, it allows you to present data in the way you need.
Let’s take the following piece of code, where data
is a simple JavaScript array containing the data:
<BarChart width={730} height={250} data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="pv" fill="#8884d8" />
<Bar dataKey="uv" fill="#82ca9d" />
</BarChart>
It will be shown like this:
Recharts is a very common solution since it integrates easily in your React environment via the multiple components available. It’s also very customizable to match your requirements: color, style, chart type, etc. You can also specify how to label content, define axis organization, choose the correct shape, and so forth
But because it’s just a front-end library, it needs a {data}
object with all the content shown on the chart. It’s obvious, but it can be complex to produce this information, for example, if the application is relying on a traditional back end with a classic database system like PostgreSQL or MySQL.
There are also other options for rendering charts on a web application:
- Charts.js is a popular solution, but it’s not a React library so you may need to rely on third-party integrations like this one.
- D3 is also a classic option, but it’s generally much more complex to integrate D3 into a React application, because both libraries will try to access the document object model (DOM).
In this tutorial, you’ll combine Cube and Recharts. The good news is that Cube supports out-of-the-box Recharts as a charting engine, saving you a lot of time when it’s time to write code.
Build a Recharts Dashboard with React and Cube
Let’s build the dashboard!
To reproduce the results here, use a sample database available online. You’ll use the MySQL Employee Sample Database. Based on this data, you will build charts to highlight useful metrics:
- Number of employees per department, gender, birth date, etc.
- Average salary per department, gender, hire date, etc.
Prerequisites
You need to have docker
and docker-compose
to use the open-source version of Cube. Since you will spin-up a local MySQL database containing the sample data, you will use Docker to start both a MySQL container and a Cube container. You also need to have node
and npm
installed to create the React application for the dashboard.
With that in place, we can begin.
Start Cube
To start, you’ll follow the docker-compose steps.
In an empty new folder named cube
, create a docker-compose.yml
file:
version: '2.2'
services:
cube:
image: cubejs/cube:latest
ports:
- 4000:4000
environment:
- CUBEJS_DEV_MODE=true
volumes:
- .:/cube/conf
database:
image: genschsa/mysql-employees
environment:
- MYSQL_ROOT_PASSWORD=pass
It will allow you to define the two containers needed:
-
cubejs/cube
is obviously the Cube image (started in development modeCUBEJS_DEV_MODE=true
to use the playground, which you’ll see later) -
genschsa/mysql-employees
is a MySQL server image with the employee sample database already loaded
Then, run the following to start Cube with the database:
docker-compose up
Both containers will start up and will be able to communicate with each other.
Start Cube via Cube Cloud
If you want to use Cube Cloud instead, the process is easier than using Docker. The free-tier is generous for testing the SaaS solution.
From Cube Cloud, log in, for example by using your GitHub account.
Then create a deployment:
You can either import an existing project from GitHub, or create a new project from scratch:
Connect to the Database
Let’s roll back to the local deployment. Once the containers are up and running, you’ll be able to connect to http://localhost:4000
via any browser.
The first task is to connect to the database where your data is located. In your case, you need to connect to the employee sample data. So first select MySQL, then configure the connection:
- Hostname:
database
- Port:
3306
- Database:
employees
- Username:
root
- Password:
pass
(Side note: the root
password is set in the docker-compose.yml
file as pass
. Yes, it’s a local deployment. It should not be shipped to your production environment.)
An .env
file is generated after this step to store the database credential information.
Generate a Schema
The important next step is to generate a schema of your database. It will define the API for later interaction.
Select the tables as shown in the screenshot below and click on Generate Schema.
It will create a set of JavaScript files located in the schema/
folder, next to your docker-compose.yml
file. Each file describes how to use each table of your database, that is, which fields can be used as a metric (number of employees), a dimension (department name), or what links can be done between tables. The dedicated section of the documentation is a good starting point to get a good foundation of schema in Cube.
Make sure to replace the generated files with the one you can find in the GitHub repository for this tutorial. The files here have been carefully designed to let Cube work well with this particular database.
Start Playing With Your Data
Once your schema is available, you can start experimenting and build your app.
For example, go to the Build section of the app. Select Employee Count
as the measure, and Departments Name
as the dimensions, and keep the Segment, Time and Filters empty. Use a Bar chart instead of Line and click on Run in the middle of the screen. You will see this kind of chart:
Take some time to play with this interface. It’s called the playground, after all, so experiment with your data. You can explore measures and dimensions as well as chart styles.
You can also define the chart engine for your output. In our case, we want to select first React then Recharts.
You can also switch between the following:
- Chart renders a test chart.
- JSON Query shows the JSON data sent to the Cube API.
- GraphiQL shows the equivalent information if you want to use the GraphiQL Cube API.
- Code generates the code for the current selected engine. (We will use it shortly.)
- SQL shows the exact SQL query sent to the database engine.
The screenshot below is of the code screen:
This code can be copy-pasted to any React stack app to include the current element of the playground (in our case, a Recharts chart that is built based on the Cube API). If you scroll down, you’ll see the Cube API information:
const cubejsApi = cubejs(
'APIKEY',
{ apiUrl: 'http://localhost:4000/cubejs-api/v1' }
);
Here is the query that is sent to the Cube engine:
query={{
"measures": [
"Employees.count"
],
"timeDimensions": [],
"order": {
"Employees.count": "desc"
},
"filters": [],
"dimensions": [
"Departments.Name"
]
}}
And also the graph component from Recharts:
return (
<CartesianChart resultSet={resultSet} ChartComponent={BarChart}>
{resultSet.seriesNames().map((series, i) => (
<Bar
key={series.key}
stackId="a"
dataKey={series.key}
name={series.title}
fill={colors[i]}
/>
))}
</CartesianChart>
This code saves you hours during dashboard coding. You simply have to organize the elements on the page correctly and define a set of environment variables (Cube API URL, Cube API Token) to have a production-ready dashboard.
Build Your Recharts Dashboard
The goal of this section is to integrate the various elements generated from the Cube playground into a React application.
Create a new React application using the Create React App starter:
npx create-react-app react-app
Add some needed libraries (Recharts for charting, CubeJs for connecting to Cube API, AntD for styling, Use Deep Compare for a React Hook used by the code produced by Cube):
cd react-app
npm add @cubejs-client/core @cubejs-client/react antd use-deep-compare recharts
Start your development server:
npm start
Copy-paste the content of the code screen of your first query in a new file in src/charts/EmployeesPerDept.js
Remove the last two lines at the end of the file:
const rootElement = document.getElementById('root');
ReactDOM.render(<ChartRenderer />, rootElement);
Replace the removed code with a classic component export to declare the chart as a React functional component that can be used in the main src/App.js
file:
export default ChartRenderer;
Now, modify the src/App.js
:
import EmployeesPerDept from "./charts/EmployeesPerDept";
function App() {
return (
<div className="App">
<EmployeesPerDept />
</div>
);
}
export default App;
If you followed all the steps, you should have the chart below on your development server:
You’re welcome to explore this tutorial’s GitHub repository containing the schema for the Cube application (under cube/
) and the final React application (under react-app/
). It contains the Recharts dashboard with the multiple charts you saw at the start of this tutorial.
Learn More
If you want to learn more about Cube and Recharts, start by working on query acceleration. It allows you to speed up the execution of the query by adding pre-aggregation.
There is also a prebuilt Dashboard App that allows you to build your React app directly based on popular templates:
You can use the Add to Dashboard button to add any query built via the playground directly. It’s even quicker than the process described in this tutorial.
What Have You Learned Today?
At first, building a custom dashboard integrated into a React application seems like a complex task. But with the right tools, it can be as simple as deciding what to show as a metric and how to present it. The Cube playground handles all the complexity without limiting you to its default values. You can explore the Cube API documentation and the Recharts API documentation to understand how to customize the generated code.
If your project is dealing with analytics, it’s worth trying Cube. Don’t hesitate to ping the team on their Slack channel. They’re very responsive and helpful, especially if you’re a new player.
Posted on March 31, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 14, 2024