Source: Statsbot Blog

Statsbot Blog Material UI Dashboard with React

Material UI is the most popular React UI framework. Created with inspiration from Google’s Material Design, Material UI provides a lot of ready-to-use components to build web applications, including dashboards, fast and easy.In this tutorial, 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 admin dashboard.We’re going to use Cube.js 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.Below you can see an animated image of the application we’re going to build. Also, check out the live demo and the full source code available on GitHub.Analytics Backend with Cube.jsWe’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 analytics backend.First, we need to install the Cube.js command-line utility (CLI). For convenience, let’s install it globally on our machine.$ npm install -g cubejs-cliThen, with the CLI installed, we can create a basic backend by running a single command. Cube.js supports all popular databases, and the backend will be pre-configured to work with a particular database type:$ cubejs create <project name> -d <database type>We’ll use a PostgreSQL database. Please make sure you have PostgreSQL installed.To create the backend, we run this command:$ cubejs create react-material-dashboard -d postgresNow we can download and import a sample e-commerce dataset for PostgreSQL:$ curl http://cube.dev/downloads/ecom-dump.sql > ecom-dump.sql$ createdb ecom$ psql — dbname ecom -f ecom-dump.sqlOnce the database is ready, the backend 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.js project folder (react-material-dashboard):CUBEJS_DB_NAME=ecomCUBEJS_DB_TYPE=postgresCUBEJS_API_SECRET=secretNow we can run the backend!In development mode, the backend will also run the Cube.js 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.js project folder:$ node index.jsNext, open http://localhost:4000 in your browser.We’ll use the Cube.js Playground to create a data schema. It’s essentially a JavaScript code that declaratively describes the data, defines analytical entities like measures and dimensions, and maps them to SQL queries. Here is an example of the schema which can be used to describe users’ data.cube(`Users`, { sql: `SELECT * FROM users`, measures: { count: { sql: `id`, type: `count` }, }, dimensions: { city: { sql: `city`, type: `string` }, signedUp: { sql: `created_at`, type: `time` }, companyName: { sql: `company_name`, type: `string` }, },});Cube.js 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 backend, we select the line_items, orders, products, and 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.The “Build” tab is a place where you can build sample charts using different visualization libraries and inspect every aspect of how that chart was created, starting from the generated SQL all the way up to the JavaScript code to render the chart. You can also inspect the Cube.js query encoded with JSON which is sent to Cube.js backend.Frontend with Material UICreating a complex dashboard from scratch usually takes time and effort.The Cube.js Playground can generate a template for any chosen frontend framework and charting library for you. To create a template for our dashboard, navigate to the “Dashboard App” and use these options:Framework: ReactMain Template: React Material UI StaticCharting Library: Chart.jsCongratulations! Now we have the dashboard-app folder in our project. This folder contains all the frontend code of our analytical dashboard.Now it’s time to add the Material UI framework. To have a nice-looking dashboard, we’re going to use a custom Material UI theme. You can learn about creating your custom Material UI themes from the documentation. For now, let’s download a pre-configured theme from GitHub:$ curl -LJO https://github.com/cube-js/cube.js/tree/master/examples/material-ui-dashboard/dashboard-app/src/theme/theme.zipThen, let’s install the Roboto font which works best with Material UI:$ npm install typeface-robotoNow we can include the theme and the font to our frontend code. Let’s use the ThemeProvider from Material UI and make the following changes in the App.js file:// ...- import { makeStyles } from "@material-ui/core/styles";+ import { makeStyles, ThemeProvider } from "@material-ui/core/styles";+ import theme from './theme';+ import 'typeface-roboto'+ import palette from "./theme/palette";// ...const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1,+ margin: '-8px',+ backgroundColor: palette.primary.light, },}));const AppLayout = ({children}) => { const classes = useStyles(); return (+ <ThemeProvider theme={theme}> <div className={classes.root}> <Header/> <div>{children}</div> </div>+ </ThemeProvider> );};// ...The only thing left to connect the frontend and the backend is a Cube.js query. We can generate a query in the Cube.js Playground. Go to http://localhost:4000/, navigate to the “Build” tab, and choose the following query parameters:Measure: Orders CountDimension: Orders StatusData range: This weekChart type: BarWe can copy the Cube.js query for the shown chart and use it in our dashboard application.To do so, let’s create a generic <BarChart /> component which, in turn, will use a ChartRenderer component. Create the src/components/BarChart.js file with the following contents:import React from "react";import clsx from "clsx";import PropTypes from "prop-types";import { makeStyles } from '@material-ui/styles';import ChartRenderer from './ChartRenderer'import { Card, CardContent, Divider,} from "@material-ui/core";const useStyles = makeStyles(() => ({ root: {}, chartContainer: { position: "relative", padding: "19px 0" }}));const BarChart = props => { const { className, query, ...rest } = props; const classes = useStyles();return ( <Card {...rest} className={clsx(classes.root, className)}> <CardContent> <div className={classes.chartContainer}> <ChartRenderer vizState={{ query, chartType: 'bar' }}/> </div> </CardContent> </Card> )};BarChart.propTypes = { className: PropTypes.string};export default BarChart;We’ll need some custom options for the <ChartRenderer /> component. These options will make the bar chart look nice.Create the helpers folder inside the dashboard-app/src folder. Inside the helpers folder, create the BarOptions.js file with the following contents:import palette from '../theme/palette';export const BarOptions = { responsive: true, legend: { display: false }, cornerRadius: 50, tooltips: { enabled: true, mode: 'index', intersect: false, borderWidth: 1, borderColor: palette.divider, backgroundColor: palette.white, titleFontColor: palette.text.primary, bodyFontColor: palette.text.secondary, footerFontColor: palette.text.secondary, }, layout: { padding: 0 }, scales: { xAxes: [ { barThickness: 12, maxBarThickness: 10, barPercentage: 0.5, categoryPercentage: 0.5, ticks: { fontColor: palette.text.secondary, }, gridLines: { display: false, drawBorder: false, }, }, ], yAxes: [ { ticks: { fontColor: palette.text.secondary, beginAtZero: true, min: 0, }, gridLines: { borderDash: [2], borderDashOffset: [2], color: palette.divider, drawBorder: false, zeroLineBorderDash: [2], zeroLineBorderDashOffset: [2], zeroLineColor: palette.divider, }, }, ], },};Let’s edit the `src/components/ChartRenderer.js` file to pass the options to the `<Bar />` component:// ...import TableHead from '@material-ui/core/TableHead';import TableRow from '@material-ui/core/TableRow';+ import palette from '../theme/palette'+ import moment from 'moment';+ import { BarOptions } from '../helpers/BarOptions.js';- const COLORS_SERIES = ['#FF6492', '#141446', '#7A77FF'];+ const COLORS_SERIES = [palette.secondary.main, palette.primary.light, palette.secondary.light];// ...bar: ({ resultSet }) => { const data = {- labels: resultSet.categories().map((c) => c.category),+ labels: resultSet.categories().map((c) => moment(c.category).format('DD/MM/YYYY')), datasets: resultSet.series().map((s, index) => ({ label: s.title, data: s.series.map((r) => r.value), backgroundColor: COLORS_SERIES[index], fill: false, })), };- return <Bar data={data} options={BarOptions} />;+ return <Bar data={data} options={BarOptions} />; },//...Now the final step! Let’s add the bar chart to the

Read full article »
Est. Annual Revenue
$100K-5.0M
Est. Employees
1-25
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100

Read more