通过 React JS SDK 集成
react js sdk 与任何 github / npm 第三方库类似,提供了 Completion UI 组件和 useProvider hook,适用于将衡石 ChatBI 的能力以及图表集成在你自己的 react 项目中。
react 版本
支持的 react 版本为 18,我们提供的 sdk 内不包含 react 及 react-dom。
此外,sdk 内包含依赖了下列第三方库:
- antd v4
- core-js v3
- zrender v5
- lodash v4
- marked v15
- moment
- react-i18next
若你的 react 项目也有使用同样的依赖库,可以联系售后进行沟通,我们可以提供排除重复依赖后的 sdk 包,以避免多余的资源加载。
提示
我们提供的 sdk 包已经是排除 react 后的压缩版本,你的项目在打包时,应避免再次将 sdk 文件进行压缩和混淆。
快速开始
- 安装与引入 由于 React JS SDK 不提供 npm 包,请与售后联系,或通过邮箱 support@hengshi.com 进行咨询。
示例项目结构
<你的项目>/
├── src/
| ├── hengshi/ <-- 例如将 SDK 放在您项目源码中的这里
│ ├── index.ejs
│ └── index.js
└── package.json
- 渲染一个 Completion 组件
示例 index.js
:
import React from "react";
import { createRoot } from "react-dom/client";
import Completion from "./hengshi";
function ReactApp() {
const chat = { // 此对象数据结构来自衡石 ChatBI 后端
"meta": "refineQuestion,answer,chart,chartConfig", // meta 属性可以控制组件渲染哪些内容
"conversationId": 226,
"uid": "00747081-9cc3-4c7c-b3de-735244498fd6",
"prompt": "bug issue的模块分布情况",
"answer": "bug issue在各模块中的分布较均匀,最多的模块有4个bug,其余大部分模块有2-3个bug。",
"refineQuestion": "请提供bug issue在各模块中的分布情况",
"charts": [
{
"appId": 134683,
"datasetId": 1,
"options": {
"axes": [
{
"op": "{{41}}.{title}",
"uid": "uid1",
"kind": "formula"
},
{
"op": "count({{33}}.{issue_id})",
"uid": "uid2",
"kind": "formula"
}
],
"limit": 100
}
}
]
};
return <Completion {...chat} />;
}
const root = createRoot(document.getElementById("root"));
root.render(<ReactApp />);
渲染后如图所示:
useProvider hook
useProvider
是我们提供一个 React Hook,等价于 vanilla js sdk 中的 new Copilot(...) 操作。hook 是为了更适配 react 项目。
useProvider
hook 的返回值参考 copilot 实例。通过此 hook 你可以实现在 react 项目中创建衡石 ChatBI 对话、渲染图表等功能。
示例:
import React from "react";
import { createRoot } from "react-dom/client";
import Completion, { useProvider } from "./hengshi";
function ReactApp() {
const [chat, setChat] = React.useState();
const [prompt, setPrompt] = React.useState('用户输入的问题');
const [dataSources, setDataSources] = React.useState([{"dataAppId":134683,"datasetId":1}]); // 对话数据源
const provider = useProvider({
baseUrl: 'http://localhost:8881', // 衡石服务地址
pollingInterval: 1000, // 轮询间隔,单位毫秒
});
const onSend = () => {
provider.context.onCreateChat({
prompt, // 这里是用户的问题
userConfig: {
dataSources,
},
}, _chat => {
setChat(_chat);
provider.context.onWaitingChat(_chat.conversationId, _chat.uid, setChat);
});
};
return (
<div>
<input onChange={e => setPrompt(e.target.value)} />
<button onClick={onSend}>发送</button>
{chat ? <Completion {...chat} /> : null}
</div>
);
}
const root = createRoot(document.getElementById("root"));
root.render(<ReactApp />);
Shadow DOM 说明
为了避免样式冲突,组件使用了 Shadow DOM 进行渲染,确保组件的样式不会影响或被外部应用影响。
SDK 目录结构
hengshi/
├── index.css # 样式表文件
├── index.js # 主 SDK 入口
├── index.esm.js # 主 SDK 入口
├── font/ # 字体资源
│ ├── fontello.eot
│ ├── fontello.ttf
│ ├── fontello.woff
│ └── fontello.woff2
└── locales/ # 语言包
├── en-US.json
├── zh-CN.json
组件 API 参考
正如前边示例中所示,Completion
组件接受 chat
数据作为参数,该对象是衡石对话回合的数据内容,可以通过 GET /api/conversations/${conversationId}/chats/${uid}
接口获取到,数据结构参考 chat。
除了 chat
对象的所有属性之外,Completion
组件还接受以下参数:
参数 | 类型 | 说明 |
---|---|---|
meta | STRING | 'refineQuestion', 'answer', 'chart', 'chartSwitcher', 'chartConfig' 等几个字符串的任意组合,以逗号(',')分割,可以用来自定义展示内容 |
disableEllipsis | BOOL | 为 true 时,不会将答案和取数逻辑的 tag 折叠或省略显示 |
showWhenNoData | BOOL | 当没有数据时是否显示图表组件,默认为 false |
chartTheme | STRING | 仪表盘主题 ID,参考主题颜色 |
stylesheets | STRING 或 STRING ARRAY | 样式表链接 或者 样式表内容,用于自定义样式 |
locale | STRING | 多语言,默认 'zh-CN', 支持 'zh-CN'、'en-US'、'zh-TW'、'ja-JP' |
onChangeChartType | FUNCTION | 图表类型切换回调函数,传递此参数后,图表上方会出现切换图表类型的 icon 按钮 |
parser | OBJECT | 配置项 |
parser.onSelect | FUNCTION | 传递此参数后,图表右上角会出现一个 + 号 icon 按钮,点击按钮会触发此函数 |
parser.selectedText | STRING | 字符串将作为 + 号 icon 按钮的 Tooltip 内容 |
onReady | FUNCTION | 初次渲染时的回调函数 |
常见问题
提示未登录,如何解决?
参考 登录认证 部分,在组件渲染之前需要先完成登录认证。
如何自定义样式?
由于使用了 Shadow DOM,您需要通过 stylesheets 传参进行样式修改, stylesheets 接收字符串或者字符串数组,同时支持样式表链接和样式表内容,例如:
const stylesheets = [ // 可以使用外部常量避免 react 组件重新渲染
'https://cdn.example.com/custom.css',
`.custom-class { color: red; }`,
];
function ReactApp() {
return <Completion
{...chat}
stylesheets={stylesheets} />;
}
在 rspack 项目里怎么使用?
联系售后获取 sdk 包,解压后是 hengshi
文件夹,将 hengshi
目录放到你项目的 public
文件夹内(因为 sdk 有静态资源文件需要被 rspack devServer 提供服务),就可以启动你项目的开发模式了。
然后还需要修改 rspack config 文件:
- 在 rspack config minimizer 的
rspack.SwcJsMinimizerRspackPlugin
配置内增加exclude: /hengshi/
,避免 sdk js 文件被二次压缩(因为二次压缩是无意义的,浪费打包时间)。 - 在 rspack config plugins 里增加
rspack.CopyRspackPlugin
,将hengshi
目录拷贝到打包输出目录,例如:
export default defineConfig({
// ...
optimization: {
minimizer: [
// ...
new rspack.SwcJsMinimizerRspackPlugin({
exclude: /hengshi/,
}),
],
},
plugins: [
// ...
new rspack.CopyRspackPlugin({
patterns: [
{ from: 'public/hengshi', to: 'hengshi' },
],
}),
],
});
示例:
在 vite 项目里怎么使用?
联系售后获取 sdk 包,解压后是 hengshi
文件夹,将 hengshi
目录放到你项目的 src
文件夹内,就可以启动你项目的开发模式了。
然后还需要修改 vite config 文件:
- 在 vite config 的
optimizeDeps
配置内增加exclude: ['hengshi']
,避免 sdk js 文件被 vite 优化(因为 vite 优化是无意义的,浪费打包时间)。 - 安装
vite-plugin-static-copy
插件,然后在 vite config 的plugins
配置内增加
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { viteStaticCopy } from 'vite-plugin-static-copy'
// https://vite.dev/config/
export default defineConfig({
optimizeDeps: {
exclude: ['hengshi'],
},
plugins: [
react(),
viteStaticCopy({
targets: [
{
src: 'src/hengshi',
dest: 'assets',
},
],
}),
],
});
示例:
在 umi 项目里怎么使用?
联系售后获取 sdk 包,解压后是 hengshi
文件夹,将 hengshi
目录同时放到你项目的 public
和 src
文件夹内即可。
示例: