Angular 🅰️ is the web framework of choice for many professional developers. According to Stack Overflow Developer Survey 2020, only just about ~10 % of developers prefer React to Angular.
In this guide, we'll learn how to build a full-stack dashboard with KPIs, charts, and a data table. We'll go from data in the database to the interactive, filterable, and searchable dashboard.
We're going to use Cube for our analytics API. It removes all the hustle of building the API layer, generating SQL, and querying the database. It also provides many production-grade features like multi-level caching for optimal performance, multi-tenancy, security, and more.
Analytical API with Cube
We're going to build the dashboard for an e-commerce company that wants to track its overall performance and orders' statuses. Let's assume that the company keeps its data in an SQL database. So, in order to display that data on a dashboard, we're going to create an analytical API.
For that, we'll use the Cube command-line utility (CLI).
To create the API, we run this command:
Now we can download and import a sample e-commerce dataset for PostgreSQL:
Once the database is ready, the API can be configured to connect to the database. To do so, we provide a few options via the
.env file in the root of the Cube project folder (
Now we can run the API!
In development mode, the API will also run the Cube Playground. It's a time-saving web application that helps to create a data schema, test out the charts, and generate a React dashboard boilerplate. Run the following command in the Cube project folder:
$ npm run dev
Next, open http://localhost:4000 in your browser.
Cube can generate a simple data schema based on the database’s tables. If you already have a non-trivial set of tables in your database, consider using the data schema generation because it can save time.
For our API, we select the
users tables and click “Generate Schema.” As the result, we'll have 4 generated files in the
schema folder—one schema file per table.
Once the schema is generated, we can build sample charts via web UI. To do so, navigate to the “Build” tab and select some measures and dimensions from the schema.
Creating a complex dashboard from scratch usually takes time and effort. Fortunately, Angular provides a tool that helps to create an application boilerplate code with just a few commands. Adding the Material library and Cube as an analytical API is also very easy.
Installing the libraries
So, let's use Angular CLI and create the frontend application inside the
Congratulations! Now we have the
dashboard-app folder in our project. This folder contains the frontend code that we're going to modify and evolve to build our analytical dashboard.
Now it's time to add the Material library. To install the Material library to our application, run:
Choose a custom theme and the following options:
- Set up global Angular Material typography styles? - Yes
- Set up browser animations for Angular Material? - Yes
Great! We'll also need a charting library to add charts to the dashboard. Chart.js is the most popular charting library, it's stable and feature-rich. So...
It's time to add the Chart.js library. To install it, run:
Also, to be able to make use of
ng2-charts directives in our Angular application we need to import
ChartsModule. For that, we add the following import statement in the
The second step is to add
ChartsModule to the imports array of the
@NgModule decorator as well:
Finally, it's time to add Cube. This is the final step that will let our application access the data in our database via an analytical API is to install Cube client libraries for Angular. Run:
Now we can add
CubejsClientModule to your
CubejsClient which you can inject into your components or services to make API calls and retrieve data:
So far so good! Let's make it live.
Creating the first chart
Let's create a generic
bar-chart component using Angular CLI. Run:
This command will add four new files to our app because this is what Angular uses for its components:
bar-chart.component.html and replace the content of that file with the following code:
Here we’re using the
baseChart directive which is added to a canvas element. Furthermore, the
chartType attributes are bound to class members which are added to the implementation of the
BarChartComponent class in
Okay, we have the code for our chart, let's show it in the app. We can use an Angular command to generate a base grid. Run:
So, now we have a folder with the
dashboard-page component. Open
app.component.html and insert this code:
Now it's time to open
dashboard-page/dashboard-page.component.html and add our component like this:
And the last edit will be in
Nice work! 🎉 That's all we need to display our first chart with the data loaded from Postgres via Cube.
In the next part, we'll make this chart interactive by letting users change the date range from "This year" to other predefined values.
Interactive Dashboard with Multiple Charts
In the previous part, we've created an analytical API and a basic dashboard with the first chart. Now we're going to expand the dashboard so it provides the view of key performance indicators of our e-commerce company.
Custom Date Range
As the first step, we'll let users change the date range of the existing chart.
For that, we'll need to make a change to the
And another one to the
Well done! 🎉 Here's what our dashboard application looks like:
The KPI chart can be used to display business indicators that provide information about the current performance of our e-commerce company. The chart will consist of a grid of tiles, where each tile will display a single numeric KPI value for a certain category.
First, let's add the
countUp package to add the count-up animation to the values on the KPI chart. Run the following command in the dashboard-app folder:
We weed to import these modules:
Second, let's add an array of cards we're going to display to the
The next step is create the KPI Card component. Run:
Edit this component's code:
And the component's template:
The final step is to add this component to our dashboard page. To do so, open
dashboard-page.component.html and replace the code:
The only thing left is to adjust the Cube schema. While doing it, we'll learn an important aspect of Cube...
Let's learn how to create custom measures in the data schema and display their values. In the e-commerce business, it's crucial to know the share of completed orders. To enable our users to monitor this metric, we'll want to display it on the KPI chart. So, we will modify the data schema by adding a custom measure (
percentOfCompletedOrders) which will calculate the share based on another measure (
Let's customize the "Orders" schema. Open the
schema/Orders.js file in the root folder of the Cube project and make the following changes:
- add the
- add the
Great! 🎉 Now our dashboard has a row of nice and informative KPI metrics:
Now, using the KPI chart, our users are able to monitor the share of completed orders. However, there are two more kinds of orders: "processed" orders (ones that were acknowledged but not yet shipped) and "shipped" orders (essentially, ones that were taken for delivery but not yet completed).
To enable our users to monitor all these kinds of orders, we'll want to add one final chart to our dashboard. It's best to use the Doughnut chart for that, because it's quite useful to visualize the distribution of a certain metric between several states (e.g., all kinds of orders).
First, let's create the
DoughnutChart component. Run:
Then edit the
And the template in the
The next step is to add this card to the
And the last step is to use this template in the
Awesome! 🎉 Now the first page of our dashboard is complete:
Multi-Page Dashboard with Data Table
Now we have a single-page dashboard that displays aggregated business metrics and provides at-a-glance view of several KPIs. However, there's no way to get information about a particular order or a range of orders.
We're going to fix it by adding a second page to our dashboard with the information about all orders. However, we'll need a way to navigate between two pages. So, let's add a navigation side bar.
Navigation Side Bar
Now we need a router, so let's add a module for this. Run:
And then edit the
Now we need to add new modules to the
The last step is to set the
app.component.html file to this code:
To make everything finally work, let's add links to our
Wow! 🎉 Here's our navigation side bar which can be used to switch between different pages of the dashboard:
Data Table for Orders
To fetch data for the Data Table, we'll need to customize the data schema and define a number of new metrics: amount of items in an order (its size), an order's price, and a user's full name.
First, let's add the full name in the "Users" schema in the
Then, let's add other measures to the "Orders" schema in the
For these measures, we're going to use the subquery feature of Cube. You can use subquery dimensions to reference measures from other cubes inside a dimension. Here's how to defined such dimensions:
Now we're ready to add a new page. Let's creating the
table-page component. Run:
And set the template to these contents:
Note that this component contains a Cube query. Later, we'll modify this query to enable the filtering of the data.
Also, let's create the
material-table component. Run:
Add it to the
And edit the
Then set its template to these contents:
Time to add pagination!
Again, let's add modules to
Then, let's edit the template:
And the component:
The last edits will be to the
And the related template:
Voila! 🎉 Now we have a table which displays information about all orders:
However, its hard to explore this orders using only the controls provided. To fix this, we'll add a comprehensive toolbar with filters and make our table interactive.
For this, let's create the
table-filters component. Run:
Set the module contents:
And the template...
The last step will be to add it to the
Perfect! 🎉 Now the data table has a filter which switches between different types of orders:
However, orders have other parameters such as price and dates. Let's create filters for these parameters and enable sorting in the table.
And its template:
Again, add plenty of modules to the
Now we need to propagate the changes to the
And its template:
Wonderful! 🎉 Now we have the data table that fully supports filtering and sorting:
And that's all! 😇 Congratulations on completing this guide! 🎉
Now you should be able to create comprehensive analytical dashboards powered by Cube using Angular and Material to display aggregate metrics and detailed information.