使用 React 和 Recharts 为 Postgres db 创建仪表板
仪表板让我们能够查看数据,并让我们能够全面了解该产品或感兴趣的领域发生的所有事情。
在本教程中,我们将在 postgresSQL 数据库上构建一个仪表板。这是一个简单的仪表板,显示存储在数据库中的项目和用户视图。我们将使用它React
作为前端、semantic-ui
UI 库、Canonic
创建 API 以及添加一些图形recharts
。
我们希望创建这样的东西:
由于这是在 postgres 数据库上构建仪表板的指南,请确保您已准备好仪表板。
让我们深入研究一下吧!🌊
步骤 1:与 CRA 开始
我们首先创建一个新项目create-react-app
npx create-react-app postgres-dashboard
这将为我们创建一个基本的 React 项目。我们还需要安装semantic-ui-react
样式和基本的 UI 组件。
yarn add semantic-ui-react semantic-ui-css
第 2 步:创建仪表板组件
我们将仪表板分为两部分:
- 顶级统计数据和图表显示在上半部分 - 命名 -
DashboardGrid
- 表格显示在下半部分 - 命名 -
DashboardTable
components
在目录中的文件夹中创建这两个组件src
。在每个文件夹中,我们将创建三个文件 - 一个用于 React 代码,一个用于 CSS 文件,一个用于导出组件。
DashboardGrid
让我们从创建组件开始。
仪表板网格
我们创建了 4 个框并添加了样式 - 以及虚拟数据。
src/components/DashboardGrid/DashboardGrid.js
import React from "react";
import { Card, Statistic } from "semantic-ui-react";
import "./DashboardGrid.css";
const DASHBOARD_BOXES = [
{
title: "Total Users",
className: "purple",
},
{
title: "Total Projects",
className: "green",
},
{
title: "Projects Created",
},
{
title: "Projects Completed",
},
];
function DashboardGrid() {
return (
<div className="dashboardGrid">
<div className="dashboardGrid-boxes">
{DASHBOARD_BOXES.map((box, i) => (
<Card className="dashboardGrid-boxes-item" centered raised>
<Statistic
className={box.className ? box.className : ""}
as="h4"
label={box.title}
value="89"
/>
</Card>
))}
</div>
<div>
{/** We'll add the chat here later */}
</div>
</div>
);
}
export default DashboardGrid;
src/components/DashboardGrid/DashboardGrid.css
.dashboardGrid {
display: flex;
justify-content: space-between;
}
.dashboardGrid-boxes {
display: grid;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.dashboardGrid-boxes-item {
text-align: center;
border: 2px solid #9e9e9e;
border-radius: 4px;
padding: 0 30px;
}
.dashboardGrid-boxes-item .value {
font-size: 32px;
}
.dashboardGrid-boxes-item .label {
margin-top: 6px;
font-weight: 400;
}
.dashboardGrid-boxes-item .purple .value {
color: #8f8cda;
}
.dashboardGrid-boxes-item .green .value {
color: #8fcfa7;
}
src/components/DashboardGrid/index.js
export { default } from "./DashboardGrid";
仪表板表
与组件类似DashboardGrid
,我们创建基本的表结构和相应的样式 - DashboardTable
。
src/components/DashboardTable/DashboardTable.js
import React from "react";
import { Table } from "semantic-ui-react";
import "./DashboardTable.css";
const TABLE_DATA = [
{
name: "Lorem Ipsum",
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
owner: "John Doe",
status: "in progress",
},
];
function DashboardTable() {
return (
<div className="dashboardTable">
<Table celled padded>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
<Table.HeaderCell>Owner</Table.HeaderCell>
<Table.HeaderCell>Status</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{TABLE_DATA.map((item, i) => (
<Table.Row>
<Table.Cell>
<div>{item.name}</div>
</Table.Cell>
<Table.Cell>
<div>{item.description}</div>
</Table.Cell>
<Table.Cell>
<div>{item.owner}</div>
</Table.Cell>
<Table.Cell>
<div>{item.status}</div>
</Table.Cell>
</Table.Row>
))}
</Table.Body>
</Table>
</div>
);
}
export default DashboardTable;
src/components/DashboardTable/DashboardTable.css
.dashboardTable {
margin-top: 60px;
}
src/components/DashboardTable/index.js
export { default } from "./DashboardTable";
步骤 3:将它们连接到 App.js
让我们添加两个组件App.js
并看看我们的设计是什么样子。
src/App.js
import React from "react";
import { Header } from "semantic-ui-react";
import DashboardGrid from "./components/DashboardGrid";
import DashboardTable from "./components/DashboardTable";
import "./App.css";
function App() {
return (
<div className="App">
<header className="App-header">
<Header as="h3">Analytics Dashboard connected with Postgres</Header>
</header>
<div className="App-main">
<DashboardGrid />
<DashboardTable />
</div>
</div>
);
}
export default App;
src/App.css
.App-header {
padding: 0 16px;
text-align: center;
}
.App-main {
padding: 0 16px;
max-width: 1160px;
margin: 60px auto 0;
}
让我们前往终端,运行一下,yarn start
看看仪表盘目前的样子。它看起来应该是这样的👇
步骤 4:在 PostgreSQL 上构建 API
现在我们已经完成了仪表板的基本框架,接下来让我们在 postgresSQL 数据库上构建 API。通常,我们可以采用两种方法:
- 搭建连接Postgres数据库的nodejs服务器
- 使用开发人员工具,让我们快速创建 API
为了简短起见,我们先来看看第二种选择。我们前往Canonic为我们的后端创建一个新项目。
创建新项目→选择“链接”→选择 Postgres 并添加 Postgres Url - 看起来像 - postgres://.....
。
出于本指南的目的,您可以直接克隆此项目并开始 - 如果您选择此路线 - 跳过此步骤的其余部分并跳过步骤 6。
它最终会创建链接到我们数据库的 API,并将这些 API 部署到 URL 上。您还可以在 Postgres 数据库中看到我们表的结构。
在我们当前的设置中,我们有两张表 -projects
和users
。我们为这两张表提供了 CRUD API。“文档”选项卡应该包含文档。
步骤5:集成DashboardTable API
现在我们有了 API,让我们将其集成到DashboardTable
组件中。我们使用的axios
库可以通过 进行安装yarn add axios
。
我们修改DashboardTable.js
文件以调用我们的 API 并获取数据。
...
import axios from "axios";
import { Table, Loader, Dimmer } from "semantic-ui-react";
import "./DashboardTable.css";
// get this URL from your project on Canonic
const GET_PROJECTS_URL =
"https://postgres-dashboard-7fc.can.canonic.dev/api/projects";
function DashboardTable() {
const [loading, setLoading] = React.useState(false);
const [projects, setProjects] = React.useState([]);
React.useEffect(() => {
setLoading(true);
axios(GET_PROJECTS_URL).then(({ data }) => {
setProjects(data.data || []);
setLoading(false);
});
}, []);
return (
<div className="dashboardTable-wrapper">
...
<Table.Body>
{projects.map((item, i) => (
<Table.Row>
...
// change item.owner to below
<Table.Cell width={1}>
<div>{item.users.name}</div>
</Table.Cell>
...
</Table.Row>
))}
</Table.Body>
</Table>
</div>
);
}
export default DashboardTable;
步骤 6:为仪表板统计信息创建自定义 API
现在,由于我们目前只有基本的 CRUD API,因此我们必须创建自定义 GET API 以使指标显示在我们的框和图表中。
所需的指标包括 - 用户总数、项目总数、正在进行的项目数、已完成的项目数以及每天新用户/项目的分布。
让我们回到我们在 Canonic 上的项目。转到“API”选项卡,并在“项目”表中创建一个新的 API 来获取所有这些指标。填写顶层详细信息 - 标题、路径。
然后在该部分中添加以下内容outputs
。
从属性面板顶部移动到代码部分,并添加以下代码。
module.exports = async function endpoint(params, ctx) {
const [users, projects] = await Promise.all([User.find({}),Project.find({})]);
return {
users: users.map((user) => user.created_at),
projects: projects.map((project) => project.created_at),
usersCount: users.length,
projectsCount: projects.length,
inProgressCount: projects.filter(project => project.status === 'in progress').length,
completedCount: projects.filter(project => project.status === 'completed').length
}
}
再次部署项目,我们的 API 应该就可以使用了。在“文档”选项卡中查找链接和请求参数。
步骤 7:集成 DashboardGrid API
我们将新构建的 API 集成到 DashboardGrid 组件中。
...
import axios from "axios";
import { Card, Statistic } from "semantic-ui-react";
import "./DashboardGrid.css";
const DASHBOARD_API_URL =
"https://postgres-dashboard-7fc.can.canonic.dev/api/projects/dashboard";
function DashboardGrid() {
const [dashboardCount, setDashboardCount] = React.useState({});
React.useEffect(() => {
axios(DASHBOARD_API_URL).then(({ data }) => setDashboardCount(data.data));
}, []);
const DASHBOARD_BOXES = [
{
title: "Total Users",
className: "purple",
value: dashboardCount?.usersCount,
},
{
title: "Total Projects",
className: "green",
value: dashboardCount?.projectsCount,
},
{
title: "In Progress",
value: dashboardCount?.inProgressCount,
},
{
title: "Completed",
value: dashboardCount?.completedCount,
},
];
return (
<div className="dashboardGrid">
...
<Statistic
...
value={box.value ? box.value : "-"}
/>
</Card>
))}
...
</div>
);
}
export default DashboardGrid;
奖励:为图表添加 Recharts!
步骤 8:安装 Recharts
recharts
使用 yarn 可以轻松添加其他包。
yarn add recharts
步骤 9:修改 DashboardGrid 以添加图表
让我们修改代码DashboardGrid
并添加图表。我们将使用 AreaChart 来实现。
...
import {
AreaChart,
CartesianGrid,
XAxis,
YAxis,
Tooltip,
Area,
} from "recharts";
...
function DashboardGrid() {
...
const { projects = [], users = [] } = dashboardCount || {};
// We're manually making displaying the trend for this week.
// You can always make it dynamic by using Date.now().
// Let me know in the comments if you want me to cover this part.
const PREVIOUS_WEEK_DATA = [
{
name: "30th Nov",
projects: projects.filter(
(created_at) =>
// for now, we're using timestammps of the day to compare which
// data point lies on which day
created_at >= 1638230400000 && created_at < 1638316799000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638230400000 && created_at < 1638316799000
).length,
},
{
name: "1st Dec",
projects: projects.filter(
(created_at) =>
created_at >= 1638316800000 && created_at < 1638403199000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638316800000 && created_at < 1638403199000
).length,
},
{
name: "2nd Dec",
projects: projects.filter(
(created_at) =>
created_at >= 1638403200000 && created_at < 1638489599000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638403200000 && created_at < 1638489599000
).length,
},
{
name: "3rd Dec",
projects: projects.filter(
(created_at) =>
created_at >= 1638489600000 && created_at < 1638575999000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638489600000 && created_at < 1638575999000
).length,
},
{
name: "4th Dec",
projects: projects.filter(
(created_at) =>
created_at >= 1638576000000 && created_at < 1638662399000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638576000000 && created_at < 1638662399000
).length,
},
{
name: "5th Dec",
projects: projects.filter(
(created_at) =>
created_at >= 1638662400000 && created_at < 1638748799000
).length,
users: users.filter(
(created_at) =>
created_at >= 1638662400000 && created_at < 1638748799000
).length,
},
];
return (
<div className="dashboardGrid">
<div className="dashboardGrid-boxes">
...
</div>
<div>
<div className="dashboardGrid-chart">
New users/projects trend per day
</div>
<AreaChart
width={700}
height={250}
data={PREVIOUS_WEEK_DATA}
margin={{ top: 10, right: 30, left: 0, bottom: 0 }}
>
<defs>
<linearGradient id="colorUv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#8884d8" stopOpacity={0.8} />
<stop offset="95%" stopColor="#8884d8" stopOpacity={0} />
</linearGradient>
<linearGradient id="colorPv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#82ca9d" stopOpacity={0.8} />
<stop offset="95%" stopColor="#82ca9d" stopOpacity={0} />
</linearGradient>
</defs>
<XAxis dataKey="name" />
<YAxis />
<CartesianGrid strokeDasharray="3 3" />
<Tooltip />
<Area
name="Projects"
type="monotone"
dataKey="projects"
stroke="#8884d8"
fillOpacity={1}
fill="url(#colorUv)"
/>
<Area
name="Users"
type="monotone"
dataKey="users"
stroke="#82ca9d"
fillOpacity={1}
fill="url(#colorPv)"
/>
</AreaChart>
</div>
</div>
);
}
export default DashboardGrid;
终于!经过这么多修改,我们来运行一下应用,看看效果如何!应该和开头的截图一致。
恭喜!您已成功创建仪表板!🎉
结论
希望本指南能帮助您更好地了解如何在 React 中创建仪表板、如何构建仪表板以及如何快速启动和运行一个基本的仪表板。您也可以在这里查看我们的其他指南 。
加入我们的 Discord,与我们的社区讨论或分享。如有任何支持请求,请发送邮件至 support@canonic.dev。访问我们的 网站 ,了解更多关于 Canonic 的信息。
文章来源:https://dev.to/canonic/creating-a-dashboard-for-your-postgres-db-with-react-and-recharts-2ecm