- 后端
- 数据分析
- 数据可视化
- 数据库
【免费下载链接】cube
📊 Cube Core is open-source semantic layer for AI, BI and embedded analytics
Vizard 是 Cube 开源仓库(Cube Core 语义层)内置在 Playground 中的一个独立 Web 应用:你只需提供 Cube API 地址、Token、查询语句(Query)和透视配置(Pivot Config),它就会自动为你挑选出适配的框架、语言与图表库,生成一份可直接运行的示例应用源码,并通过 iframe 提供真实数据驱动的实时预览。读完本文,你将掌握 Vizard 的完整配置方式、运行与构建流程、参数校验机制,以及从源码层面理解"代码生成 + 实时预览"这一整套工作链路,从而快速搭建你自己的 Cube 前端可视化 Demo 或基于该模式扩展新的模板应用。
Vizard 是什么:Cube 生态中的"示例应用生成器"
Vizard 的定位在 vizard/README.md 中有清晰定义:
Vizard is a web application that allows you to receive an application code example for your framework, visualization library and language using your Cube API params for live preview.
也就是说,Vizard 是一个按需生成前端示例代码的 Web 应用:它把"Cube API 参数"(API URL、Token、查询、透视配置)作为输入,把"可运行的示例应用源码"作为输出,并且输出之后还能直接以 live preview 的形式在浏览器里看到真实数据渲染的图表。
从仓库结构看,Vizard 位于 packages/cubejs-playground/vizard 目录,与 Playground(数据模型 IDE 与查询工作台)同属于 cubejs-playground 包,但它是独立运行的 Vite + React 应用(包名为vizard-preview,见 package.json),不依赖 Playground 本体即可启动。其核心能力可以拆成三个层面:
- 参数输入层:读取
.env.local中的 Cube API 参数; - 选项组合层:按"可视化类型 → 框架 → 语言 → 图表库"的层级关系,筛选出可用的技术栈组合(见 app-options.js);
- 代码生成与预览层:依据组合结果选择模板应用文件树,动态注入
.env.local配置,并在右侧 iframe 中渲染真实图表(见 app-files.ts 与 Preview.tsx)。
快速上手:四个环境变量搞定参数注入
Vizard 使用 Vite 构建,所有 Cube API 参数都通过环境变量注入。在项目根目录(即packages/cubejs-playground/vizard)创建.env.local文件,并填入以下内容(完整示例见 README.md):
# Create the .env.local file in the root of the project and copy the content of this file filling it with your params VITE_CUBE_API_URL=https://{domain or IP}/cubejs-api/v1 VITE_CUBE_API_TOKEN={YOUR API TOKEN} VITE_CUBE_QUERY={QUERY IN JSON} VITE_CUBE_PIVOT_CONFIG={PIVOT CONFIG IN JSON}各变量的含义与格式如下:
| 环境变量 | 说明 | 格式要求 |
|---|---|---|
VITE_CUBE_API_URL | Cube API 的 REST 端点地址 | https://{域名或 IP}/cubejs-api/v1 |
VITE_CUBE_API_TOKEN | 访问 Cube API 所需的认证令牌 | 字符串,由 Cube 生成 |
VITE_CUBE_QUERY | 需要执行的 Cube 查询 | JSON 字符串,如{"measures":["Orders.count"],"dimensions":["Orders.status"]} |
VITE_CUBE_PIVOT_CONFIG | 控制查询结果如何透视(行列转换)的配置 | JSON 字符串,如{"x":["Orders.status"],"y":["measures"]} |
这些变量之所以带有VITE_前缀,是因为 Vite 只会在构建期把import.meta.env.VITE_*暴露给前端代码。Vizard 在启动时会将这四个变量序列化进页面 URL 的 hash 中(见下文"参数如何流转"一节),因此即使之后修改了查询,也可以不重新构建、仅通过 URL hash 覆盖默认参数。
关于 API URL 的路径约定
VITE_CUBE_API_URL需要指向 Cube API 的/cubejs-api/v1前缀。例如本地开发时通常填写http://localhost:4000/cubejs-api/v1(Cube Core 默认端口为 4000)。Vizard 生成的示例应用会把这个地址连同 Token 一起写入它自己的.env.local,确保示例代码 clone 后开箱即用。
开发 / 构建 / 预览:三条命令的完整闭环
README 给出了三个标准命令,它们分别对应 package.json 中的 scripts:
$ yarn dev # 本地开发,等价于 yarn prepare && vite $ yarn build # 生产构建,等价于 yarn prepare && tsc && vite build $ yarn preview # 本地预览生产构建产物,等价于 vite preview值得注意的是dev与build前面都有一个prepare步骤(node ./convert-apps.js && node ./build-apps.js),这意味着:
convert-apps.js:把apps/目录下的模板应用递归读取、按.gitignore规则过滤,输出为src/apps.json(详见下文"模板应用如何变成可注入的文件树");build-apps.js:负责把各模板应用单独构建成可供 iframe 预览的静态页面。
因此,任何时候修改了apps/下的模板,都必须重新运行yarn dev或yarn build让prepare重新生成apps.json与预览产物,否则改动不会生效。
vite.config.ts(查看)中还做了几项对运行有影响的配置:
base: '/vizard/':所有静态资源路径都以/vizard/为基准,Preview iframe 的地址也是/vizard/preview/{appName}/index.html;- 手动分块(
manualChunks):把react、monaco-editor、@cubejs-client/*等拆分为独立 chunk,优化首屏加载; - 开发与预览服务器统一设置
Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin响应头,这是 Monaco Editor 的 Web Worker 正常加载所必需的跨源隔离配置。
技术栈选项:五类图表 × 三大框架 × 两种语言 × 两种库
Vizard 的核心交互是让用户通过右侧面板(Setup.tsx)自由组合技术栈。全部可选值定义在 app-options.js:
export const APP_OPTIONS = { visualization: ['line', 'bar', 'area', 'pie', 'doughnut', 'table'], framework: ['react', 'angular', 'vue'], language: ['typescript', 'javascript'], library: ['chartjs', 'antd'], };与之对应的展示名称与图标(Line/Bar/Area/Pie/Donut 等)映射在 options.tsx,例如:
| 选项值 | 显示名称 | 类型 |
|---|---|---|
line/bar/area/pie/doughnut | Line / Bar / Area / Pie / Donut | visualization |
table | Table | visualization |
react/angular/vue | React / Angular / Vue | framework |
typescript/javascript | TypeScript / JavaScript | language |
chartjs | Chart.js | library |
antd | Ant Design | library |
这些类型在 types.ts 中体现为VisualType、FrameworkType、LanguageType、LibraryType等联合类型,并组合出:
VisualParams:visualization + framework + language + library四元组;ConnectionParams:useWebSockets与useSubscription两个布尔开关;AllParams=VisualParams & ConnectionParams;ChartType:'area' | 'bar' | 'doughnut' | 'line' | 'pie' | 'table',最终传给模板应用的图表类型。
选项间的依赖校验:stats.json 组合矩阵
不是所有组合都有效——例如 Angular + Chart.js 可能就不可用。Vizard 通过构建期生成的stats.json(即VIZARD_PARAMS_MAP)维护了一张层级组合矩阵(visualization → framework → language → library),核心校验逻辑在 helpers.ts:
validateVisualParams(params):按优先级逐级校验四个参数。如果某个层级的值缺失或不在矩阵中,就自动回退到该层级第一个可用选项,保证任何时候都返回一个合法的VisualParams四元组;getAvailableOptions(params):根据当前已选的前 N 个维度,过滤出下一维度的可用选项,让 UI 只展示可行的组合。
这套机制在 Setup.tsx 中被实时调用:每当用户在表单里改动 visualization / framework / language / library 中的任意一项,都会重新校验并刷新可用选项;如果当前组合没有任何图表库支持,面板会给出提示 "This combination of options supports no charting library yet."(见 Setup.tsx)。
默认状态下,Vizard 使用visualization: 'line'作为初始值(见 Vizard.tsx),其余维度由校验逻辑自动推导。
参数如何流转:env → URL hash → 预览
理解 Vizard 内部的数据流,是读懂它"改参数即可实时更新预览"的关键。整条链路如下:
- 启动时写 hash:如果 URL 上没有 hash,Vizard.tsx 会把
.env.local中的apiUrl、apiToken、query、pivotConfig序列化为 JSON,再btoa+encodeURIComponent编码后写入location.hash; - 运行时读 hash:Vizard 启动时从
location.hash解码出VizardProps({ apiUrl, apiToken, query, pivotConfig }),并以此为唯一数据源(见 Vizard.tsx)。如果 hash 非法,会抛出Invalid params错误; - 组装 Config:把 hash 参数与用户在面板中选定的
chartType、useWebSockets、useSubscription合并为Config对象(见 Vizard.tsx); - 计算应用名:
useAppName依据四元组从VIZARD_PARAMS_MAP中查出对应的模板应用名(见 app-name.ts),任何一层组合非法都会抛出对应错误; - 生成文件树:
useAppFiles从apps.json取出该模板的完整文件树,并动态生成一个.env.local文件节点,内容为(见 app-files.ts):
VITE_CUBE_API_URL={apiUrl} VITE_CUBE_API_TOKEN={apiToken} VITE_CUBE_QUERY={JSON.stringify(query)} VITE_CUBE_PIVOT_CONFIG={JSON.stringify(pivotConfig)} VITE_CHART_TYPE={chartType} VITE_CUBE_API_USE_WEBSOCKETS={useWebSockets ? 'true' : 'false'} VITE_CUBE_API_USE_SUBSCRIPTION={useSubscription ? 'true' : 'false'}注意这里比 Vizard 自身的.env.local多了三个变量:VITE_CHART_TYPE、VITE_CUBE_API_USE_WEBSOCKETS、VITE_CUBE_API_USE_SUBSCRIPTION——它们是模板应用运行时需要的; 6.实时预览:Preview组件把整个Config再次编码进 URL hash,拼出 iframe 地址/vizard/preview/{appName}/index.html#{hash},并在参数变化时重新加载 iframe(见 Preview.tsx)。这就是"改选项 → 预览立即更新"的实现原理。
模板应用端如何消费这些参数
以仓库内置的 Chart.js 模板 react-typescript-chartjs-area+bar+doughnut+line+pie 为例,它在App.tsx中:
- 用
extractHashConfig(见 config.ts)从自身 URL hash 中解码 Config,覆盖.env.local提供的默认值——hash 的优先级最高,这正是 Vizard 主应用"注入参数"的通道; - 若
useWebSockets为真,则创建WebSocketTransport({ authorization: apiToken, apiUrl })作为 Cube API 的传输层,否则走默认 REST 传输; - 通过
cube(apiToken, { apiUrl, transport })创建客户端实例,包进CubeProvider; - 用
QueryRenderer(查看)调用useCubeQuery(query, { subscribe }),渲染 Loading / Error / 数据三种状态; - 数据到达后交给
ChartViewer:Chart.js 版通过resultSet.chartPivot(pivotConfig)生成 labels、resultSet.series(pivotConfig)生成 datasets,再根据chartType选择Line / Bar / Pie / Doughnut组件(见 ChartViewer.tsx);Ant Design 表格版则用resultSet.tableColumns()生成列、resultSet.tablePivot(pivotConfig)生成行数据渲染<Table>(见 ChartViewer.tsx)。
这就是"你的 Cube API 参数 + 你选的技术栈 → 真实可运行代码 → 真实数据图表"的完整闭环。
代码浏览与下载:生成结果的三种交付方式
在 Code 标签页(CodeViewer.tsx)中,Vizard 将生成的文件树渲染为一个可折叠的左侧文件列表(目录图标 + 文件图标,按路径缩进),点击文件即打开编辑区,编辑区使用Monaco Editor(只读模式,主题cube,见 Editor.tsx)进行语法高亮展示。底部工具栏提供了三种交付方式:
- Source 按钮:点击下载整个模板应用的源码(
./download/{appName}.zip),即一份完整可独立运行的工程; - Config 按钮:仅下载动态生成的
.env.local文件——把这份配置放进任何克隆下来的模板工程根目录即可连上你的 Cube API(下载逻辑见 download-file.ts,通过 Blob +<a download>触发浏览器下载); - Docs 按钮:跳转到 Vizard 的官方文档页面(在 CodeViewer.tsx 中配置)。
模板应用机制:新示例代码如何被纳入
Vizard 的"示例代码"并非写死在前端,而是由apps/目录下的模板应用在构建期自动收集。目前仓库内置了两个模板(见 apps 目录):
react-typescript-chartjs-area+bar+doughnut+line+pie:React + TypeScript + Chart.js,覆盖五种图表类型;react-typescript-antd-table:React + TypeScript + Ant Design Table。
convert-apps.js(查看)的处理逻辑是:
- 遍历
apps/下每个子目录,若存在.vizardignore文件则整体跳过; - 解析模板自身的
.gitignore(并强制忽略.gitignore本身),用minimatch做路径匹配,过滤掉应忽略的文件(如node_modules、构建产物); - 递归读取剩余文件,构造
{ name: { file: { contents } } }/{ name: { directory: {...} } }形式的嵌套结构,最终写入src/apps.json。
运行时 app-files.ts 从apps.json中按键名(即目录名,如react-typescript-chartjs-...)取出对应的文件树,再注入动态生成的.env.local节点。可以推断:在apps/下新增一个模板目录(并让stats.json的组合矩阵指向它),就能让 Vizard 支持新的技术栈组合——这是扩展 Vizard 的主要方式。
常见问题与排查思路
- 预览空白或报错:优先检查
.env.local中VITE_CUBE_API_URL是否以/cubejs-api/v1结尾、Token 是否有效、VITE_CUBE_QUERY是否是合法 JSON(可以在.env.local中先写{}测试连通性)。同时确认通过yarn dev启动过(prepare已生成apps.json与预览产物)。 - 修改模板后看不到变化:由于
prepare是前置步骤,请重新执行yarn dev或yarn build;如果是开发调试,建议先手动执行一次yarn prepare再启动 Vite。 - hash 无法解析:Vizard 从
location.hash读取参数并解码,若手动改动过 URL 导致 base64 损坏,会抛出Invalid params,此时清空 URL hash 重新加载即可(会回退到.env.local的默认值)。 - 跨源隔离相关报错:Monaco 的 Worker 依赖 COEP/COOP 头,请保持 vite.config.ts 中的响应头配置,不要在反向代理层移除它们。
小结
Vizard 以极简的四行环境变量作为输入,把"生成示例应用代码"与"真实数据实时预览"两件事无缝衔接在一起:参数经 URL hash 在主应用与模板应用之间传递,选项经组合矩阵校验保证技术栈组合始终可用,模板经convert-apps.js自动收集并可自由扩展。对开发者而言,它既是一个快速产出 Cube 前端 Demo 的工具,也是一个"配置驱动代码生成 + iframe 实时预览"模式的完整参考实现——相关源码均可从 vizard 目录 开始阅读,入口依次是 Vizard.tsx、Setup.tsx、app-files.ts 与 Preview.tsx。
- 后端
- 数据分析
- 数据可视化
- 数据库
【免费下载链接】cube
📊 Cube Core is open-source semantic layer for AI, BI and embedded analytics
相关推荐
Cube-UI 图片预览组件 ImagePreview 使用指南
Cube UI 图片预览组件 ImagePreview 使用指南 什么是 ImagePreview 组件 ImagePreview 是 Cube UI 提供的一
前端UI组件移动开发Cube CLI(`cube`):用 Rust 单二进制命令行管理 Cube Cloud 的完整实战指南
Cube CLI( cube ):用 Rust 单二进制命令行管理 Cube Cloud 的完整实战指南 Cube CLI( cube )是 Cube 开源仓库
后端数据分析数据可视化数据库WrenAI 如何定义 cube 预聚合指标并用 wren cube query 执行结构化查询
WrenAI 如何定义 cube 预聚合指标并用 wren cube query 执行结构化查询 在 WrenAI 项目中,当你希望把"月度收入""订单量"这类
后端人工智能AI Agent数据分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考