

Cube.js:开源仪表板框架的终极指南
source link: https://www.infoq.cn/article/6gv1jGDbcy0ZtoEb-om6?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Cube.js 是一个用于构建分析 web 应用程序的开源框架,主要用于构建内部的商业智能工具或将面向客户的分析添加到现有的应用程序当中。大多数情况下,构建此类应用程序的第一步是分析仪表板。通常从“在管理面板中添加一个分析仪表板”开始,然后就像软件开发中经常发生的那样,事情会变得更加复杂。
当开始使用 Cube.js 时,会想要构建一个工具,它起初很简单,但在功能、复杂性和数据量方面很容易扩展。Cube.js 为未来的分析系统奠定坚实的基础,无论是独立的应用程序还是嵌入到现有的分析系统中。
本教程可以视为“Cube.js 101”,它介绍了从数据库到可视化的第一个仪表板的基本设计步骤。
最终仪表板的现场演示可在 此处 获得。完整的源代码在 GitHub 上。
架构
大多数现代 web 应用程序都是作为 单页面应用程序 构建的,前端与后端分离。遵循 微服务架构 ,后端通常也会分成多个服务。
通常,Cube.js 的后端作为服务运行,管理与数据库的连接,包括查询队列、缓存、预聚合等。同时为前端应用程序公开一个 API,用于构建仪表板和其他分析功能。
后端
分析从数据产生并驻留在数据库中开始,如果用户已经有一个适用于应用程序的数据库,通常它可以直接用于分析。现代流行的数据库,如 Postgres 或 MySQL,都可以做简单的分析工作,这里的简单指的是行数少于 10 亿的数据量。
另外,MongoDB 也可以,不过需要添加 MongoDB Connector for BI。它允许在 MongoDB 数据之上执行 SQL 代码。这是免费的,可以从 MongoDB 网站直接下载。需要注意的是,出于性能问题的考虑,直接在生产数据库上运行分析查询是不好的做法。所以,即使 Cube.js 可以显著减少数据库的工作量,但仍然建议连接到副本。
总而言之,如果使用 Postgres 或 MySQL,只需创建一个副本就可以了。如果您使用 MongoDB,请下载 MongoDB Connector for BI 并创建副本。
如果没有构建仪表板的任何数据,可以加载示例中的电子商务 Postgres 数据集。
复制代码
$ curl http://cube.dev/downloads/ecom-dump.sql> ecom-dump.sql $createdbecom $ psql--dbname ecom -f ecom-dump.sql
当数据库中有数据,就可以开始创建 Cube.js 的后端服务。在终端中运行以下命令:
复制代码
$npm install -g cubejs-cli $cubejs create dashboard-backend -d postgres
上面的命令安装 Cube.js CLI,并创建一个新服务,配置为可以与 Postgres 数据库一起使用。
Cube.js 使用环境变量进行配置,环境变量以 CUBEJS_ 开头。要配置与数据库的连接,需要指定数据库的类型和名称。在 Cube.js 项目文件夹中,替换.env 的以下内容:
复制代码
CUBEJS_API_SECRET =SECRET CUBEJS_DB_TYPE = postgres CUBEJS_DB_NAME = ecom
Cube.js 数据 Schema
下一步是创建一个 Cube.js 数据 Schema 。Cube.js 利用数据 Schema 生成 SQL 代码,该代码将在数据库中执行。数据 Schema 不是 SQL 的替代品,它旨在使 SQL 可重用并赋予其结构,同时保留其所有功能。数据 Schema 的基本元素是 measures 和 dimensions。
,
Measure 被称为定量数据,例如单位销售数、唯一访问量、利润等。
Dimension 被称为分类数据,例如状态、性别、产品名称或时间单位(例如,日、周、月)。
通常,模式文件位于 schema 文件夹中。以下是架构的示例,可用于描述用户的数据。
复制代码
cube(`Users`,{ sql:`SELECT*FROMusers`, measures:{ count:{ sql:`id`, type:`count` } }, dimensions:{ city:{ sql:`city`, type:`string` }, signedUp:{ sql:`created_at`, type:`time` }, companyName:{ sql:`company_name`, type:`string` } } }); {1}
现在,通过上述 Schema,可以向 Cube.js 后端发送有关用户数据的查询。Cube.js 查询是纯 JavaScript 对象。通常情况下,它有一个或多个 measures、dimensions 和 timeDimensions。
如果要回答“用户在哪里?”这个问题,可以将以下查询发送到 Cube.js:
复制代码
{ measures: ['Users.count'], dimensions: ['Users.city'] }
Cube.js 将根据 Schema 生成所需的 SQL,执行它并将结果发回。
我们可以创建一个稍微复杂的查询,添加一个 timeDimensions,看看去年不同城市的比例在每个月是如何变化的。为此,需要添加 signedUp 时间维度,按月分组,并仅包含去年的注册。
复制代码
{ measures: ['Users.count'], dimensions: ['Users.city'], timeDimensions: [{ dimension:'Users.signedUp', granularity:'month', dateRange: ['2018-01-31','2018-12-31'] }] }
Cube.js 还可以根据数据库的表生成简单的 Schema,并需要为仪表板生成所需的 Schema,启动一个供开发的服务器。
复制代码
$ cubejsgenerate-t users,orders $ npm run dev
可以通过在 http://localhost:4000 打开开发后台,检查生成的 Schema 并发送测试的查询。
前端
通过 Cube.js 的 React 客户端,可以使用 React 来构建前端和仪表板。也可以使用任何框架或只使用 vanilla JavaScript 来构建 Cube.js 的前端, 这个教程将向您展示如何在纯 JavaScript 中构建仪表板 。我们将使用 React 团队正式支持的 Create React App 来设置所有内容,它打包了 React 应用程序的所有依赖项,可以轻松地开始使用新项目。在终端中运行以下命令:
复制代码
$npxcreate-react-appdashboard-frontend $cdcubejs-dashboard $npmstart
最后一行在端口 3000 上启动服务器,并通过 http://localhost:3000 打开 web 浏览器。
我们将使用 Reactstrap 来构建我们的 UI,它是 Bootstrap 4 的 React wrapper。用 NPM 来安装 Reactstrap 和 Bootstrap。Reactstrap 不包括 Bootstrap CSS,所以需要单独安装:
复制代码
$ npminstallreactstrapbootstrap--save
导入./index.css 之前,导入 src/index.js 文件中的 Bootstrap CSS:
复制代码
import'bootstrap/dist/css/bootstrap.min.css';
现在,我们已准备好使用 Reactstrap 组件。
下一步是安装 Cube.js 客户端,这样可以从服务器和可视化库中获取数据并进行显示。在本教程中,我们将使用 Recharts。Cube.js 是可视化不可知的,这意味着可以使用任何所需的库。我们还将使用 moment 和 numeral 来很好地格式化日期和数字。
复制代码
$ npm install --save@ cubejs-client / core @cubejs-client / react rechartsmomentnumbers
这样,我们搞定了依赖关系。接下来继续创建我们的第一个图表,用以下替换 src/App.js 的内容:
复制代码
importReact, {Component} from"react"; import{ BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from"recharts"; importcubejs from"@cubejs-client/core"; importmoment from"moment"; import{QueryRenderer} from"@cubejs-client/react"; const cubejsApi = cubejs(process.env.REACT_APP_CUBEJS_TOKEN, { apiUrl: process.env.REACT_APP_API_URL }); const dateFormatter = item => moment(item).format("MMM YY"); classAppextendsComponent{ render() { return( <QueryRenderer query={{ measures: ["Orders.count"], timeDimensions: [ { dimension:"Orders.createdAt", dateRange: ["2017-01-01","2018-12-31"], granularity:"month" } ] }} cubejsApi={cubejsApi} render={({ resultSet }) => { if(!resultSet) { return"Loading..."; } return( <ResponsiveContainerwidth="100%"height={300}> <BarChartdata={resultSet.chartPivot()}> <XAxisdataKey="x"tickFormatter={dateFormatter} /> <YAxis/> <TooltiplabelFormatter={dateFormatter} /> <BardataKey="Orders.count"fill="rgba(106, 110, 229)"/> </BarChart> </ResponsiveContainer> ); }} /> ); } } exportdefaultApp;
可以在下面的 CodeSandbox 中查看此示例。
接下来,让我们更深入地了解如何加载数据并绘制图表。
首先,我们初始化 Cube.js API 客户端:
复制代码
constcubejsApi = cubejs(process.env.REACT_APP_CUBEJS_TOKEN, { apiUrl:process.env.REACT_APP_API_URL });
这里,我们使用 REACT_APP_CUBEJS_TOKEN 和 REACT_APP_API_URL 这两个环境变量。如果环境变量以 REACT_APP_ 开头,Create React App 会自动从.env 文件中加载。Cube.js 后端将在启动期间打印这些 API token。
使用正确的凭据创建.env 文件。
复制代码
REACT_APP_CUBEJS_TOKEN=COPY-API-TOKEN-FROM-TERMINAL-OUTPUT REACT_APP_API_URL=http://localhost:4000/cubejs-api/v1
接下来,我们使用 QueryRenderer Cube.js React Component 来加载 Orders 数据。
复制代码
<QueryRenderer query={{ measures: ["Orders.count"], timeDimensions: [ { dimension:"Orders.createdAt", dateRange: ["2017-01-01","2018-12-31"], granularity:"month" } ] }} cubejsApi={cubejsApi} render={({ resultSet }) => { // Render result }} />
QueryRenderer 对 Cube.js 后端执行 API 请求,并根据需要使用 render props 技术来渲染结果。我们上面已经介绍了查询格式,想得到最新的格式,这里是 查询格式的完整参考。
QueryRenderer 的参数 render,是几个类型的函数 ({error, resultSet, isLoading}) => React.Node。该函数的输出将由 QueryRenderer 提供。resultSet 是从查询获得的数据对象,如果未定义此对象,则表示仍在提取数据中。
resultSet 提供了多种数据操作方法,但在我们的例子中,只需要 chartPivot 方法,它以 Recharts 预期的格式返回数据。
我们将订单数据绘制成响应式容器内的条形图。
复制代码
if (!resultSet) { return "Loading..."; } return ( <ResponsiveContainerwidth="100%"height={300}> <BarChartdata={resultSet.chartPivot()}> <XAxisdataKey="x"tickFormatter={dateFormatter}/> <YAxis/> <TooltiplabelFormatter={dateFormatter}/> <BardataKey="Orders.count"fill="rgba(106, 110, 229)"/> </BarChart> </ResponsiveContainer> );
构建仪表板
我们学习了如何使用 Cube.js 和 Recharts 构建单个图表,现在可以开始构建整个仪表板。可以找到设计仪表板布局的一些最佳实践,通常的做法是将最重要和最高级别的指标放在顶部作为单值图表(有时称为 KPI) ,然后列出这些指标的相关细节。
以下是最终仪表板的屏幕截图,其中 KPI 位于顶部,下面是条形图和折线图。
首先,让我们重构图表,并将公共代码提取到可重用的 组件中。用以下的内容创建一个 src/Chart.js 文件:
复制代码
importReactfrom"react"; import{ Card, CardTitle, CardBody, CardText }from"reactstrap"; import{ QueryRenderer }from"@cubejs-client/react"; const Chart =({ cubejsApi, title, query, render })=>( <Card> <CardBody> <CardTitle tag="h5">{title}</CardTitle> <CardText> <QueryRenderer query={query} cubejsApi={cubejsApi} render={({ resultSet }) => { if(!resultSet) { return<div className="loader"/>; } returnrender(resultSet); }} /> </CardText> </CardBody> </Card> ); exportdefaultChart;
接下来,让我们使用此组件来创建仪表板。用以下内容替换 src/App.js:
复制代码
import React, { Component } from "react"; import { Container, Row, Col } from "reactstrap"; import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, Legend, BarChart, Bar } from "recharts"; import moment from "moment"; import numeral from "numeral"; import cubejs from "@cubejs-client/core"; import Chart from "./Chart.js"; const cubejsApi = cubejs(process.env.REACT_APP_CUBEJS_TOKEN, { apiUrl: process.env.REACT_APP_API_URL }); const numberFormatter = item => numeral(item).format("0,0"); const dateFormatter = item => moment(item).format("MMM YY"); const renderSingleValue = (resultSet, key) => ( <h1height={300}>{numberFormatter(resultSet.chartPivot()[0][key])}</h1> ); class App extends Component { render() { return ( <Containerfluid> <Row> <Colsm="4"> <Chart cubejsApi={cubejsApi} title="Total Users" query={{measures:["Users.count"] }} render={resultSet=> renderSingleValue(resultSet, "Users.count")} /> </Col> <Colsm="4"> <Chart cubejsApi={cubejsApi} title="Total Orders" query={{measures:["Orders.count"] }} render={resultSet=> renderSingleValue(resultSet, "Orders.count")} /> </Col> <Colsm="4"> <Chart cubejsApi={cubejsApi} title="Shipped Orders" query={{ measures:["Orders.count"], filters:[ { dimension:"Orders.status", operator:"equals", values:["shipped"] } ] }} render={resultSet=>renderSingleValue(resultSet, "Orders.count")} /> </Col> </Row> <br/> <br/> <Row> <Colsm="6"> <Chart cubejsApi={cubejsApi} title="New Users Over Time" query={{ measures:["Users.count"], timeDimensions:[ { dimension:"Users.createdAt", dateRange:["2017-01-01", "2018-12-31"], granularity:"month" } ] }} render={resultSet=>( <ResponsiveContainerwidth="100%"height={300}> <AreaChartdata={resultSet.chartPivot()}> <XAxisdataKey="category"tickFormatter={dateFormatter}/> <YAxistickFormatter={numberFormatter}/> <TooltiplabelFormatter={dateFormatter}/> <Area type="monotone" dataKey="Users.count" name="Users" stroke="rgb(106, 110, 229)" fill="rgba(106, 110, 229, .16)" /> </AreaChart> </ResponsiveContainer> )} /> </Col> <Colsm="6"> <Chart cubejsApi={cubejsApi} title="Orders by Status Over time" query={{ measures:["Orders.count"], dimensions:["Orders.status"], timeDimensions:[ { dimension:"Orders.createdAt", dateRange:["2017-01-01", "2018-12-31"], granularity:"month" } ] }} render={resultSet=>{ return ( <ResponsiveContainerwidth="100%"height={300}> <BarChartdata={resultSet.chartPivot()}> <XAxistickFormatter={dateFormatter}dataKey="x"/> <YAxistickFormatter={numberFormatter}/> <Bar stackId="a" dataKey="shipped, Orders.count" name="Shipped" fill="#7DB3FF" /> <Bar stackId="a" dataKey="processing, Orders.count" name="Processing" fill="#49457B" /> <Bar stackId="a" dataKey="completed, Orders.count" name="Completed" fill="#FF7C78" /> <Legend/> <Tooltip/> </BarChart> </ResponsiveContainer> ); }} /> </Col> </Row> </Container> ); } } export default App;
这足以构建第一个仪表板,然后可以在下面的 CodeSanbox 中尝试一下。
下一步
以上是我们使用 Cube.js 构建了一个简单的验证概念的仪表板。可以在 这里 查看 现场演示 。GitHub 有 完整的源代码 。
要了解有关 Cube.js 后端部署的更多信息,可以参考 部署文档。 此外,还可以在此处找到有关各种主题的 更多教程 。
原文链接: Cube.js: Ultimate Guide to the Open-Source Dashboard Framework
Recommend
-
84
性能测试工具 JMeter 实时监控仪表板配置 (Grafana + InfluxDB)
-
41
导读 Tableau公司近日推出Tableau 2018. 2 版本更新,该更新的扩展API能够让用户直接拖放第三方应用功能到仪表板。此外,在新推出的Tableau服务管理器下,用户可直接在浏览器中管理Tableau Server。 此外,Tableau 2018. 2 还具备...
-
45
一个好的仪表板能够帮助用户理解复杂数据、分析以及呈现关键的见解,对于提升用户体验是十分重要的;以下就是仪表板设计的7个实用技巧。 ...
-
37
之前虫虫的文章中介绍过很多终端软件,也介绍过分屏神器Screen和Tmux但是毕竟他们使用配置有一点点的难度。那么有没有一款简单易用,界面美观的终端仪表板程序,实现各种所需信息的展示呢,答案是肯定的,那就是本文我们要介绍的另一个神...
-
61
VMWare 开源了 Octant ,这是一款帮助开发人员了解应用程序在 Kubernetes 集群中如何运行的工具。它通过可视化的方式,呈现 Kubernetes 对...
-
23
学习使用 IBM Cloud Pak for Data 创建 Cognos Analytics 仪表板的基础知识 Srikanth Manne, Smruthi Raj Mohan, 和 Manjula G Hosurmath 2019 年 12 月 10 日发布 本教程是使用 IBM Cloud Pak for Data、Data...
-
9
10月21日!亚马逊美国站将推出新的退货绩效仪表板!-跨境头条-AMZ123亚马逊导航-跨境电商出海门户 10月21日!亚马逊美国站将推出新的退货绩效仪表板!...
-
8
亚马逊试点推出新的管理合规仪表板;亚马逊为圣诞季销售完善物流运输服务;美国打假组织对亚马逊发出假货警告-跨境头条-AMZ123亚马逊导航-跨境电商出海门户 ...
-
6
如何使用 Rancher Desktop 访问 Traefik Proxy 仪表板Adrian Goins 最近举办了关于如何使用 K3s...
-
3
Kubernetes 是一个开源容器编排平台,已成为大规模管理容器化应用的首选解决方案。虽然 Kubernetes 提供了强...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK