Data visualization using React and Tremor - With Sample

Hello! Coding dashboards and data visualization layers might be a tedious activity for React developers (and not only). In order to simplify this task and focus more on the application logic and data processing, Tremor Library comes to the rescue. This article is an introduction to this open-source library using a coding-sample approach. During the article, we will code together a sample that uses GitHub API as a source of information and Tremor Charts for the presentation layer. Β Thank you!


Copyright Note: Project adapted for React & Tremor from Svelte Version crafted by Robert Soriano.

In the end, the product is able to accept any GitHub (valid) Username as input, pull the data from GitHub public API, and render a few charts as shown below:

React & Tremor Charts - Free SampleΒ 

In order to understand better the options we have using Tremor, let's take look at this free product crafted by TremorLabs.

✨ What is Tremor

Tremor is an open-source UI component library that enables React developers to create dashboards with speed. Its components are beautifully styled to provide a fully interactive user interface and a great user experience.

Developed by data scientists and software engineers with an eye for design and aesthetics, Tremor is loved by React developers worldwide.

In this tutorial, I'll walk you through how to add Tremor and visualize data with Tremor in a React application. Before then, let's learn why you should use Tremor.

React & Tremor Charts - Tremor Cover

Why should you use Tremor?

βœ… Beautifully styled UI components

Tremor provides various UI components which have been beautifully designed to enable you to build multiple UI layouts within a few minutes. It is built on top of the popular Tailwind CSS library to provide fully responsive and easily customizable UI components. With Tremor, you don't need to worry about aesthetics and responsiveness; the UI components have been professionally designed to respond to different screen sizes.

βœ… Fast and easiest data visualization library

Tremor is a fast and easy data visualization library for React developers. Within a few minutes of going through the documentation, you can create stunning dashboards and UI components with Tremor.

To create charts with Tremor, you just need to feed your data into the chart component, state your x and y-axes, and Tremor takes care of the rest.

βœ… Excellent documentation

Another reason why Tremor stands out is its documentation. Tremor has excellent documentation that is easy to use and navigate with detailed code samples.

The documentation describes each UI component, how to use them, and the various props required by the UI component; thus making it easy for new and existing users to explore and use the components easily.

βœ… Open-source

Tremor is constantly growing to provide more UI components such as charts, input, and other layout elements. It has a community of developers, data scientists, and talented contributors constantly maintaining and improving the library. As a developer or user, you are more than welcome to contribute to the growth of the library.


✨ Getting Started

A good way to fully understand concepts is to code something from scratch without reusing boilerplates or pre-coded layers. Just to follow up on this principle, our sample will be created via create-react-app and all configurations are manually done. Let's go!

πŸ‘‰ Create React codebase and integrate Tremor
$ npx create-react-app my-project
$ cd my-project 

Copy the code below to install Tremor.

$ npm install @tremor/react

Import the Tremor stylesheet into your `App.js` file as done below:

import '@tremor/react/dist/esm/tremor.css';

Once you've completed the steps above, you can start using Tremor. In the upcoming sections, I'll guide you through building a GitHub application that analyses and visualizes users' data via Tremor. The UI contains three pages: HOMEpage (expects input), charts page, and a simple error page.

React & Tremor Charts - HOMEpage

React & Tremor Charts - Charts

React & Tremor Charts - Error Page

Navigate into the `client/src` folder and create a components folder containing the `Home.js`, `UserProfile.js`, and `GitHubError.js` components.

The `Home` component is the application's homepage containing an input field that accepts the username from the user, the `UserProfile` component displays the user information, and the `GitHubError` component represents the error page.

cd src
mkdir components
touch Home.js UserProfile.js GitHubError.js 

Install React Router - a JavaScript library that enables us to navigate between pages in a React application and React Icons.

$ npm install react-router-dom react-icons

Copy the CSS styling for the application here.

Copy the code below into the `App.js` file. The code snippet below uses React Router for navigating between the web pages.

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import GithubError from "./components/GithubError";
import Home from "./components/Home";
import UserProfile from "./components/UserProfile";
import "@tremor/react/dist/esm/tremor.css";
 
const App = () => {
   return (
       <BrowserRouter>
           <Routes>
               <Route path='/' element={<Home />} />
               <Route path='/profile/:username' element={<UserProfile />} />
               <Route path='/error' element={<GithubError />} />
           </Routes>
       </BrowserRouter>
   );
};
 
export default App;

πŸ‘‰ The Home Component

Update the `Home.js` file to render an input field that accepts the users' GitHub username.

import React, { useState } from "react";
import { FaGithubAlt } from "react-icons/fa";
import { useNavigate } from "react-router-dom";
 
const Home = () => {
   const navigate = useNavigate();
   const [username, setUsername] = useState("");
 
   const handleSubmit = (e) => {
       e.preventDefault();
       //navigates the user to the dynamic route
       navigate(`/profile/${username}`);
       setUsername("");
   };
   return (
       <div className='home'>
           <form className='home__form' onSubmit={handleSubmit}>
               <FaGithubAlt className='githubIcon' />
               <label htmlFor='username'>Enter your GitHub username</label>
               <input
                   value={username}
                   onChange={(e) => setUsername(e.target.value)}
                   name='username'
                   id='username'
               />
           </form>
       </div>
   );
};
 
export default Home;
React & Tremor Charts - Input Component

πŸ‘‰ The GitHubError Component

This component is displayed when the username provided by the user does not exist on GitHub.

import React from "react";
import { Link } from "react-router-dom";
 
const GithubError = ({ error }) => {
   return (
       <main className='errorContainer'>
           <h2 style={{ color: "#fff" }}>Github User: {error || "Not Found"}</h2>
           <Link to='/'>Go back</Link>
       </main>
   );
};
 
export default GithubError;
React & Tremor Charts - Error Component

πŸ‘‰ The UserProfile component

The user's GitHub details are displayed within this component. Copy the code below into the `UserProfile.js` file:

import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import Header from "./Header";
import Charts from "./Charts";
import Section from "./Section";
 
const UserProfile = () => {
   const navigate = useNavigate();
   //πŸ‘‡πŸ» fetch the username from the URL
   const { username } = useParams();
   //πŸ‘‡πŸ» the required states
   const [loading, setLoading] = useState(true);
   const [userData, setUserData] = useState([]);
   const [error, setError] = useState(false);
 
   //πŸ‘‡πŸ» fetch the user details on page load
   useEffect(() => {
       function fetchGitHubUser() {
           fetch(`https://api.github.com/users/${username}`)
               .then((res) => res.json())
               .then((data) => {
                   if (data.message) {
                       setError(true);
                       setLoading(false);
                   } else {
                       setLoading(false);
                       setUserData(data);
                   }
               })
               .catch((err) => {
                   setError(true);
                   setLoading(false);
                   console.error(err);
               });
       }
       fetchGitHubUser();
   }, [username]);
 
   //πŸ‘‡πŸ» runs if the user data is loading
   if (loading) {
       return <div className='loading'>Loading...please wait</div>;
   } 

In case the API call returns an error, this case is managed by this code snippet:

   if (error) {
       return navigate("/error");
   }
   return (
       <div className='profile'>
           <Header data={userData} />
           <main className='main' style={{ padding: "30px" }}>
               <Charts />
               <Section />
           </main>
       </div>
   );
};
 
export default UserProfile;

From the code snippet, I imported three components - the Header, Charts, and Section components. Create the sub-components by running the code below:

touch Header.js Charts.js Section.js

πŸ‘‰ Β Coding the Header component
const Header = ({ data }) => {
   return (
       <header className='profile__header'>
           <nav className='profile__nav'>
               <h2>Coder Stats</h2>
               <div className='profile__links'>
                   <Link to='/' className='home__link'>
                       Home
                   </Link>
                   <a href='https://github.com' target='_blank' rel='noreferrer'>
                       GitHub
                   </a>
               </div>
           </nav>
           <Bio data={data} />
       </header>
   );
};
 
export default Header;

The Header component also contains a Bio component, create the component and copy the code below into the `Bio.js` file.

import React from "react";
import { IoLocationSharp } from "react-icons/io5";
import { FaCalendarAlt } from "react-icons/fa";
import { splitDate } from "../utils/requests";
 
const Bio = ({ data }) => {
   return (
       <div className='profile___section'>
           <img src={data.avatar_url} alt={data.name} className='profile__image' />
           <h1>{data.name}</h1>
           <a
               href={`https://github.com/${data.login}`}
               alt={data.name}
               className='profile__url'
               target='_blank'
               rel='noreferrer'
           >
               @{data.login}
           </a>
           <div className='profile__info'>
               <div style={{ display: "flex", marginRight: "30px", color: "#ddd" }}>
                   <IoLocationSharp />
                   <p>{data.location}</p>
               </div>
 
               <div style={{ display: "flex", color: "#ddd" }}>
                   <FaCalendarAlt style={{ marginRight: "5px" }} />
                   <p>{splitDate(data.created_at)}</p>
               </div>
           </div>
           <div className='profile__details'>
               <div>
                   <p className='profile__text'>{data.public_repos}</p>
                   <p style={{ color: "#21325e" }}>Repositories</p>
               </div>
               <div>
                   <p className='profile__text'>{data.followers}</p>
                   <p style={{ color: "#21325e" }}>Followers</p>
               </div>
               <div>
                   <p className='profile__text'>{data.following}</p>
                   <p style={{ color: "#21325e" }}>Following</p>
               </div>
           </div>
       </div>
   );
};
 
export default Bio;

From the code snippet above, we imported a `splitDate` function from a `utils` folder. Create a `requests.js` file within the `utils` folder and copy the code below into the file. It converts the date retrieved from GitHub to a readable format.

React & Tremor Charts - Profile Header for Facebook

πŸ‘‰ Β Coding the INFO Component

In this section, we'll display the user's top nine repositories, as shown in the image below:

React & Tremor Charts - Information Component

Within the `utils` folder, create a `langColors.js` file - containing an object containing different color tags for various programming languages.

export function fetchRepos(user, setVariable) {
   fetch(
       `https://api.github.com/users/${user}/repos?type=owner&sort=updated&per_page=100`
   )
       .then((res) => res.json())
       .then((data) => {
           const mostStarred = data.sort(
               (a, b) => b.stargazers_count - a.stargazers_count
           );
           setVariable(mostStarred.splice(0, 9));
       })
       .catch((err) => console.error(err));
} 

The code snippet above fetches the user's GitHub repositories, sorts the result according to the number of stars, and returns the top nine.

Import the `fetchRepos` function into the `UserProfile.js` file and display the list of repositories.

import React, { useEffect, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
 
//πŸ‘‡πŸ» Import fetchRepos function
import { fetchRepos } from "../utils/requests";
 
const UserProfile = () => {
   const { username } = useParams();
   //....other states and functions
 
   // states the holds all the repositories
   const [repos, setRepos] = useState([]);
 
   useEffect(() => {
       // fetch the repos if there is no error
       function authenticate() {
           if (!error) {
               fetchRepos(username, setRepos);
           }
       }
       authenticate();
   }, [username, error]);
    
   return (
       <div className='profile'>
           <Header data={userData} />
           <main className='main' style={{ padding: "30px" }}>
               <Charts />
               <Section repos={repos} />
           </main>
       </div>
   );
};
 
export default UserProfile; 

πŸ‘‰ Visualizing data with the Tremor UI library

Here, I will walk you through visualizing data with the Tremor library. We'll display the top languages used by the user, the most starred languages, and the stars per language.

React & Tremor Charts - Tremor Charts

Update the `requests.js` file to contain the following functions that fetch the top languages, most starred languages, and the stars per language.

The information is pulled via 4 helpers (code not shown) that provide the information to be used by Charts.

import {
   fetchMostStarredRepos,
   fetchRepos,
   fetchStarsPerLang,
   fetchTopLanguages,
} from "../utils/requests";

In order to use the helper, we need to update UserProfile.js:

import Charts from "./Charts";
 
const UserProfile = () => {
   const [mostStarred, setMostStarred] = useState([]);
   const [starsPerLanguageArray, setStarsPerLanguageArray] = useState([]);
   const [topLanguages, setTopLanguages] = useState([]);
 
   //...other functions and states
   useEffect(() => {
       function authenticate() {
           if (!error) {
               fetchMostStarredRepos(username, setMostStarred);
               fetchRepos(username, setRepos);
               fetchStarsPerLang(username, setStarsPerLanguageArray);
               fetchTopLanguages(username, setTopLanguages);
           }
       }
       authenticate();
   }, [username, error]);
 
   return (
       <div className='profile'>
           <Header data={userData} />
           <main className='main' style={{ padding: "30px" }}>
               {/*Pass the data into the Charts component*/}
               <Charts
                   topLanguages={topLanguages}
                   mostStarred={mostStarred}
                   starsPerLanguageArray={starsPerLanguageArray}
               />
               <Section repos={repos} />
           </main>
       </div>
   );
};
export default UserProfile;

To visualize the data as done in the image above, update the `Charts.js` file to contain the code below:

import React from "react";
import { BarChart, DonutChart, Card, Title } from "@tremor/react";
 
const Charts = ({ topLanguages, mostStarred, starsPerLanguageArray }) => {
   return (
       <div className='card__container'>
           <Card>
               <Title>Top Languages</Title>
               <DonutChart
                   data={topLanguages}
                   category='count'
                   variant='pie'
                   dataKey='lang'
                   marginTop='mt-6'
                   colors={["yellow", "blue", "red", "blue"]}
               />
           </Card>
           <Card>
               <Title>Most Starred</Title>
               <BarChart
                   data={mostStarred}
                   dataKey='name'
                   categories={["stars"]}
                   colors={["blue"]}
                   marginTop='mt-6'
                   yAxisWidth='w-6'
               />
           </Card>
           <Card>
               <Title>Stars per Language</Title>
               <DonutChart
                   data={starsPerLanguageArray}
                   category='stars'
                   dataKey='lang'
                   marginTop='mt-6'
                   colors={["yellow", "blue", "red", "blue"]}
               />
           </Card>
       </div>
   );
};
 
export default Charts;

According to the code snippet, I imported two types of charts provided by Tremor and passed the data into the UI components.


✨ Conclusion

So far, you've learned how to use Tremor, the various features provided by Tremor, and how to visualize data via the Tremor library.

This tutorial walks you through a demo of what you can build with the Tremor UI library and GitHub API. Feel free to explore Tremor's documentation, contribute and join its community of developers.

If you are looking for a React library that can help you visualize data with ease and as fast as possible, Tremor is an excellent choice. Thanks for reading!