Compare commits
328 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa93624cf7 | ||
|
|
bd5adfa922 | ||
|
|
8db3741725 | ||
|
|
f333be7f05 | ||
|
|
ea9590441b | ||
|
|
dd6c730021 | ||
|
|
1c43272719 | ||
|
|
2ae971d17a | ||
|
|
272815578b | ||
|
|
81e2e4784d | ||
|
|
ff403c5e6a | ||
|
|
d925a8e104 | ||
|
|
d7f0986cec | ||
|
|
278d67945a | ||
|
|
e62f9cbd02 | ||
|
|
131abbb28e | ||
|
|
a54652c072 | ||
|
|
656949f7b8 | ||
|
|
601e1a2ea7 | ||
|
|
c228bc97fb | ||
|
|
75c47dc97e | ||
|
|
b825e41707 | ||
|
|
bb1bfc564d | ||
|
|
e07be55f65 | ||
|
|
0cf5e175cf | ||
|
|
b06b5f252b | ||
|
|
6e55c9951b | ||
|
|
52aeca9dd4 | ||
|
|
87aa938e60 | ||
|
|
006a0edca9 | ||
|
|
58a4a4ca17 | ||
|
|
97bb192696 | ||
|
|
d6f4f20be0 | ||
|
|
d9fec13eae | ||
|
|
634f689f07 | ||
|
|
f4c9787807 | ||
|
|
24bcccdf2b | ||
|
|
6c968d9a24 | ||
|
|
586db5aca1 | ||
|
|
491604527e | ||
|
|
70da85c1e9 | ||
|
|
9dce33ee01 | ||
|
|
e903489a52 | ||
|
|
5b932af6c8 | ||
|
|
84f6bfcb8a | ||
|
|
2f43ddd59b | ||
|
|
45254c3dc4 | ||
|
|
afc6cf04a1 | ||
|
|
5340e89f7d | ||
|
|
4d05697b1c | ||
|
|
68c77760ca | ||
|
|
307480ded2 | ||
|
|
817b25f1a8 | ||
|
|
d457cc7135 | ||
|
|
8f996173b3 | ||
|
|
a06e8fb7a4 | ||
|
|
276bcbe831 | ||
|
|
2c6086edca | ||
|
|
55a6bd93ad | ||
|
|
622fec4e73 | ||
|
|
bdfad88357 | ||
|
|
c8e0b6c474 | ||
|
|
6b7f759071 | ||
|
|
dfe97bf5d5 | ||
|
|
8809022e8c | ||
|
|
fe87d0e433 | ||
|
|
f37264fdbb | ||
|
|
092a252ac4 | ||
|
|
0309c567e6 | ||
|
|
f23439d31f | ||
|
|
03be42b910 | ||
|
|
c3b7711f0a | ||
|
|
0a775af9bb | ||
|
|
15f2d77bec | ||
|
|
2e6611bf8b | ||
|
|
73524283ed | ||
|
|
6038bc8e58 | ||
|
|
5fce7f163e | ||
|
|
3be567ada8 | ||
|
|
2acf1f4351 | ||
|
|
8edc2767f9 | ||
|
|
29339c4c7c | ||
|
|
7836332a97 | ||
|
|
b5fe803059 | ||
|
|
30f1f058c7 | ||
|
|
afe17efde9 | ||
|
|
23e459de94 | ||
|
|
bcbf53d08f | ||
|
|
43aefe7b6e | ||
|
|
b7fda10caf | ||
|
|
824c7a29d8 | ||
|
|
326ad82182 | ||
|
|
92f50f0be2 | ||
|
|
dd0170eecc | ||
|
|
02500aff30 | ||
|
|
c31fa20b02 | ||
|
|
31cdbe2a57 | ||
|
|
5605e6a831 | ||
|
|
aef798c382 | ||
|
|
1922213f8b | ||
|
|
92afc0f366 | ||
|
|
7f9cde3c67 | ||
|
|
effd870897 | ||
|
|
dd7e1692d6 | ||
|
|
a3bbe95643 | ||
|
|
ef39ecb3c6 | ||
|
|
85fe91705b | ||
|
|
7ff21d6156 | ||
|
|
b53dd405a5 | ||
|
|
a53d9c4da2 | ||
|
|
de6b2e8bf9 | ||
|
|
968edea932 | ||
|
|
682419d174 | ||
|
|
e586311744 | ||
|
|
edaa9f7b99 | ||
|
|
0fdbde1cc1 | ||
|
|
3eb1ce7ec5 | ||
|
|
6e3302fed6 | ||
|
|
0d52a8bc5e | ||
|
|
09ac83a62b | ||
|
|
f04864ed7f | ||
|
|
4c968aee18 | ||
|
|
0fd8d11107 | ||
|
|
661b3570a5 | ||
|
|
4ffc6a608b | ||
|
|
2308e1c22b | ||
|
|
2967a6c763 | ||
|
|
327d23ebac | ||
|
|
15c12ca367 | ||
|
|
4351aef5cd | ||
|
|
8186595d84 | ||
|
|
16e58749a7 | ||
|
|
8214b30653 | ||
|
|
7dfa156e30 | ||
|
|
648f4f479e | ||
|
|
dff9ff2caf | ||
|
|
9a4f436b27 | ||
|
|
83e50d6e96 | ||
|
|
2d752f119d | ||
|
|
ab22db62f7 | ||
|
|
cb750c73b9 | ||
|
|
18784d4455 | ||
|
|
08b1c14a1c | ||
|
|
8cf47e9005 | ||
|
|
666841458e | ||
|
|
dafdbeca4b | ||
|
|
5aac8c0546 | ||
|
|
0609b95a28 | ||
|
|
6f9b109022 | ||
|
|
2f6bdcc8c8 | ||
|
|
4886af4bb5 | ||
|
|
b57cf1bf59 | ||
|
|
183349dce8 | ||
|
|
1b9d220abd | ||
|
|
70ee06d622 | ||
|
|
ae7f1bcb3e | ||
|
|
74c9d1df65 | ||
|
|
b270e0ad43 | ||
|
|
7b327df38e | ||
|
|
2ec4f56943 | ||
|
|
367d0a23ca | ||
|
|
4d6b68ee60 | ||
|
|
a34544296a | ||
|
|
e8399875e5 | ||
|
|
d78be0093e | ||
|
|
09fb1aff92 | ||
|
|
b79c2b2fdb | ||
|
|
656adfcf56 | ||
|
|
786458adfe | ||
|
|
31b5a6961b | ||
|
|
babab39710 | ||
|
|
60a2bf7f4f | ||
|
|
9e25e1866d | ||
|
|
781151319c | ||
|
|
d3c3cf86b2 | ||
|
|
5f7d505f20 | ||
|
|
cd8bdc5d1d | ||
|
|
d8117b66ca | ||
|
|
b26a45a7b6 | ||
|
|
37eb0ed357 | ||
|
|
858ee8515d | ||
|
|
7313f8707e | ||
|
|
564f8d0ae2 | ||
|
|
37df8a7fa1 | ||
|
|
8039213380 | ||
|
|
c5a704767d | ||
|
|
20be7f2e45 | ||
|
|
d43823794d | ||
|
|
5e09105a70 | ||
|
|
7d2a98ab85 | ||
|
|
2d302bb468 | ||
|
|
789328b02e | ||
|
|
b93a2a516a | ||
|
|
c8662537ca | ||
|
|
b083bd9724 | ||
|
|
5fd6870cfe | ||
|
|
9004a55b8c | ||
|
|
c349e6384e | ||
|
|
4e298efaa0 | ||
|
|
c7cbb9b72a | ||
|
|
bd5e06350d | ||
|
|
c311dd08e3 | ||
|
|
504a1f4703 | ||
|
|
a67cc9f876 | ||
|
|
e0d2e8031d | ||
|
|
bcec26374f | ||
|
|
a5981a4387 | ||
|
|
0d26dce512 | ||
|
|
6359ec15b3 | ||
|
|
32ca138e6a | ||
|
|
171e0aa408 | ||
|
|
52009a415b | ||
|
|
da809f13b3 | ||
|
|
801aa1f82f | ||
|
|
72c26b71f3 | ||
|
|
3b8181ae10 | ||
|
|
c2a9642393 | ||
|
|
3c04f81147 | ||
|
|
ec28ccf09c | ||
|
|
fa34300401 | ||
|
|
f506ccd2e4 | ||
|
|
f379f7652c | ||
|
|
e8760c81ac | ||
|
|
a9bb294f60 | ||
|
|
0b5f35752b | ||
|
|
7322817cb5 | ||
|
|
437ad1bd9f | ||
|
|
cd20e68480 | ||
|
|
35968475b9 | ||
|
|
78eb3ccc3f | ||
|
|
7cccbabca4 | ||
|
|
cdccfa3e12 | ||
|
|
e8c5455748 | ||
|
|
8e40416e72 | ||
|
|
d058361e01 | ||
|
|
2491f7ff57 | ||
|
|
c5908f6d92 | ||
|
|
7e64d30258 | ||
|
|
437818abce | ||
|
|
5197eb9292 | ||
|
|
3cf01f0c51 | ||
|
|
db815661e8 | ||
|
|
6edbb7c8a7 | ||
|
|
799c445c4b | ||
|
|
70fbf5de3e | ||
|
|
73c7697443 | ||
|
|
8092edab81 | ||
|
|
ef4f45ddb0 | ||
|
|
3e969e4ae5 | ||
|
|
bcd1dfd7bd | ||
|
|
c1dfd78d18 | ||
|
|
39aa1645c9 | ||
|
|
d3afea8c5e | ||
|
|
2499cbdd44 | ||
|
|
3cc3714e94 | ||
|
|
be0aa6d099 | ||
|
|
34d27c1004 | ||
|
|
85f3b4e9e3 | ||
|
|
0fb9a79df9 | ||
|
|
6b805fbdfb | ||
|
|
abe76aeb59 | ||
|
|
5f49bc1aa8 | ||
|
|
71807be01d | ||
|
|
e74f796203 | ||
|
|
041d7da9d8 | ||
|
|
a99d949b29 | ||
|
|
c2a9e2a469 | ||
|
|
80b05db764 | ||
|
|
340cab11b7 | ||
|
|
712233c215 | ||
|
|
b9b915e913 | ||
|
|
044143571f | ||
|
|
06fe805736 | ||
|
|
077881e499 | ||
|
|
f655a57e61 | ||
|
|
0b04bf4929 | ||
|
|
2fcd3b1132 | ||
|
|
568fd6c105 | ||
|
|
221351ec11 | ||
|
|
6ab34a0996 | ||
|
|
6b551ae68b | ||
|
|
2917cde2e5 | ||
|
|
294a4a6cdf | ||
|
|
1e678b7492 | ||
|
|
2ceca7287f | ||
|
|
7f4dd5295b | ||
|
|
ffd628fa82 | ||
|
|
d639e445eb | ||
|
|
b263681dda | ||
|
|
e16413b570 | ||
|
|
63b5186c3e | ||
|
|
ba20316761 | ||
|
|
437dd1c411 | ||
|
|
d0d5f5b77d | ||
|
|
efd9228cc9 | ||
|
|
ebd6132385 | ||
|
|
9098443c83 | ||
|
|
423890a4df | ||
|
|
fb2edeb7d2 | ||
|
|
b861587f01 | ||
|
|
c3738fab45 | ||
|
|
24fba75f28 | ||
|
|
00b6b63e1e | ||
|
|
5dab8fa7d9 | ||
|
|
9a5d71fb5c | ||
|
|
c930efba0c | ||
|
|
ff7c820b1f | ||
|
|
4252725d9d | ||
|
|
deeb3a472c | ||
|
|
763173de44 | ||
|
|
f46e6ad8c8 | ||
|
|
09b31547e1 | ||
|
|
dee2ff8dee | ||
|
|
7f315b95ce | ||
|
|
093e7d1edb | ||
|
|
a4e18f8893 | ||
|
|
c754a36ee5 | ||
|
|
a07d4daed5 | ||
|
|
39023832e3 | ||
|
|
5b8dda60bd | ||
|
|
f7ade54e93 | ||
|
|
4ae7e9dd2e | ||
|
|
7e237b508a | ||
|
|
28bb82e579 | ||
|
|
bcabcb0831 | ||
|
|
c24b03f3da | ||
|
|
63dd03e755 | ||
|
|
f3f1f57b01 |
12
.env
@@ -1,14 +1,8 @@
|
||||
# port
|
||||
VITE_DEV_PORT = '8001'
|
||||
VITE_DEV_PORT = '8080'
|
||||
|
||||
# development path
|
||||
VITE_DEV_PATH = '/'
|
||||
VITE_DEV_PATH = 'https://demo.mtruning.club'
|
||||
|
||||
# production path
|
||||
VITE_PRO_PATH = '/'
|
||||
|
||||
# spa-title
|
||||
VITE_GLOB_APP_TITLE = GoView
|
||||
|
||||
# spa shortname
|
||||
VITE_GLOB_APP_SHORT_NAME = GoView
|
||||
VITE_PRO_PATH = 'https://demo.mtruning.club'
|
||||
1
.gitignore
vendored
@@ -5,4 +5,3 @@ dist-ssr
|
||||
*.local
|
||||
.vscode
|
||||
.idea
|
||||
pnpm-lock
|
||||
209
README.md
@@ -1,153 +1,114 @@
|
||||
## 总览
|
||||
|
||||

|
||||
**`master-fetch` 分支是带有后端接口请求的分支**
|
||||
|
||||
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
|
||||
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
|
||||
|
||||
### 😶 纯 **前端** 分支: **`master`**
|
||||
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)**
|
||||
|
||||
### 👻 携带 **后端** 请求分支: **`master-fetch`**
|
||||
## 使用
|
||||
|
||||
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
|
||||
所有的接口地址位置:`src\api\path\*`
|
||||
|
||||
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
|
||||
|
||||
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
|
||||
|
||||
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
|
||||
|
||||
文档-源码地址:[https://gitee.com/MTrun/go-view-doc](https://gitee.com/MTrun/go-view-doc)
|
||||
|
||||
### 🤯 后端项目
|
||||
|
||||
后端项目 gitee 地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
|
||||
|
||||
接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)
|
||||
|
||||
技术点:
|
||||
|
||||
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
|
||||
|
||||
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
|
||||
|
||||
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
|
||||
|
||||
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
|
||||
|
||||
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
|
||||
|
||||
- 可视化:基于开源图表库[ECharts](https://echarts.apache.org/zh/index.html) 和 [VChart](https://www.visactor.io/vchart) 编写,具有丰富的图表类型和适配大屏的主题效果;
|
||||
|
||||
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
|
||||
|
||||
说明文档:
|
||||

|
||||
|
||||
工作台:
|
||||

|
||||
|
||||
请求配置:
|
||||

|
||||
|
||||
数据过滤:
|
||||

|
||||
|
||||
主题色:
|
||||

|
||||
|
||||
主要技术栈为:
|
||||
|
||||
| 名称 | 版本 | 名称 | 版本 |
|
||||
| ------------------- | ----- | ----------- | ------ |
|
||||
| Vue | 3.2.x | TypeScript4 | 4.6.x |
|
||||
| Vite | 4.2.x | NaiveUI | 2.34.x |
|
||||
| ECharts | 5.3.x | Pinia | 2.0.x |
|
||||
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
|
||||
|
||||
开发环境:
|
||||
|
||||
| 名称 | 版本 | 名称 | 版本 |
|
||||
| ---- | ------- | ------- | ----- |
|
||||
| node | 16.16.x | npm | 8.5.x |
|
||||
| pnpm | 7.1.x | windows | 11 |
|
||||
|
||||
已完成图表:
|
||||
|
||||
| 分类 | 名称 | 名称 | 名称 |
|
||||
| ------ | ---------------- | ---------------- | -------- |
|
||||
| 图表 | 柱状图 | 横向柱状图 | 折线图 |
|
||||
| \* | 单/多 折线面积图 | 饼图 | 水球图 |
|
||||
| \* | 环形图 | NaiveUI 多种进度 | 🤠 |
|
||||
| 信息 | 文字 | 图片 | 😶 |
|
||||
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 |
|
||||
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 |
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
|
||||
|
||||
## 安装
|
||||
|
||||
本项目采用` pnpm` 进行包管理
|
||||
接口地址修改:`.env`
|
||||
|
||||
```shell
|
||||
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
|
||||
#pnpm
|
||||
pnpm install
|
||||
# port
|
||||
VITE_DEV_PORT = '8080'
|
||||
|
||||
#yarn
|
||||
yarn install
|
||||
# development path
|
||||
VITE_DEV_PATH = 'http://127.0.0.1:8080'
|
||||
|
||||
#npm
|
||||
npm install
|
||||
# production path
|
||||
VITE_PRO_PATH = 'http://127.0.0.1:8080'
|
||||
```
|
||||
|
||||
## 启动
|
||||
公共前缀修改:`src\settings\httpSetting.ts`
|
||||
|
||||
```shell
|
||||
#pnpm
|
||||
pnpm dev
|
||||
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
#yarn
|
||||
yarn dev
|
||||
|
||||
#Makefile
|
||||
make dev
|
||||
// 请求前缀
|
||||
export const axiosPre = '/api/goview'
|
||||
```
|
||||
|
||||
## 编译
|
||||
接口封装:`src\api\http.ts`
|
||||
|
||||
```shell
|
||||
#pnpm
|
||||
pnpm run build
|
||||
```ts
|
||||
import axiosInstance from './axios'
|
||||
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
# npm
|
||||
npm run build
|
||||
export const get = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.GET,
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
#yarn
|
||||
yarn run build
|
||||
export const post = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.POST,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#Makefile
|
||||
make dist
|
||||
export const put = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PUT,
|
||||
data: data,
|
||||
headers: {
|
||||
'Content-Type': headersType || ContentTypeEnum.JSON
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const del = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
url: url,
|
||||
method: RequestHttpEnum.DELETE,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取请求函数,默认get
|
||||
export const http = (type?: RequestHttpEnum) => {
|
||||
switch (type) {
|
||||
case RequestHttpEnum.GET:
|
||||
return get
|
||||
|
||||
case RequestHttpEnum.POST:
|
||||
return post
|
||||
|
||||
case RequestHttpEnum.PUT:
|
||||
return put
|
||||
|
||||
case RequestHttpEnum.DELETE:
|
||||
return del
|
||||
|
||||
default:
|
||||
return get
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 代码提交
|
||||
|
||||
- feat: 新功能
|
||||
- fix: 修复 Bug
|
||||
- docs: 文档修改
|
||||
- perf: 性能优化
|
||||
- revert: 版本回退
|
||||
- ci: CICD 集成相关
|
||||
- test: 添加测试代码
|
||||
- refactor: 代码重构
|
||||
- build: 影响项目构建或依赖修改
|
||||
- style: 不影响程序逻辑的代码修改
|
||||
- chore: 不属于以上类型的其他类型(日常事务)
|
||||
* feat: 新功能
|
||||
* fix: 修复 Bug
|
||||
* docs: 文档修改
|
||||
* perf: 性能优化
|
||||
* revert: 版本回退
|
||||
* ci: CICD集成相关
|
||||
* test: 添加测试代码
|
||||
* refactor: 代码重构
|
||||
* build: 影响项目构建或依赖修改
|
||||
* style: 不影响程序逻辑的代码修改
|
||||
* chore: 不属于以上类型的其他类型(日常事务)
|
||||
|
||||
## 交流
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Get the configuration file variable name
|
||||
* @param env
|
||||
*/
|
||||
export const getConfigFileName = (env: Record<string, any>) => {
|
||||
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
|
||||
.toUpperCase()
|
||||
.replace(/\s/g, '');
|
||||
};
|
||||
@@ -7,8 +7,10 @@
|
||||
<meta name="description" content="GoView 是高效、高性能的拖拽式低代码数据可视化开发平台,将页面元素封装为基础组件,无需编写代码即可完成业务需求。">
|
||||
<meta name="keywords" content="GoView,goview,低代码,可视化">
|
||||
<meta name="author" content="奔跑的面条,面条">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1,maximum-scale=1,user-scalable=0">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=yes" media="(min-width: 769px)">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
||||
/>
|
||||
<link rel="icon" href="./favicon.ico" />
|
||||
<title>GoView</title>
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
|
||||
14
package.json
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "go-view",
|
||||
"version": "1.1.11",
|
||||
"version": "2.2.8",
|
||||
"engines": {
|
||||
"node": ">=16.14"
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"preview": "vite preview",
|
||||
"new": "plop --plopfile ./plop/plopfile.js",
|
||||
"postinstall": "husky install",
|
||||
@@ -21,8 +21,6 @@
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@visactor/vchart": "^2.0.0",
|
||||
"@visactor/vchart-theme": "^1.12.2",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.4.0",
|
||||
"color": "^4.2.3",
|
||||
@@ -39,11 +37,11 @@
|
||||
"keymaster": "^1.6.2",
|
||||
"mitt": "^3.0.0",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"naive-ui": "2.40.3",
|
||||
"naive-ui": "2.34.3",
|
||||
"pinia": "^2.0.13",
|
||||
"screenfull": "^6.0.1",
|
||||
"three": "^0.145.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue": "^3.2.31",
|
||||
"vue-demi": "^0.13.1",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "4.0.12",
|
||||
@@ -77,7 +75,7 @@
|
||||
"mockjs": "^1.1.0",
|
||||
"plop": "^3.0.5",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "1.49.11",
|
||||
"sass": "^1.49.11",
|
||||
"sass-loader": "^12.6.0",
|
||||
"typescript": "4.6.3",
|
||||
"vite": "4.3.6",
|
||||
|
||||
10912
pnpm-lock.yaml
generated
@@ -17,7 +17,7 @@
|
||||
import { NConfigProvider } from 'naive-ui'
|
||||
import { GoAppProvider } from '@/components/GoAppProvider'
|
||||
import { I18n } from '@/components/I18n'
|
||||
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
|
||||
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
|
||||
|
||||
// 暗黑主题
|
||||
const darkTheme = useDarkThemeHook()
|
||||
@@ -28,6 +28,9 @@ const overridesTheme = useThemeOverridesHook()
|
||||
// 代码主题
|
||||
const hljsTheme = useCode()
|
||||
|
||||
// 系统全局数据初始化
|
||||
useSystemInit()
|
||||
|
||||
// 全局语言
|
||||
const { locale, dateLocale } = useLang()
|
||||
//测试提交
|
||||
|
||||
14
src/api/axios.config.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
|
||||
// 接口白名单(免登录)
|
||||
export const fetchAllowList = [
|
||||
// 登录
|
||||
`${ModuleTypeEnum.SYSTEM}/login`,
|
||||
// 获取 OSS 接口
|
||||
`${ModuleTypeEnum.SYSTEM}/getOssInfo`,
|
||||
// 预览获取数据
|
||||
`${ModuleTypeEnum.PROJECT}/getData`,
|
||||
]
|
||||
|
||||
// 接口黑名单
|
||||
export const fetchBlockList = []
|
||||
@@ -1,34 +1,93 @@
|
||||
import axios, { AxiosResponse, InternalAxiosRequestConfig, AxiosError } from 'axios'
|
||||
import { ResultEnum } from "@/enums/httpEnum"
|
||||
import { ErrorPageNameMap } from "@/enums/pageEnum"
|
||||
import { redirectErrorPage } from '@/utils'
|
||||
import axios, { AxiosResponse, AxiosRequestConfig, Axios, AxiosError, InternalAxiosRequestConfig } from 'axios'
|
||||
import { RequestHttpHeaderEnum, ResultEnum, ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
import { PageEnum, ErrorPageNameMap } from '@/enums/pageEnum'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { axiosPre } from '@/settings/httpSetting'
|
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
|
||||
import { fetchAllowList } from './axios.config'
|
||||
import includes from 'lodash/includes'
|
||||
|
||||
export interface MyResponseType<T> {
|
||||
code: ResultEnum
|
||||
data: T
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface MyRequestInstance extends Axios {
|
||||
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
|
||||
}
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: import.meta.env.DEV ? import.meta.env.VITE_DEV_PATH : import.meta.env.VITE_PRO_PATH,
|
||||
timeout: ResultEnum.TIMEOUT,
|
||||
})
|
||||
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
|
||||
timeout: ResultEnum.TIMEOUT
|
||||
}) as unknown as MyRequestInstance
|
||||
|
||||
axiosInstance.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
// 白名单校验
|
||||
if (includes(fetchAllowList, config.url)) return config
|
||||
// 获取 token
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
// 重新登录
|
||||
if (!info) {
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
return config
|
||||
}
|
||||
const userInfo = info[SystemStoreEnum.USER_INFO]
|
||||
config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
|
||||
return config
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
Promise.reject(error)
|
||||
(err: AxiosError) => {
|
||||
Promise.reject(err)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
axiosInstance.interceptors.response.use(
|
||||
(res: AxiosResponse) => {
|
||||
// 预览页面错误不进行处理
|
||||
if (isPreview()) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
const { code } = res.data as { code: number }
|
||||
|
||||
if (code === undefined || code === null) return Promise.resolve(res.data)
|
||||
if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
|
||||
// 重定向
|
||||
if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
|
||||
|
||||
// 成功
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 登录过期
|
||||
if (code === ResultEnum.TOKEN_OVERDUE) {
|
||||
window['$message'].error(window['$t']('http.token_overdue_message'))
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 固定错误码重定向
|
||||
if (ErrorPageNameMap.get(code)) {
|
||||
redirectErrorPage(code)
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
|
||||
// 提示错误
|
||||
window['$message'].error(window['$t']((res.data as any).msg))
|
||||
return Promise.resolve(res.data)
|
||||
},
|
||||
(err: AxiosResponse) => {
|
||||
Promise.reject(err)
|
||||
(err: AxiosError) => {
|
||||
const status = err.response?.status
|
||||
switch (status) {
|
||||
case 401:
|
||||
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
|
||||
Promise.reject(err)
|
||||
break
|
||||
|
||||
default:
|
||||
Promise.reject(err)
|
||||
break
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -9,16 +9,16 @@ import {
|
||||
} from '@/enums/httpEnum'
|
||||
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
|
||||
|
||||
export const get = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
export const get = <T = any>(url: string, params?: object) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.GET,
|
||||
params: params
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
export const post = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
export const post = <T = any>(url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.POST,
|
||||
data: data,
|
||||
@@ -28,8 +28,8 @@ export const post = (url: string, data?: object, headersType?: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const patch = (url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance({
|
||||
export const patch = <T = any>(url: string, data?: object, headersType?: string) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PATCH,
|
||||
data: data,
|
||||
@@ -39,8 +39,8 @@ export const patch = (url: string, data?: object, headersType?: string) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const put = (url: string, data?: object, headersType?: ContentTypeEnum) => {
|
||||
return axiosInstance({
|
||||
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.PUT,
|
||||
data: data,
|
||||
@@ -50,8 +50,8 @@ export const put = (url: string, data?: object, headersType?: ContentTypeEnum) =
|
||||
})
|
||||
}
|
||||
|
||||
export const del = (url: string, params?: object) => {
|
||||
return axiosInstance({
|
||||
export const del = <T = any>(url: string, params?: object) => {
|
||||
return axiosInstance<T>({
|
||||
url: url,
|
||||
method: RequestHttpEnum.DELETE,
|
||||
params
|
||||
@@ -82,11 +82,11 @@ export const http = (type?: RequestHttpEnum) => {
|
||||
}
|
||||
const prefix = 'javascript:'
|
||||
// 对输入字符进行转义处理
|
||||
export const translateStr = (target: string | object) => {
|
||||
export const translateStr = (target: string | Record<any, any>) => {
|
||||
if (typeof target === 'string') {
|
||||
if (target.startsWith(prefix)) {
|
||||
const funcStr = target.split(prefix)[1]
|
||||
let result;
|
||||
let result
|
||||
try {
|
||||
result = new Function(`${funcStr}`)()
|
||||
} catch (error) {
|
||||
@@ -100,8 +100,8 @@ export const translateStr = (target: string | object) => {
|
||||
}
|
||||
for (const key in target) {
|
||||
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
||||
const subTarget = (target as any)[key];
|
||||
(target as any)[key] = translateStr(subTarget)
|
||||
const subTarget = target[key]
|
||||
target[key] = translateStr(subTarget)
|
||||
}
|
||||
}
|
||||
return target
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import test from './test.mock'
|
||||
import vchart from './vchart.mock'
|
||||
import { MockMethod } from 'vite-plugin-mock'
|
||||
import { RequestHttpEnum } from '@/enums/httpEnum'
|
||||
|
||||
@@ -23,8 +22,6 @@ export const threeEarth01Url = '/mock/threeEarth01Data'
|
||||
export const sankeyUrl = '/mock/sankey'
|
||||
export const graphUrl = '/mock/graphData'
|
||||
|
||||
export const vchartBarDataUrl = '/mock/vchart/barDataUrl'
|
||||
|
||||
const mockObject: MockMethod[] = [
|
||||
{
|
||||
// 正则
|
||||
@@ -118,11 +115,6 @@ const mockObject: MockMethod[] = [
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => test.graphData
|
||||
},
|
||||
{
|
||||
url: vchartBarDataUrl,
|
||||
method: RequestHttpEnum.GET,
|
||||
response: () => vchart.bar
|
||||
}
|
||||
]
|
||||
|
||||
export default mockObject
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import bar from './vchart/bar.json'
|
||||
|
||||
export default {
|
||||
bar: {
|
||||
code: 0,
|
||||
status: 200,
|
||||
msg: '请求成功',
|
||||
data: bar
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"values": [
|
||||
{ "type": "Nail polish", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Nail polish", "year": "USA", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Eyebrow pencil", "year": "USA", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "Africa", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "EU", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "China", "value|100-900": 3 },
|
||||
{ "type": "Rouge", "year": "USA", "value|100-900": 3 }
|
||||
]
|
||||
}
|
||||
2
src/api/path/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from '@/api/path/project.api'
|
||||
export * from '@/api/path/system.api'
|
||||
99
src/api/path/project.api.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { http } from '@/api/http'
|
||||
import { httpErrorHandle } from '@/utils'
|
||||
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
import { ProjectItem, ProjectDetail } from './project'
|
||||
|
||||
// * 项目列表
|
||||
export const projectListApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 新增项目
|
||||
export const createProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
id: number
|
||||
}>(`${ModuleTypeEnum.PROJECT}/create`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 获取项目
|
||||
export const fetchProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<ProjectDetail>(`${ModuleTypeEnum.PROJECT}/getData`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 保存项目
|
||||
export const saveProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(
|
||||
`${ModuleTypeEnum.PROJECT}/save/data`,
|
||||
data,
|
||||
ContentTypeEnum.FORM_URLENCODED
|
||||
)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改项目基础信息
|
||||
export const updateProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 删除项目
|
||||
export const deleteProjectApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.DELETE)(`${ModuleTypeEnum.PROJECT}/delete`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 修改发布状态 [-1未发布,1发布]
|
||||
export const changeProjectReleaseApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/publish`, data)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 上传文件
|
||||
export const uploadFile = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<{
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
fileName: string,
|
||||
fileurl: string,
|
||||
}>(`${ModuleTypeEnum.PROJECT}/upload`, data, ContentTypeEnum.FORM_DATA)
|
||||
return res
|
||||
} catch {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
39
src/api/path/project.d.ts
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
export type ProjectItem = {
|
||||
/**
|
||||
* 项目 id
|
||||
*/
|
||||
id: string
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
projectName: string
|
||||
/**
|
||||
* 项目状态:\
|
||||
* -1: 未发布\
|
||||
* 1: 已发布
|
||||
*/
|
||||
state: number
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string
|
||||
/**
|
||||
* 预览图片url
|
||||
*/
|
||||
indexImage: string
|
||||
/**
|
||||
* 创建者 id
|
||||
*/
|
||||
createUserId: string
|
||||
/**
|
||||
* 项目备注
|
||||
*/
|
||||
remarks: string
|
||||
}
|
||||
|
||||
export interface ProjectDetail extends ProjectItem {
|
||||
/**
|
||||
* 项目参数
|
||||
*/
|
||||
content: string
|
||||
}
|
||||
39
src/api/path/system.api.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { http } from '@/api/http'
|
||||
import { httpErrorHandle } from '@/utils'
|
||||
import { RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
|
||||
import { LoginResult } from './system'
|
||||
|
||||
// * 登录
|
||||
export const loginApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.POST)<LoginResult>(`${ModuleTypeEnum.SYSTEM}/login`, data)
|
||||
return res
|
||||
} catch (err) {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 登出
|
||||
export const logoutApi = async () => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.SYSTEM}/logout`)
|
||||
return res
|
||||
} catch (err) {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
|
||||
// * 获取 oss 上传接口
|
||||
export const ossUrlApi = async (data: object) => {
|
||||
try {
|
||||
const res = await http(RequestHttpEnum.GET)<{
|
||||
/**
|
||||
* bucket 地址
|
||||
*/
|
||||
bucketURL?: string
|
||||
}>(`${ModuleTypeEnum.SYSTEM}/getOssInfo`, data)
|
||||
return res
|
||||
} catch (err) {
|
||||
httpErrorHandle()
|
||||
}
|
||||
}
|
||||
26
src/api/path/system.d.ts
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface LoginResult {
|
||||
token: {
|
||||
/**
|
||||
* token 值
|
||||
*/
|
||||
tokenValue: string
|
||||
/**
|
||||
* token key
|
||||
*/
|
||||
tokenName: string
|
||||
}
|
||||
userinfo: {
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
nickname: string
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
username: string
|
||||
/**
|
||||
* 用户 id
|
||||
*/
|
||||
id: string
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 46 KiB |
@@ -27,7 +27,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { h, ref } from 'vue'
|
||||
import { NAvatar, NText } from 'naive-ui'
|
||||
import { renderIcon } from '@/utils'
|
||||
import { renderIcon, getLocalStorage } from '@/utils'
|
||||
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { StorageEnum } from '@/enums/storageEnum'
|
||||
import { logout, renderLang } from '@/utils'
|
||||
import { GoSystemSet } from '@/components/GoSystemSet/index'
|
||||
import { GoSystemInfo } from '@/components/GoSystemInfo/index'
|
||||
@@ -64,7 +66,17 @@ const renderUserInfo = () => {
|
||||
}),
|
||||
h('div', null, [
|
||||
h('div', null, [
|
||||
h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
|
||||
h(NText, { depth: 2 }, {
|
||||
default: () => {
|
||||
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
|
||||
if (info) {
|
||||
return info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_NAME];
|
||||
}
|
||||
else {
|
||||
return 'admin';
|
||||
}
|
||||
}
|
||||
})
|
||||
])
|
||||
])
|
||||
]
|
||||
@@ -137,4 +149,4 @@ const handleSelect = (key: string) => {
|
||||
cursor: pointer;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,3 +0,0 @@
|
||||
import GoVChart from './index.vue'
|
||||
|
||||
export { GoVChart }
|
||||
@@ -1,250 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
ref="vChartRef"
|
||||
v-on="{
|
||||
...Object.fromEntries(event.map((eventName: string) => [eventName, (eventData: MouseEvent) => eventHandlers(eventData, eventName)]))
|
||||
}"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, PropType, watch, onBeforeUnmount, nextTick, toRaw, toRefs } from 'vue'
|
||||
import { VChart, type IVChart, type IInitOption } from '@visactor/vchart'
|
||||
import { transformHandler } from './transformProps'
|
||||
import { IOption } from '@/packages/components/VChart/index.d'
|
||||
import { registerChartsAndComponents } from './register'
|
||||
|
||||
// VChart按需加载: 注册图表及组件
|
||||
registerChartsAndComponents()
|
||||
|
||||
// 事件说明 v1.13.0 https://www.visactor.io/vchart/api/API/event
|
||||
const event = [
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'mouseupoutside',
|
||||
'rightdown',
|
||||
'rightup',
|
||||
'rightupoutside',
|
||||
'click',
|
||||
'dblclick',
|
||||
'mousemove',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'mouseenter',
|
||||
'mouseleave',
|
||||
'wheel',
|
||||
'touchstart',
|
||||
'touchend',
|
||||
'touchendoutside',
|
||||
'touchmove',
|
||||
'touchcancel',
|
||||
'tap',
|
||||
'dragstart',
|
||||
'dragend',
|
||||
'drag',
|
||||
'dragenter',
|
||||
'dragleave',
|
||||
'dragover',
|
||||
'drop',
|
||||
'pan',
|
||||
'panstart',
|
||||
'panend',
|
||||
'press',
|
||||
'pressup',
|
||||
'pressend',
|
||||
'pinch',
|
||||
'pinchstart',
|
||||
'pinchend',
|
||||
'swipe',
|
||||
'dimensionHover',
|
||||
'dimensionClick',
|
||||
'dataZoomChange',
|
||||
'scrollBarChange',
|
||||
'brushStart',
|
||||
'brushChange',
|
||||
'brushEnd',
|
||||
'brushClear',
|
||||
'drill',
|
||||
'legendItemClick',
|
||||
'legendItemHover',
|
||||
'legendItemUnHover',
|
||||
'legendFilter',
|
||||
'initialized',
|
||||
'rendered',
|
||||
'renderFinished',
|
||||
'animationFinished',
|
||||
'layoutStart',
|
||||
'layoutEnd',
|
||||
'afterResizef'
|
||||
]
|
||||
const emit = defineEmits([
|
||||
'mousedown',
|
||||
'mouseup',
|
||||
'mouseupoutside',
|
||||
'rightdown',
|
||||
'rightup',
|
||||
'rightupoutside',
|
||||
'click',
|
||||
'dblclick',
|
||||
'mousemove',
|
||||
'mouseover',
|
||||
'mouseout',
|
||||
'mouseenter',
|
||||
'mouseleave',
|
||||
'wheel',
|
||||
'touchstart',
|
||||
'touchend',
|
||||
'touchendoutside',
|
||||
'touchmove',
|
||||
'touchcancel',
|
||||
'tap',
|
||||
'dragstart',
|
||||
'dragend',
|
||||
'drag',
|
||||
'dragenter',
|
||||
'dragleave',
|
||||
'dragover',
|
||||
'drop',
|
||||
'pan',
|
||||
'panstart',
|
||||
'panend',
|
||||
'press',
|
||||
'pressup',
|
||||
'pressend',
|
||||
'pinch',
|
||||
'pinchstart',
|
||||
'pinchend',
|
||||
'swipe',
|
||||
'dimensionHover',
|
||||
'dimensionClick',
|
||||
'dataZoomChange',
|
||||
'scrollBarChange',
|
||||
'brushStart',
|
||||
'brushChange',
|
||||
'brushEnd',
|
||||
'brushClear',
|
||||
'drill',
|
||||
'legendItemClick',
|
||||
'legendItemHover',
|
||||
'legendItemUnHover',
|
||||
'legendFilter',
|
||||
'initialized',
|
||||
'rendered',
|
||||
'renderFinished',
|
||||
'animationFinished',
|
||||
'layoutStart',
|
||||
'layoutEnd',
|
||||
'afterResizef'
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object as PropType<
|
||||
IOption & {
|
||||
dataset: any
|
||||
}
|
||||
>,
|
||||
required: true
|
||||
},
|
||||
initOptions: {
|
||||
type: Object as PropType<
|
||||
IInitOption & {
|
||||
deepWatch?: boolean | number
|
||||
}
|
||||
>,
|
||||
required: false,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const vChartRef = ref()
|
||||
let chart: IVChart
|
||||
|
||||
// 解构 props.option,排除 dataset
|
||||
const { dataset, ...restOfOption } = toRefs(props.option)
|
||||
|
||||
// 排除 data 监听
|
||||
watch(
|
||||
() => ({
|
||||
...restOfOption
|
||||
}),
|
||||
() => {
|
||||
nextTick(() => {
|
||||
createOrUpdateChart(props.option)
|
||||
})
|
||||
},
|
||||
{
|
||||
deep: props.initOptions?.deepWatch || true,
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => dataset.value,
|
||||
() => {
|
||||
nextTick(() => {
|
||||
createOrUpdateChart(props.option)
|
||||
})
|
||||
},
|
||||
{
|
||||
deep: false
|
||||
}
|
||||
)
|
||||
|
||||
// 更新
|
||||
const createOrUpdateChart = (
|
||||
chartProps: IOption & {
|
||||
dataset: any
|
||||
}
|
||||
) => {
|
||||
if (vChartRef.value && !chart) {
|
||||
const spec = transformHandler[chartProps.category || '']?.(chartProps)
|
||||
chart = new VChart(
|
||||
{ ...spec, data: chartProps.dataset },
|
||||
{
|
||||
dom: vChartRef.value,
|
||||
...props.initOptions
|
||||
}
|
||||
)
|
||||
chart.renderSync()
|
||||
return true
|
||||
} else if (chart) {
|
||||
const spec = transformHandler[chartProps.category || '']?.(chartProps)
|
||||
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined }, false, undefined, {
|
||||
change: false,
|
||||
reMake: true,
|
||||
reAnimate: true
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 刷新
|
||||
const refresh = () => {
|
||||
if (chart) {
|
||||
chart.renderSync()
|
||||
}
|
||||
}
|
||||
|
||||
// 抛出事件
|
||||
const eventHandlers = (eventData: MouseEvent, eventName: string) => {
|
||||
if (event.includes(eventName)) emit(eventName as any, eventData)
|
||||
}
|
||||
|
||||
// 卸载
|
||||
onBeforeUnmount(() => {
|
||||
if (chart) {
|
||||
chart.release()
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
// 重刷新
|
||||
refresh,
|
||||
release: () => {
|
||||
if (chart) {
|
||||
chart.release()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,29 +0,0 @@
|
||||
import { VChart } from '@visactor/vchart/esm/core';
|
||||
import { registerBarChart, registerAreaChart, registerLineChart, registerPieChart, registerFunnelChart, registerWordCloudChart, registerScatterChart } from '@visactor/vchart/esm/chart';
|
||||
import { registerTooltip, registerCartesianCrossHair, registerDiscreteLegend, registerLabel } from '@visactor/vchart/esm/component';
|
||||
import { registerDomTooltipHandler } from '@visactor/vchart/esm/plugin/components';
|
||||
import { registerAnimate } from '@visactor/vchart';
|
||||
|
||||
export const registerChartsAndComponents = () => {
|
||||
VChart.useRegisters([
|
||||
// 图表
|
||||
registerBarChart,
|
||||
registerAreaChart,
|
||||
registerLineChart,
|
||||
registerPieChart,
|
||||
registerScatterChart,
|
||||
registerFunnelChart,
|
||||
registerWordCloudChart,
|
||||
|
||||
// 组件
|
||||
registerTooltip,
|
||||
registerDomTooltipHandler,
|
||||
registerCartesianCrossHair,
|
||||
registerDiscreteLegend,
|
||||
registerLabel,
|
||||
|
||||
// 动画
|
||||
registerAnimate
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
// console.log('spec-area-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [
|
||||
{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
// paddingInner: 0.5
|
||||
},
|
||||
{
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}
|
||||
]
|
||||
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
|
||||
spec.label = {
|
||||
...spec.label,
|
||||
style: {
|
||||
...spec.label?.style,
|
||||
lineWidth: 0
|
||||
}
|
||||
}
|
||||
// console.log('spec-bar-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Datum } from "@visactor/vchart/esm/typings"
|
||||
import { cloneDeep } from "lodash"
|
||||
const INNER_RADIUS = 0.75
|
||||
const OUTER_RADIUS = 0.68
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// label
|
||||
spec.label = {
|
||||
visible: true,
|
||||
}
|
||||
|
||||
// console.log('spec-funnel-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
import { ChatCategoryEnum, IOption } from "@/packages/components/VChart/index.d";
|
||||
import bars from './bars'
|
||||
import pies from './pies'
|
||||
import lines from './lines'
|
||||
import areas from './areas'
|
||||
import funnels from "./funnels";
|
||||
import wordClouds from "./wordClouds";
|
||||
import scatters from "./scatters";
|
||||
export const transformHandler: {
|
||||
[key: string]: (args: IOption) => any
|
||||
} = {
|
||||
[ChatCategoryEnum.BAR]: bars,
|
||||
[ChatCategoryEnum.PIE]: pies,
|
||||
[ChatCategoryEnum.LINE]: lines,
|
||||
[ChatCategoryEnum.AREA]: areas,
|
||||
[ChatCategoryEnum.FUNNEL]: funnels,
|
||||
[ChatCategoryEnum.WORDCLOUD]: wordClouds,
|
||||
[ChatCategoryEnum.SCATTER]: scatters,
|
||||
// todo: more charts handler
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [
|
||||
{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps
|
||||
},
|
||||
{
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}
|
||||
]
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
|
||||
spec.label = {
|
||||
...spec.label,
|
||||
style: {
|
||||
...spec.label?.style,
|
||||
lineWidth: 0
|
||||
}
|
||||
}
|
||||
// console.log('spec-line-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
import { Datum } from '@visactor/vchart/esm/typings'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
delete spec.category
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
if (spec.extensionMark) {
|
||||
// extensionMark
|
||||
spec.extensionMark = [
|
||||
{
|
||||
name: 'arc_inner_shadow',
|
||||
type: 'arc',
|
||||
dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
startAngle: (datum: Datum) => {
|
||||
return datum['__VCHART_ARC_START_ANGLE']
|
||||
},
|
||||
endAngle: (datum: Datum) => {
|
||||
return datum['__VCHART_ARC_END_ANGLE']
|
||||
},
|
||||
innerRadius: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * spec.innerRadius - 30
|
||||
},
|
||||
outerRadius: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * spec.innerRadius
|
||||
},
|
||||
fillOpacity: 0.3,
|
||||
fill: (datum: Datum, context: any) => {
|
||||
return context.seriesColor(datum[spec.seriesField])
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arc_inner',
|
||||
type: 'symbol',
|
||||
// dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
size: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * 2 * spec.innerRadius - 100
|
||||
},
|
||||
fillOpacity: 0,
|
||||
lineWidth: 1,
|
||||
strokeOpacity: 0.5,
|
||||
stroke: {
|
||||
gradient: 'conical',
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI * 2,
|
||||
stops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#FFF',
|
||||
opacity: 0
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#FFF',
|
||||
opacity: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'arc_outer',
|
||||
type: 'symbol',
|
||||
// dataId: 'id0',
|
||||
style: {
|
||||
interactive: false,
|
||||
size: (datum: Datum, context: any) => {
|
||||
return context.getLayoutRadius() * 2 * spec.outerRadius + 50
|
||||
},
|
||||
fillOpacity: 0,
|
||||
lineWidth: 1,
|
||||
strokeOpacity: 0.5,
|
||||
stroke: {
|
||||
gradient: 'conical',
|
||||
startAngle: 0,
|
||||
endAngle: Math.PI * 2,
|
||||
stops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#FFF',
|
||||
opacity: 0
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#FFF',
|
||||
opacity: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
visible: true,
|
||||
x: (datum: Datum, context: any) => {
|
||||
return context.getCenter().x()
|
||||
},
|
||||
y: (datum: Datum, context: any) => {
|
||||
return context.getCenter().y()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
return spec
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
// axis
|
||||
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
|
||||
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
|
||||
spec.axes = [{
|
||||
orient: 'bottom',
|
||||
...restXAxisProps,
|
||||
label: {
|
||||
formatMethod: (value: string) => Number(value).toFixed(2)
|
||||
}
|
||||
}, {
|
||||
orient: 'left',
|
||||
...restYAxisProps
|
||||
}]
|
||||
|
||||
delete spec.xAxis
|
||||
delete spec.yAxis
|
||||
// console.log('spec-scatter-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Datum } from "@visactor/vchart/esm/typings"
|
||||
import { cloneDeep } from "lodash"
|
||||
|
||||
export default (chartProps: any) => {
|
||||
const spec = cloneDeep(chartProps)
|
||||
|
||||
// tooltip
|
||||
const keyFill = spec.tooltip.style.keyLabel.fill
|
||||
const valueFill = spec.tooltip.style.valueLabel.fill
|
||||
const titleFill = spec.tooltip.style.titleLabel.keyFill
|
||||
delete spec.tooltip.style.keyLabel.fill
|
||||
delete spec.tooltip.style.valueLabel.fill
|
||||
delete spec.tooltip.style.titleLabel.keyFill
|
||||
spec.tooltip.style.keyLabel.fontColor = keyFill
|
||||
spec.tooltip.style.valueLabel.fontColor = valueFill
|
||||
spec.tooltip.style.titleLabel.fontColor = titleFill
|
||||
|
||||
|
||||
// console.log('spec-word-cloud-transform', spec)
|
||||
return spec
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<collapse-item :name="axis.name">
|
||||
<template #header>
|
||||
<n-switch v-model:value="axis.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="单位">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.unit.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="内容">
|
||||
<n-input v-model:value="axis.unit.text" size="small"></n-input>
|
||||
</setting-item>
|
||||
<FontStyle :style="toRefs(axis.unit.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴标签">
|
||||
<setting-item v-if="axis.label" name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.label.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item v-if="axis.label" name="角度">
|
||||
<n-input-number v-model:value="axis.label.style.angle" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
<FontStyle v-if="axis.label" :style="toRefs(axis.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴标题">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.title.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="内容">
|
||||
<n-input v-model:value="axis.title.style.text" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="axis.title.position" :options="legendsConfig.position" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="角度">
|
||||
<n-input-number v-model:value="axis.title.angle" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
<FontStyle :style="toRefs(axis.title.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="轴线">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.domainLine.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name=""> </setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="axis.domainLine.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="axis.domainLine.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="网格线">
|
||||
<setting-item name="可见性">
|
||||
<n-space>
|
||||
<n-switch v-model:value="axis.grid.visible" size="small"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="开启虚线">
|
||||
<n-space>
|
||||
<n-switch v-model:value="isLineDashRef" size="small" @update:value="changeLineDash"></n-switch>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="axis.grid.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="axis.grid.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, ref, toRefs } from 'vue'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
const props = defineProps({
|
||||
axis: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 判断是否是虚线
|
||||
const isDash = (data: undefined | Array<number>) => {
|
||||
if (!data || data.length === 0 || data[0] === 0) return false
|
||||
return true
|
||||
}
|
||||
|
||||
// 虚线
|
||||
const isLineDashRef = ref(isDash(props.axis.grid.style.lineDash))
|
||||
|
||||
const changeLineDash = (data: boolean) => {
|
||||
if (data) {
|
||||
props.axis.grid.style.lineDash = [4, 4] // 设置为虚线
|
||||
} else {
|
||||
props.axis.grid.style.lineDash = [0] // 设置为实线
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,52 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.bar">
|
||||
<collapse-item name="柱体">
|
||||
<SettingItemBox name="样式">
|
||||
<setting-item v-if="'width' in optionData.bar.style" name="宽度">
|
||||
<n-input-number v-model:value="optionData.bar.style.width" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item v-if="'height' in (optionData.bar.style as any)" name="高度">
|
||||
<n-input-number v-model:value="(optionData.bar.style as any).height" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="圆角大小">
|
||||
<n-input-number v-model:value="optionData.bar.style.cornerRadius" size="small" :min="0"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="填充透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.bar.style.fillOpacity"
|
||||
:step="0.1"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="1"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="整体透明度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.bar.style.opacity"
|
||||
:step="0.1"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="1"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="纹理类型">
|
||||
<n-select v-model:value="optionData.bar.style.texture" :options="styleConfig.texture" size="small"></n-select>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,46 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.label">
|
||||
<collapse-item name="标签">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.label.visible" size="small"></n-switch>
|
||||
</template>
|
||||
|
||||
<setting-item-box name="布局">
|
||||
<setting-item name="位置">
|
||||
<n-select
|
||||
v-model:value="optionData.label.position"
|
||||
size="small"
|
||||
:options="positionOptions || labelConfig.barPosition"
|
||||
/>
|
||||
</setting-item>
|
||||
|
||||
<setting-item name="间距">
|
||||
<n-input-number v-model:value="optionData.label.offset" :min="1" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
|
||||
<setting-item-box name="字体">
|
||||
<FontStyle :style="toRefs(optionData.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { labelConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
},
|
||||
positionOptions: {
|
||||
type: Array,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<div v-if="optionData.legends">
|
||||
<div v-for="(legendItem, index) in optionData.legends" :key="index">
|
||||
<collapse-item name="图例">
|
||||
<template #header>
|
||||
<n-switch v-model:value="legendItem.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="布局">
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="legendItem.orient" size="small" :options="legendsConfig.orient" />
|
||||
</setting-item>
|
||||
<setting-item name="对齐方式">
|
||||
<n-select v-model:value="legendItem.position" size="small" :options="legendsConfig.position" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="项配置">
|
||||
<FontStyle :style="toRefs(legendItem.item.label.style)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,33 +0,0 @@
|
||||
<template>
|
||||
<collapse-item name="线条" v-if="optionData.line">
|
||||
<SettingItemBox name="样式">
|
||||
<setting-item name="宽度">
|
||||
<n-input-number v-model:value="optionData.line.style.lineWidth" size="small" :min="1"></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="线条类型">
|
||||
<n-select
|
||||
v-model:value="optionData.line.style.curveType"
|
||||
:options="styleConfig.curveType"
|
||||
size="small"
|
||||
></n-select>
|
||||
</setting-item>
|
||||
<setting-item name="末端样式">
|
||||
<n-select v-model:value="optionData.line.style.lineCap" :options="styleConfig.lineCap" size="small"></n-select>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
</collapse-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<template v-if="optionData.point">
|
||||
<collapse-item name="实心点(图元)">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.point.visible" size="small"></n-switch>
|
||||
</template>
|
||||
|
||||
<setting-item-box name="样式">
|
||||
<setting-item name="位置">
|
||||
<n-select v-model:value="optionData.point.style.symbolType" size="small" :options="styleConfig.symbolType" />
|
||||
</setting-item>
|
||||
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="optionData.point.style.size" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="填充透明度">
|
||||
<n-input-number v-model:value="optionData.point.style.fillOpacity" :step="0.1" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框宽度">
|
||||
<n-input-number v-model:value="optionData.point.style.lineWidth" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框颜色">
|
||||
<n-color-picker v-model:value="optionData.point.style.stroke" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="边框透明度">
|
||||
<n-input-number v-model:value="optionData.point.style.strokeOpacity" :step="0.1" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="偏移X">
|
||||
<n-input-number v-model:value="optionData.point.style.dx" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="偏移Y">
|
||||
<n-input-number v-model:value="optionData.point.style.dy" :min="0" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import { styleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
},
|
||||
positionOptions: {
|
||||
type: Array,
|
||||
required: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<div v-if="optionData.tooltip">
|
||||
<collapse-item name="提示框">
|
||||
<template #header>
|
||||
<n-switch v-model:value="optionData.tooltip.visible" size="small"></n-switch>
|
||||
</template>
|
||||
<setting-item-box name="框">
|
||||
<setting-item name="填充">
|
||||
<n-color-picker v-model:value="optionData.tooltip.style.panel.backgroundColor" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="瞄边">
|
||||
<n-color-picker v-model:value="optionData.tooltip.style.panel.border.color" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="粗细">
|
||||
<n-input-number v-model:value="optionData.tooltip.style.panel.border.width" :min="0" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="圆角">
|
||||
<n-input-number v-model:value="optionData.tooltip.style.panel.border.radius" :min="0" size="small" />
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="标题">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.titleLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="名称">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.keyLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="值">
|
||||
<FontStyle :style="toRefs(optionData.tooltip.style.valueLabel)"></FontStyle>
|
||||
</setting-item-box>
|
||||
</collapse-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs } from 'vue'
|
||||
import FontStyle from './common/FontStyle.vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<!-- 图例 -->
|
||||
<Legends :optionData="optionData"></Legends>
|
||||
<Tooltip :optionData="optionData"></Tooltip>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
|
||||
import Legends from './Legends.vue'
|
||||
import Tooltip from './Tooltip.vue'
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<vChartGlobalThemeJsonType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<!-- todo 补充常用配置项 -->
|
||||
<template v-if="style">
|
||||
<setting-item name="颜色">
|
||||
<n-color-picker v-model:value="style.fill.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="style.fontSize.value" :min="1" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字体">
|
||||
<n-select v-model:value="style.fontFamily.value" :options="fontStyleConfig.fontFamily" size="small" />
|
||||
</setting-item>
|
||||
<setting-item name="字重">
|
||||
<n-select v-model:value="style.fontWeight.value" :options="fontStyleConfig.fontWeight" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.dx" name="X轴偏移">
|
||||
<n-input-number v-model:value="style.dx.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.dy" name="Y轴偏移">
|
||||
<n-input-number v-model:value="style.dy.value" size="small" />
|
||||
</setting-item>
|
||||
<setting-item v-if="style?.angle" name="旋转">
|
||||
<n-input-number v-model:value="style.angle.value" :step="0.1" :min="0" :max="360" size="small" />
|
||||
</setting-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { fontStyleConfig } from '@/packages/chartConfiguration/vcharts/index'
|
||||
import { FontType } from '@/settings/vchartThemes/index'
|
||||
import { SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
defineProps({
|
||||
style: {
|
||||
type: Object as PropType<any>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,84 +0,0 @@
|
||||
<template>
|
||||
<setting-item name="间距">
|
||||
<n-input v-model:value="paddingArray" size="small" @update:value="updateHandle"/>
|
||||
</setting-item>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ICartesianTitle } from '@visactor/vchart/esm/component/axis'
|
||||
import { forEach, isNumber } from 'lodash'
|
||||
import { SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { PropType, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
axis: {
|
||||
type: Object as PropType<ICartesianTitle>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
// 解析间距
|
||||
const paddingInit = (padding: ICartesianTitle['padding']) => {
|
||||
const arr = [0, 0, 0, 0]
|
||||
if (!padding) {
|
||||
return arr
|
||||
}
|
||||
if (isNumber(padding)) {
|
||||
arr.forEach((item, index) => {
|
||||
arr[index] = padding
|
||||
})
|
||||
} else if (Array.isArray(padding)) {
|
||||
if (padding.length === 1) {
|
||||
arr.forEach((item, index) => {
|
||||
arr[index] = padding[0]
|
||||
})
|
||||
} else if (padding.length === 2) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[0]
|
||||
arr[3] = padding[1]
|
||||
} else if (padding.length === 3) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[2]
|
||||
arr[3] = padding[1]
|
||||
} else if (padding.length === 4) {
|
||||
arr[0] = padding[0]
|
||||
arr[1] = padding[1]
|
||||
arr[2] = padding[2]
|
||||
arr[3] = padding[3]
|
||||
}
|
||||
}
|
||||
|
||||
// 转成字符串,逗号分隔
|
||||
return arr.map(item => item.toString()).join(',')
|
||||
}
|
||||
|
||||
// 间距处理
|
||||
const paddingArray = ref(paddingInit(props.axis.padding))
|
||||
|
||||
// 字符串转成数组
|
||||
const paddingArrayToNumber = (padding: string) => {
|
||||
const arr = padding.split(',').map(item => parseFloat(item.trim()))
|
||||
if (arr.length === 1) {
|
||||
return [arr[0], arr[0], arr[0], arr[0]]
|
||||
} else if (arr.length === 2) {
|
||||
return [arr[0], arr[1], arr[0], arr[1]]
|
||||
} else if (arr.length === 3) {
|
||||
return [arr[0], arr[1], arr[2], arr[1]]
|
||||
} else if (arr.length === 4) {
|
||||
return arr
|
||||
}
|
||||
return [0, 0, 0, 0]
|
||||
}
|
||||
|
||||
const updateHandle = (value: string) => {
|
||||
const padding = paddingArrayToNumber(value)
|
||||
forEach(padding, (item, index) => {
|
||||
if (isNaN(item)) {
|
||||
padding[index] = 0
|
||||
}
|
||||
})
|
||||
props.axis.padding = padding
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +0,0 @@
|
||||
import VChartGlobalSetting from './VChartGlobalSetting.vue'
|
||||
import Axis from './Axis.vue'
|
||||
import Label from './Label.vue'
|
||||
import Bar from './Bar.vue'
|
||||
import Line from './Line.vue'
|
||||
import Point from './Point.vue'
|
||||
|
||||
export { VChartGlobalSetting, Axis, Label, Bar, Line, Point }
|
||||
@@ -48,7 +48,6 @@ export enum MenuEnum {
|
||||
UN_GROUP = 'unGroup',
|
||||
// 后退
|
||||
BACK = 'back',
|
||||
// 前进
|
||||
FORWORD = 'forward',
|
||||
// 保存
|
||||
SAVE = 'save',
|
||||
@@ -84,3 +83,15 @@ export enum MacKeyboard {
|
||||
ALT_SOURCE_KEY = '⌥',
|
||||
SPACE = 'Space'
|
||||
}
|
||||
|
||||
// 同步状态枚举
|
||||
export enum SyncEnum {
|
||||
// 等待
|
||||
PENDING,
|
||||
// 开始
|
||||
START,
|
||||
// 成功
|
||||
SUCCESS,
|
||||
// 失败
|
||||
FAILURE
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
/**
|
||||
* @description: 请求结果集
|
||||
*/
|
||||
// 模块 Path 前缀分类
|
||||
export enum ModuleTypeEnum {
|
||||
SYSTEM = 'sys',
|
||||
PROJECT = 'project',
|
||||
}
|
||||
|
||||
// 请求结果集
|
||||
export enum ResultEnum {
|
||||
DATA_SUCCESS = 0,
|
||||
SUCCESS = 200,
|
||||
SERVER_ERROR = 500,
|
||||
SERVER_FORBIDDEN = 403,
|
||||
NOT_FOUND = 404,
|
||||
TIMEOUT = 60000
|
||||
TOKEN_OVERDUE = 886,
|
||||
TIMEOUT = 60000,
|
||||
}
|
||||
|
||||
// 数据相关
|
||||
@@ -28,9 +33,13 @@ export enum RequestContentTypeEnum {
|
||||
SQL = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 请求方法
|
||||
*/
|
||||
// 头部
|
||||
export enum RequestHttpHeaderEnum {
|
||||
TOKEN = 'Token',
|
||||
COOKIE = 'Cookie'
|
||||
}
|
||||
|
||||
// 请求方法
|
||||
export enum RequestHttpEnum {
|
||||
GET = 'get',
|
||||
POST = 'post',
|
||||
@@ -111,9 +120,7 @@ export type RequestParams = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 常用的contentTyp类型
|
||||
*/
|
||||
// 常用的contentTyp类型
|
||||
export enum ContentTypeEnum {
|
||||
// json
|
||||
JSON = 'application/json;charset=UTF-8',
|
||||
|
||||
@@ -26,10 +26,15 @@ export enum PageEnum {
|
||||
//重定向
|
||||
REDIRECT = '/redirect',
|
||||
REDIRECT_NAME = 'Redirect',
|
||||
|
||||
// 未发布
|
||||
REDIRECT_UN_PUBLISH = '/redirect/unPublish',
|
||||
REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
|
||||
|
||||
// 重载
|
||||
RELOAD = '/reload',
|
||||
RELOAD_NAME = 'Reload',
|
||||
|
||||
|
||||
// 首页
|
||||
BASE_HOME = '/project',
|
||||
BASE_HOME_NAME = 'Project',
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
export enum StorageEnum {
|
||||
// 全局设置
|
||||
GO_SYSTEM_SETTING_STORE = 'GO_SYSTEM_SETTING',
|
||||
// token 等信息
|
||||
GO_ACCESS_TOKEN_STORE = 'GO_ACCESS_TOKEN',
|
||||
GO_SETTING_STORE = 'GO_SETTING',
|
||||
// 登录信息
|
||||
GO_LOGIN_INFO_STORE = 'GO_LOGIN_INFO',
|
||||
GO_SYSTEM_STORE = 'GO_SYSTEM',
|
||||
// 语言
|
||||
GO_LANG_STORE = 'GO_LANG',
|
||||
// 当前选择的主题
|
||||
|
||||
@@ -2,8 +2,8 @@ export * from '@/hooks/useTheme.hook'
|
||||
export * from '@/hooks/usePreviewScale.hook'
|
||||
export * from '@/hooks/useCode.hook'
|
||||
export * from '@/hooks/useChartDataFetch.hook'
|
||||
export * from '@/hooks/useSystemInit.hook'
|
||||
export * from '@/hooks/useChartDataPondFetch.hook'
|
||||
export * from '@/hooks/useLifeHandler.hook'
|
||||
export * from '@/hooks/useLang.hook'
|
||||
export * from '@/hooks/useChartInteract.hook'
|
||||
export * from '@/hooks/useVCharts.hook'
|
||||
export * from '@/hooks/useChartInteract.hook'
|
||||
@@ -7,7 +7,6 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
|
||||
import { RequestDataTypeEnum } from '@/enums/httpEnum'
|
||||
import { isPreview, newFunctionHandle, intervalUnitHandle } from '@/utils'
|
||||
import { setOption } from '@/packages/public/chart'
|
||||
import { isNil } from 'lodash'
|
||||
|
||||
// 获取类型
|
||||
type ChartEditStoreType = typeof useChartEditStore
|
||||
@@ -36,7 +35,7 @@ export const useChartDataFetch = (
|
||||
const echartsUpdateHandle = (dataset: any) => {
|
||||
if (chartFrame === ChartFrameEnum.ECHARTS) {
|
||||
if (vChartRef.value) {
|
||||
setOption(vChartRef.value, { dataset: dataset }, false)
|
||||
setOption(vChartRef.value, { dataset: dataset })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,12 +101,14 @@ export const useChartDataFetch = (
|
||||
)
|
||||
|
||||
// 定时时间
|
||||
const time = targetInterval && !isNil(targetInterval.value) ? targetInterval.value : globalRequestInterval.value
|
||||
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
|
||||
// 单位
|
||||
const unit = targetInterval && !isNil(targetInterval.value) ? targetUnit.value : globalUnit.value
|
||||
const unit = targetInterval && targetInterval.value ? targetUnit.value : globalUnit.value
|
||||
// 开启轮询
|
||||
if (time) {
|
||||
fetchInterval = setInterval(fetchFn, intervalUnitHandle(time, unit))
|
||||
} else {
|
||||
fetchFn()
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
|
||||
@@ -116,7 +116,7 @@ export const useChartDataPondFetch = () => {
|
||||
const requestDataPondItem = computed(() => {
|
||||
return requestGlobalConfig.requestDataPond.find(item => item.dataPondId === pondKey)
|
||||
}) as ComputedRef<RequestDataPondItemType>
|
||||
if (requestDataPondItem) {
|
||||
if (requestDataPondItem.value) {
|
||||
newPondItemInterval(chartEditStore.requestGlobalConfig, requestDataPondItem, mittDataPondMap.get(pondKey))
|
||||
}
|
||||
}
|
||||
|
||||
23
src/hooks/useSystemInit.hook.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
|
||||
import { SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d'
|
||||
import { ResultEnum } from '@/enums/httpEnum'
|
||||
import { ossUrlApi } from '@/api/path'
|
||||
|
||||
|
||||
// * 初始化
|
||||
export const useSystemInit = async () => {
|
||||
const systemStore = useSystemStore()
|
||||
|
||||
// 获取 OSS 信息的 url 地址,用来拼接展示图片的地址
|
||||
const getOssUrl = async () => {
|
||||
const res = await ossUrlApi({})
|
||||
if (res && res.code === ResultEnum.SUCCESS) {
|
||||
systemStore.setItem(SystemStoreEnum.FETCH_INFO, {
|
||||
OSSUrl: res.data?.bucketURL
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 执行
|
||||
getOssUrl()
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
import { watch } from 'vue'
|
||||
import { VChart, type ITheme } from '@visactor/vchart'
|
||||
|
||||
import light from '@visactor/vchart-theme/public/light.json'
|
||||
import dark from '@visactor/vchart-theme/public/dark.json'
|
||||
import vScreenVolcanoBlue from '@visactor/vchart-theme/public/vScreenVolcanoBlue.json'
|
||||
import vScreenClean from '@visactor/vchart-theme/public/vScreenClean.json'
|
||||
import vScreenOutskirts from '@visactor/vchart-theme/public/vScreenOutskirts.json'
|
||||
import vScreenBlueOrange from '@visactor/vchart-theme/public/vScreenBlueOrange.json'
|
||||
import vScreenFinanceYellow from '@visactor/vchart-theme/public/vScreenFinanceYellow.json'
|
||||
import vScreenWenLvCyan from '@visactor/vchart-theme/public/vScreenWenLvCyan.json'
|
||||
import vScreenElectricGreen from '@visactor/vchart-theme/public/vScreenElectricGreen.json'
|
||||
import vScreenECommercePurple from '@visactor/vchart-theme/public/vScreenECommercePurple.json'
|
||||
import vScreenRedBlue from '@visactor/vchart-theme/public/vScreenRedBlue.json'
|
||||
import vScreenPartyRed from '@visactor/vchart-theme/public/vScreenPartyRed.json'
|
||||
// 行业色板
|
||||
import veODesignLightFinance from '@visactor/vchart-theme/public/veODesignLightFinance.json'
|
||||
import veODesignDarkFinance from '@visactor/vchart-theme/public/veODesignDarkFinance.json'
|
||||
|
||||
import veODesignLightGovernment from '@visactor/vchart-theme/public/veODesignLightGovernment.json'
|
||||
import veODesignDarkGovernment from '@visactor/vchart-theme/public/veODesignDarkGovernment.json'
|
||||
|
||||
import veODesignLightConsumer from '@visactor/vchart-theme/public/veODesignLightConsumer.json'
|
||||
import veODesignDarkConsumer from '@visactor/vchart-theme/public/veODesignDarkConsumer.json'
|
||||
|
||||
import veODesignLightAutomobile from '@visactor/vchart-theme/public/veODesignLightAutomobile.json'
|
||||
import veODesignDarkAutomobile from '@visactor/vchart-theme/public/veODesignDarkAutomobile.json'
|
||||
|
||||
import veODesignLightCulturalTourism from '@visactor/vchart-theme/public/veODesignLightCulturalTourism.json'
|
||||
import veODesignDarkCulturalTourism from '@visactor/vchart-theme/public/veODesignDarkCulturalTourism.json'
|
||||
|
||||
import veODesignLightMedical from '@visactor/vchart-theme/public/veODesignLightMedical.json'
|
||||
import veODesignDarkMedical from '@visactor/vchart-theme/public/veODesignDarkMedical.json'
|
||||
|
||||
import veODesignLightNewEnergy from '@visactor/vchart-theme/public/veODesignLightNewEnergy.json'
|
||||
import veODesignDarkNewEnergy from '@visactor/vchart-theme/public/veODesignDarkNewEnergy.json'
|
||||
|
||||
const themeMap = {
|
||||
// 明亮
|
||||
light: light,
|
||||
// 暗黑
|
||||
dark: dark,
|
||||
// 火山蓝
|
||||
vScreenVolcanoBlue: vScreenVolcanoBlue,
|
||||
// 党建红
|
||||
vScreenPartyRed: vScreenPartyRed,
|
||||
// 清新蜡笔
|
||||
vScreenClean: vScreenClean,
|
||||
// 郊外
|
||||
vScreenOutskirts: vScreenOutskirts,
|
||||
// 汽车蓝橙
|
||||
vScreenBlueOrange: vScreenBlueOrange,
|
||||
// 金融黄
|
||||
vScreenFinanceYellow: vScreenFinanceYellow,
|
||||
// 文旅青
|
||||
vScreenWenLvCyan: vScreenWenLvCyan,
|
||||
// 电力绿
|
||||
vScreenElectricGreen: vScreenElectricGreen,
|
||||
// 电商紫
|
||||
vScreenECommercePurple: vScreenECommercePurple,
|
||||
// 红蓝
|
||||
vScreenRedBlue: vScreenRedBlue,
|
||||
// 金融行业色板
|
||||
veODesignLightFinance: veODesignLightFinance,
|
||||
veODesignDarkFinance: veODesignDarkFinance,
|
||||
// 政府行业色板
|
||||
veODesignLightGovernment: veODesignLightGovernment,
|
||||
veODesignDarkGovernment: veODesignDarkGovernment,
|
||||
// 消费行业色板
|
||||
veODesignLightConsumer: veODesignLightConsumer,
|
||||
veODesignDarkConsumer: veODesignDarkConsumer,
|
||||
// 汽车行业色板
|
||||
veODesignLightAutomobile: veODesignLightAutomobile,
|
||||
veODesignDarkAutomobile: veODesignDarkAutomobile,
|
||||
// 文旅行业色板
|
||||
veODesignLightCulturalTourism: veODesignLightCulturalTourism,
|
||||
veODesignDarkCulturalTourism: veODesignDarkCulturalTourism,
|
||||
// 医疗行业色板
|
||||
veODesignLightMedical: veODesignLightMedical,
|
||||
veODesignDarkMedical: veODesignDarkMedical,
|
||||
// 新能源行业色板
|
||||
veODesignLightNewEnergy: veODesignLightNewEnergy,
|
||||
veODesignDarkNewEnergy: veODesignDarkNewEnergy
|
||||
}
|
||||
|
||||
export const useVCharts = () => {
|
||||
const getThemeMap = () => {
|
||||
return themeMap
|
||||
}
|
||||
|
||||
// 注册主题(支持自定义主题)
|
||||
const registerTheme = (themeName: keyof typeof themeMap, theme: any) => {
|
||||
VChart.ThemeManager.registerTheme(themeName, (themeMap[themeName] as any) || theme)
|
||||
}
|
||||
|
||||
// 设置当前主题
|
||||
const setCurrentTheme = (themeName = 'vScreenVolcanoBlue') => {
|
||||
VChart.ThemeManager.setCurrentTheme(themeName)
|
||||
}
|
||||
|
||||
// 判断主题是否存在
|
||||
const themeExist = (name: string): boolean => {
|
||||
return VChart.ThemeManager.themeExist(name)
|
||||
}
|
||||
|
||||
// 获取主题
|
||||
const getTheme = (name: string): ITheme => {
|
||||
return VChart.ThemeManager.getTheme(name)
|
||||
}
|
||||
|
||||
// 获取当前主题
|
||||
const getCurrentTheme = (): ITheme => {
|
||||
return VChart.ThemeManager.getCurrentTheme()
|
||||
}
|
||||
|
||||
// 设置主题
|
||||
const setTheme = (name: keyof typeof themeMap): boolean => {
|
||||
if (themeExist(name)) {
|
||||
setCurrentTheme(name)
|
||||
return true
|
||||
} else {
|
||||
// 先注册
|
||||
const theme = themeMap[name]
|
||||
if (theme) {
|
||||
registerTheme(name, theme)
|
||||
setCurrentTheme(name)
|
||||
return true
|
||||
} else {
|
||||
// 注册默认主题
|
||||
registerTheme('vScreenVolcanoBlue', vScreenVolcanoBlue)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return {
|
||||
getThemeMap,
|
||||
registerTheme,
|
||||
setCurrentTheme,
|
||||
themeExist,
|
||||
getTheme,
|
||||
setTheme,
|
||||
getCurrentTheme
|
||||
}
|
||||
}
|
||||
|
||||
// 主题初始化
|
||||
export const useInitVChartsTheme = (chartEditStore: any) => {
|
||||
const vCharts = useVCharts()
|
||||
|
||||
const initVChartsThemeIns = watch(
|
||||
() => chartEditStore.getEditCanvasConfig.vChartThemeName,
|
||||
(newTheme: string) => {
|
||||
vCharts.setTheme(newTheme as any)
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
initVChartsThemeIns
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ const global = {
|
||||
help: 'Help',
|
||||
contact: 'About Software',
|
||||
logout: 'Logout',
|
||||
logout_success: 'Logout success!',
|
||||
logout_failure: 'Logout Failed!',
|
||||
// system setting
|
||||
sys_set: 'System Setting',
|
||||
lang_set: 'Language Setting',
|
||||
@@ -26,8 +28,14 @@ const global = {
|
||||
r_more: 'More',
|
||||
}
|
||||
|
||||
const http = {
|
||||
error_message: 'The interface is abnormal, please check the interface!',
|
||||
token_overdue_message: 'Login expired, please log in again!'
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
http,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ export default {
|
||||
desc: "Login",
|
||||
form_auto: "Sign in automatically",
|
||||
form_button: "Login",
|
||||
login_success: "Login success",
|
||||
login_message: "Please complete the letter",
|
||||
login_success: "Login success!",
|
||||
login_message: "Please complete the letter!",
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
export default {
|
||||
create_btn: 'Create',
|
||||
create_tip: 'Please select a content for development',
|
||||
create_btn: 'Creat',
|
||||
create_success: 'Creat Success!',
|
||||
create_failure: 'Failed to create, please try again later!',
|
||||
create_tip: 'Please select a content for development!',
|
||||
project: 'Project',
|
||||
my: 'My',
|
||||
new_project: 'New Project',
|
||||
all_project: 'All Project',
|
||||
my_template: 'My Template',
|
||||
my_templete: 'My Templete',
|
||||
template_market: 'Template Market',
|
||||
|
||||
// items
|
||||
|
||||
@@ -11,6 +11,8 @@ const global = {
|
||||
help: '帮助中心',
|
||||
contact: '关于软件',
|
||||
logout: '退出登录',
|
||||
logout_success: '退出成功!',
|
||||
logout_failure: '退出失败!',
|
||||
// 系统设置
|
||||
sys_set: '系统设置',
|
||||
lang_set: '语言设置',
|
||||
@@ -18,16 +20,27 @@ const global = {
|
||||
r_edit: '编辑',
|
||||
r_preview: '预览',
|
||||
r_copy: '克隆',
|
||||
r_copy_success: '克隆成功!',
|
||||
r_rename: '重命名',
|
||||
r_rename_success: '重命名成功!',
|
||||
r_publish: '发布',
|
||||
r_publish_success: '成功发布!',
|
||||
r_unpublish: '取消发布',
|
||||
r_unpublish_success: '取消成功!',
|
||||
r_download: '下载',
|
||||
r_delete: '删除',
|
||||
r_delete_success: '删除成功!',
|
||||
r_more: '更多',
|
||||
}
|
||||
|
||||
const http = {
|
||||
error_message: '获取数据失败,请稍后重试!',
|
||||
token_overdue_message: '登录过期,请重新登录!'
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
http,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ export default {
|
||||
desc: "登录",
|
||||
form_auto: "自动登录",
|
||||
form_button: "登录",
|
||||
login_success: "登录成功",
|
||||
login_message: "请填写完整信息",
|
||||
login_success: "登录成功!",
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
export default {
|
||||
// aside
|
||||
create_btn: '新建',
|
||||
create_success: '新建成功!',
|
||||
create_failure: '新建失败,请稍后重试!',
|
||||
create_tip: '从哪里出发好呢?',
|
||||
project: '项目',
|
||||
my: '我的',
|
||||
new_project: '新项目',
|
||||
all_project: '全部项目',
|
||||
my_template: '我的模板',
|
||||
my_templete: '我的模板',
|
||||
template_market: '模板市场',
|
||||
|
||||
// items
|
||||
|
||||
@@ -38,16 +38,18 @@ const isProject = computed(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$min-width: 520px;
|
||||
@include go(header) {
|
||||
&-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 33%);
|
||||
&.is-project {
|
||||
grid-template-columns: none;
|
||||
}
|
||||
.header-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: $min-width;
|
||||
&.left {
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,5 @@ export const labelConfig = {
|
||||
{ label: '外侧', value: 'outside' },
|
||||
{ label: '内部', value: 'inside' },
|
||||
{ label: '中心', value: 'center' }
|
||||
],
|
||||
fontWeight: [
|
||||
{ label: '正常', value: 'normal' },
|
||||
{ label: '普通加粗', value: 'bold' },
|
||||
{ label: '加粗', value: 'bolder' },
|
||||
{ label: '细体', value: 'lighter' }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from './legends'
|
||||
export * from './label'
|
||||
export * from './style'
|
||||
@@ -1,120 +0,0 @@
|
||||
export const labelConfig = {
|
||||
position: [
|
||||
{
|
||||
label: '外部',
|
||||
value: 'outside'
|
||||
},
|
||||
{
|
||||
label: '内部',
|
||||
value: 'inside'
|
||||
},
|
||||
{
|
||||
label: '内部-外',
|
||||
value: 'inside-outer'
|
||||
},
|
||||
{
|
||||
label: '内部-里',
|
||||
value: 'inside-inner'
|
||||
},
|
||||
{
|
||||
label: '内部-居中',
|
||||
value: 'inside-center'
|
||||
}
|
||||
],
|
||||
barPosition: [
|
||||
{
|
||||
label: '外部',
|
||||
value: 'outside'
|
||||
},
|
||||
{
|
||||
label: '内部',
|
||||
value: 'inside'
|
||||
},
|
||||
{
|
||||
label: '顶部',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '底部',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左侧',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'right'
|
||||
},
|
||||
{
|
||||
label: '内部-顶',
|
||||
value: 'inside-top'
|
||||
},
|
||||
{
|
||||
label: '内部-底',
|
||||
value: 'inside-bottom'
|
||||
},
|
||||
{
|
||||
label: '内部-右',
|
||||
value: 'inside-right'
|
||||
},
|
||||
{
|
||||
label: '内部-左',
|
||||
value: 'inside-left'
|
||||
},
|
||||
{
|
||||
label: '顶部-右',
|
||||
value: 'top-right'
|
||||
},
|
||||
{
|
||||
label: '顶部-左',
|
||||
value: 'top-left'
|
||||
},
|
||||
{
|
||||
label: '底部-右',
|
||||
value: 'bottom-right'
|
||||
},
|
||||
{
|
||||
label: '底部-左',
|
||||
value: 'bottom-left'
|
||||
}
|
||||
],
|
||||
linePosition: [
|
||||
{
|
||||
label: '顶部',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '底部',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左侧',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'right'
|
||||
},
|
||||
{
|
||||
label: '顶部-右',
|
||||
value: 'top-right'
|
||||
},
|
||||
{
|
||||
label: '顶部-左',
|
||||
value: 'top-left'
|
||||
},
|
||||
{
|
||||
label: '底部-右',
|
||||
value: 'bottom-right'
|
||||
},
|
||||
{
|
||||
label: '底部-左',
|
||||
value: 'bottom-left'
|
||||
},
|
||||
{
|
||||
label: '居中',
|
||||
value: 'center'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
export const legendsConfig = {
|
||||
// 位置
|
||||
orient: [
|
||||
{
|
||||
label: '顶部',
|
||||
value: 'top'
|
||||
},
|
||||
{
|
||||
label: '底部',
|
||||
value: 'bottom'
|
||||
},
|
||||
{
|
||||
label: '左侧',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '右侧',
|
||||
value: 'right'
|
||||
}
|
||||
],
|
||||
// 对齐方式
|
||||
position: [
|
||||
{
|
||||
label: '起始',
|
||||
value: 'start'
|
||||
},
|
||||
{
|
||||
label: '居中',
|
||||
value: 'middle'
|
||||
},
|
||||
{
|
||||
label: '末尾',
|
||||
value: 'end'
|
||||
}
|
||||
],
|
||||
// 每一项的图例位置
|
||||
align: [
|
||||
{
|
||||
label: '居左',
|
||||
value: 'left'
|
||||
},
|
||||
{
|
||||
label: '居右',
|
||||
value: 'right'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const fontStyleConfig = {
|
||||
// 字重
|
||||
fontWeight: [
|
||||
{
|
||||
label: '100',
|
||||
value: 100
|
||||
},
|
||||
{
|
||||
label: '200',
|
||||
value: 200
|
||||
},
|
||||
{
|
||||
label: '300',
|
||||
value: 300
|
||||
},
|
||||
{
|
||||
label: '400',
|
||||
value: 400
|
||||
},
|
||||
{
|
||||
label: '500',
|
||||
value: 500
|
||||
},
|
||||
{
|
||||
label: '600',
|
||||
value: 600
|
||||
},
|
||||
{
|
||||
label: '正常',
|
||||
value: "normal"
|
||||
},
|
||||
{
|
||||
label: '加粗',
|
||||
value: "bold"
|
||||
}
|
||||
],
|
||||
fontFamily: [
|
||||
{
|
||||
label: '宋体',
|
||||
value: 'SimSun'
|
||||
},
|
||||
{
|
||||
label: '黑体',
|
||||
value: 'SimHei'
|
||||
},
|
||||
{
|
||||
label: '楷体',
|
||||
value: '楷体'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
export const styleConfig = {
|
||||
texture: [
|
||||
{
|
||||
label: '无纹理',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'circle'
|
||||
},
|
||||
{
|
||||
label: '钻石',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
label: '矩形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '竖线',
|
||||
value: 'horizontal-line'
|
||||
},
|
||||
{
|
||||
label: '横线',
|
||||
value: 'vertical-line'
|
||||
},
|
||||
{
|
||||
label: '右向左斜线',
|
||||
value: 'bias-rl'
|
||||
},
|
||||
{
|
||||
label: '左向右斜线',
|
||||
value: 'bias-lr'
|
||||
},
|
||||
{
|
||||
label: '格子',
|
||||
value: 'grid'
|
||||
}
|
||||
],
|
||||
curveType: [
|
||||
{
|
||||
label: '线性',
|
||||
value: 'linear'
|
||||
},
|
||||
{
|
||||
label: '平滑',
|
||||
value: 'monotone'
|
||||
},
|
||||
{
|
||||
label: '平滑趋近X',
|
||||
value: 'monotoneX'
|
||||
},
|
||||
{
|
||||
label: '台阶',
|
||||
value: 'step'
|
||||
},
|
||||
{
|
||||
label: '连线闭合',
|
||||
value: 'catmullRom'
|
||||
},
|
||||
{
|
||||
label: '顺滑闭合',
|
||||
value: 'catmullRomClosed'
|
||||
}
|
||||
],
|
||||
lineCap: [
|
||||
{
|
||||
label: '默认',
|
||||
value: 'butt'
|
||||
},
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'round'
|
||||
},
|
||||
{
|
||||
label: '方形',
|
||||
value: 'square'
|
||||
}
|
||||
],
|
||||
symbolType: [
|
||||
{
|
||||
label: '圆形',
|
||||
value: 'circle'
|
||||
},
|
||||
{
|
||||
label: '方形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '菱形',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
label: '三角形',
|
||||
value: 'square'
|
||||
},
|
||||
{
|
||||
label: '指向向上',
|
||||
value: 'arrow'
|
||||
},
|
||||
{
|
||||
label: '指向向左',
|
||||
value: 'arrow2Left'
|
||||
},
|
||||
{
|
||||
label: '箭头向右',
|
||||
value: 'arrow2Right'
|
||||
},
|
||||
{
|
||||
label: '瘦箭头向上',
|
||||
value: 'wedge'
|
||||
},
|
||||
{
|
||||
label: '箭头向上',
|
||||
value: 'triangle'
|
||||
},
|
||||
{
|
||||
label: '箭头向下',
|
||||
value: 'triangleDown'
|
||||
},
|
||||
{
|
||||
label: '箭头向右',
|
||||
value: 'triangleRight'
|
||||
},
|
||||
{
|
||||
label: '箭头向左',
|
||||
value: 'triangleLeft'
|
||||
},
|
||||
{
|
||||
label: '星星',
|
||||
value: 'star'
|
||||
},
|
||||
{
|
||||
label: 'y字形物',
|
||||
value: 'wye'
|
||||
},
|
||||
{
|
||||
label: '矩形',
|
||||
value: 'rect'
|
||||
},
|
||||
{
|
||||
label: '圆角矩形',
|
||||
value: 'rectRound'
|
||||
},
|
||||
{
|
||||
label: '扁平矩形',
|
||||
value: 'roundLine'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export const option = {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
xAxis: {
|
||||
show: true,
|
||||
type: 'category'
|
||||
},
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
<template>
|
||||
<v-chart
|
||||
ref="vChartRef"
|
||||
:init-options="initOptions"
|
||||
:theme="themeColor"
|
||||
:option="option"
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()"
|
||||
:update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}"
|
||||
autoresize
|
||||
></v-chart>
|
||||
}" autoresize></v-chart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -91,7 +85,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
:init-options="initOptions"
|
||||
:theme="themeColor"
|
||||
:option="option"
|
||||
:manual-update="isPreview()"
|
||||
:update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}"
|
||||
@@ -22,6 +23,7 @@ import { mergeTheme } from '@/packages/public/chart'
|
||||
import config, { includes, seriesItem } from './config'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { isPreview } from '@/utils'
|
||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import isObject from 'lodash/isObject'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
@@ -77,7 +79,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -33,6 +33,7 @@ export const lineSeriesItem = {
|
||||
},
|
||||
symbolSize: 5, //设定实心点的大小
|
||||
itemStyle: {
|
||||
color: '#FFE47A',
|
||||
borderWidth: 1
|
||||
},
|
||||
lineStyle: {
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
:init-options="initOptions"
|
||||
:theme="themeColor"
|
||||
:option="option"
|
||||
:update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}"
|
||||
:manual-update="isPreview()"
|
||||
autoresize
|
||||
></v-chart>
|
||||
</template>
|
||||
@@ -90,7 +88,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -124,14 +124,7 @@ const calcData = (data: any, type?: string) => {
|
||||
const calcCapsuleLengthAndLabelData = (dataset: any) => {
|
||||
try {
|
||||
const { source } = dataset
|
||||
if (!source) return
|
||||
|
||||
if (source.length === 0) {
|
||||
// 清空数据
|
||||
state.capsuleLength = []
|
||||
state.labelData = []
|
||||
return
|
||||
}
|
||||
if (!source || !source.length) return
|
||||
|
||||
state.capsuleItemHeight = numberSizeHandle(state.mergedConfig.itemHeight)
|
||||
const capsuleValue = source.map((item: DataProps) => item[state.mergedConfig.dataset.dimensions[1]])
|
||||
@@ -147,8 +140,9 @@ const calcCapsuleLengthAndLabelData = (dataset: any) => {
|
||||
const labelData = Array.from(new Set(new Array(6).fill(0).map((v, i) => Math.ceil(i * oneFifth))))
|
||||
|
||||
state.labelData = labelData
|
||||
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
console.warn(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
:init-options="initOptions"
|
||||
:theme="themeColor"
|
||||
:option="option"
|
||||
:manual-update="isPreview()"
|
||||
:update-options="{
|
||||
replaceMerge: replaceMergeArr
|
||||
}"
|
||||
@@ -23,9 +24,9 @@ import config, { includes, seriesItem } from './config'
|
||||
import { mergeTheme } from '@/packages/public/chart'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { isPreview } from '@/utils'
|
||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||
import isObject from 'lodash/isObject'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
const props = defineProps({
|
||||
themeSetting: {
|
||||
@@ -61,7 +62,7 @@ watch(
|
||||
if (Array.isArray(newData?.dimensions)) {
|
||||
const seriesArr = []
|
||||
for (let i = 0; i < newData.dimensions.length - 1; i++) {
|
||||
seriesArr.push(cloneDeep(seriesItem))
|
||||
seriesArr.push(seriesItem)
|
||||
}
|
||||
replaceMergeArr.value = ['series']
|
||||
props.chartConfig.option.series = seriesArr
|
||||
@@ -78,7 +79,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" autoresize>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize>
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
@@ -82,7 +82,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" autoresize></v-chart>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize></v-chart>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -80,7 +80,5 @@ watch(
|
||||
option.value = props.chartConfig.option
|
||||
}
|
||||
)
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" autoresize>
|
||||
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize>
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
@@ -79,7 +79,5 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
props.chartConfig.option.dataset = newData
|
||||
})
|
||||
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
|
||||
</script>
|
||||
|
||||
@@ -56,7 +56,7 @@ export const option = {
|
||||
mapOptions: {
|
||||
pitch: 60,
|
||||
skyColor: '#53A9DE',
|
||||
amapKey: '',
|
||||
amapKey: 'd5f3e16589dbecae64d05fe90e2ba4f2',
|
||||
amapStyleKey: ThemeEnum.DARK,
|
||||
amapStyleKeyCustom: '',
|
||||
amapLon: 116.397428,
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="鼠标悬停聚焦">
|
||||
<SettingItem name="禁用(预览可见)">
|
||||
<SettingItemBox name="悬浮 (预览可见)">
|
||||
<SettingItem name="禁用">
|
||||
<n-space>
|
||||
<n-switch v-model:value="seriesList[1].emphasis.disabled" size="small"></n-switch>
|
||||
</n-space>
|
||||
|
||||
@@ -49,12 +49,16 @@ const {
|
||||
dataset
|
||||
} = toRefs(props.chartConfig.option)
|
||||
|
||||
const option = shallowReactive({
|
||||
dataset: configOption.dataset
|
||||
})
|
||||
|
||||
// 手动更新
|
||||
watch(
|
||||
() => props.chartConfig.option.dataset,
|
||||
(newData: any) => {
|
||||
try {
|
||||
dataset.value = toNumber(newData, 2)
|
||||
option.dataset = toNumber(newData, 2)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
@@ -65,6 +69,6 @@ watch(
|
||||
)
|
||||
// 预览更新
|
||||
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => {
|
||||
dataset.value = toNumber(newData, 2)
|
||||
option.dataset = toNumber(newData, 2)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -52,16 +52,12 @@ const option = {
|
||||
show: false,
|
||||
position: 'center',
|
||||
formatter: '{b}',
|
||||
fontWeight: 'normal',
|
||||
fontSize: 14,
|
||||
color: '#454E54',
|
||||
textBorderColor: '#ffffff',
|
||||
textBorderWidth: 1
|
||||
fontSize:12
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 40,
|
||||
fontSize: '40',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -18,20 +18,6 @@
|
||||
<n-text :depth="3">无鼠标点击图例场景时,可强行打开图例</n-text>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="图形">
|
||||
<setting-item name="内圈范围">
|
||||
<n-input v-model:value="optionData.series[0].radius[0]" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="外圈范围">
|
||||
<n-input v-model:value="optionData.series[0].radius[1]" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="X轴中心">
|
||||
<n-input v-model:value="optionData.series[0].center[0]" size="small"></n-input>
|
||||
</setting-item>
|
||||
<setting-item name="Y轴中心">
|
||||
<n-input v-model:value="optionData.series[0].center[1]" size="small"></n-input>
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
<SettingItemBox name="标签">
|
||||
<SettingItem>
|
||||
<n-space>
|
||||
@@ -52,66 +38,27 @@
|
||||
<n-select v-model:value="optionData.series[0].label.formatter" size="small" :options="labelFormatterOptions" />
|
||||
</setting-item>
|
||||
</SettingItemBox>
|
||||
<setting-item-box name="字体">
|
||||
<setting-item name="大小">
|
||||
<n-input-number v-model:value="optionData.series[0].label.fontSize" size="small" :min="0"></n-input-number>
|
||||
<setting-item-box name="圆角">
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].itemStyle.borderRadius"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
<n-text>圆角大小</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<setting-item name="颜色" v-if="optionData.series[0].label.color">
|
||||
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.series[0].label.color"></n-color-picker>
|
||||
<setting-item>
|
||||
<n-space>
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].itemStyle.borderWidth"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
<n-text>线条宽度</n-text>
|
||||
</n-space>
|
||||
</setting-item>
|
||||
<SettingItem name="文字加粗" v-if="optionData.series[0].label.fontWeight">
|
||||
<n-select
|
||||
v-model:value="optionData.series[0].label.fontWeight"
|
||||
size="small"
|
||||
:options="labelConfig.fontWeight"
|
||||
/>
|
||||
</SettingItem>
|
||||
<setting-item name="文字边框大小" v-if="optionData.series[0].label.textBorderWidth > -1">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].label.textBorderWidth"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="文字边框色" v-if="optionData.series[0].label.textBorderColor">
|
||||
<n-color-picker
|
||||
size="small"
|
||||
:modes="['hex']"
|
||||
v-model:value="optionData.series[0].label.textBorderColor"
|
||||
></n-color-picker>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="分段样式">
|
||||
<setting-item name="圆角大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].itemStyle.borderRadius"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<setting-item name="线条宽度">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].itemStyle.borderWidth"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
</setting-item-box>
|
||||
<setting-item-box name="鼠标聚焦">
|
||||
<setting-item name="文字大小">
|
||||
<n-input-number
|
||||
v-model:value="optionData.series[0].emphasis.label.fontSize"
|
||||
size="small"
|
||||
:min="0"
|
||||
></n-input-number>
|
||||
</setting-item>
|
||||
<SettingItem name="文字加粗" v-if="optionData.series[0].emphasis.label.fontWeight">
|
||||
<n-select
|
||||
v-model:value="optionData.series[0].emphasis.label.fontWeight"
|
||||
size="small"
|
||||
:options="labelConfig.fontWeight"
|
||||
/>
|
||||
</SettingItem>
|
||||
</setting-item-box>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, onMounted, watch, ref } from 'vue'
|
||||
import { computed, PropType, onMounted, watch } from 'vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||
import { use } from 'echarts/core'
|
||||
@@ -103,10 +103,6 @@ watch(
|
||||
() => props.chartConfig.option.type,
|
||||
newData => {
|
||||
try {
|
||||
// 防止初始化时触发修改,导致部分参数丢失
|
||||
if (isPreview()) {
|
||||
return
|
||||
}
|
||||
if (newData === 'nomal') {
|
||||
props.chartConfig.option.series[0].radius = '70%'
|
||||
props.chartConfig.option.series[0].roseType = false
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { FlowChartLineConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
export const option = {
|
||||
endWidth: 15,
|
||||
lineWidth: 2, //线条粗细
|
||||
lineNum: 2, //向下数量
|
||||
lineNumUp: 2, //向上数量
|
||||
backgroundCol: '#303a4c', //线条背景
|
||||
animateCol: '#3788ea' //流动动画背景
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = FlowChartLineConfig.key
|
||||
public chartConfig = cloneDeep(FlowChartLineConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<CollapseItem name="线条" :expanded="true">
|
||||
<SettingItemBox name="折线数量">
|
||||
<SettingItem name="向下增加">
|
||||
<n-input-number size="small" :min="0" v-model:value="optionData.lineNum"></n-input-number>
|
||||
</SettingItem>
|
||||
<SettingItem name="向上增加">
|
||||
<n-input-number size="small" :min="0" v-model:value="optionData.lineNumUp"></n-input-number>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
|
||||
<SettingItemBox name="折线样式">
|
||||
<SettingItem name="折线粗细">
|
||||
<n-input-number size="small" :min="1" v-model:value="optionData.lineWidth"></n-input-number>
|
||||
</SettingItem>
|
||||
<SettingItem name="背景条颜色">
|
||||
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.backgroundCol"></n-color-picker>
|
||||
</SettingItem>
|
||||
<SettingItem name="流动颜色">
|
||||
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.animateCol"></n-color-picker>
|
||||
</SettingItem>
|
||||
</SettingItemBox>
|
||||
</CollapseItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue'
|
||||
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||
import { option } from './config'
|
||||
|
||||
const props = defineProps({
|
||||
optionData: {
|
||||
type: Object as PropType<typeof option>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -1,14 +0,0 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
|
||||
|
||||
export const FlowChartLineConfig: ConfigType = {
|
||||
key: 'FlowChartLine',
|
||||
chartKey: 'VFlowChartLine',
|
||||
conKey: 'VCFlowChartLine',
|
||||
title: '流程线',
|
||||
category: ChatCategoryEnum.FlowChart,
|
||||
categoryName: ChatCategoryEnumName.FlowChart,
|
||||
package: PackagesCategoryEnum.DECORATES,
|
||||
chartFrame: ChartFrameEnum.STATIC,
|
||||
image: 'flow-zhexian.png'
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<template>
|
||||
<svg :width="w" :height="h">
|
||||
<polyline :stroke-width="lineWidth" :points="getStartPoint(-1, '')" :stroke="backgroundCol" fill="none" />
|
||||
<polyline
|
||||
:stroke-width="lineWidth"
|
||||
class="g-dashed-line"
|
||||
:points="getStartPoint(-1, '')"
|
||||
:stroke="animateCol"
|
||||
fill="none"
|
||||
/>
|
||||
<polyline
|
||||
:stroke-width="lineWidth"
|
||||
v-for="(item, index) in lineNum"
|
||||
:key="index"
|
||||
:points="getStartPoint(index + 1, 'down')"
|
||||
:stroke="backgroundCol"
|
||||
fill="none"
|
||||
/>
|
||||
<polyline
|
||||
:stroke-width="lineWidth"
|
||||
class="g-dashed-line"
|
||||
v-for="(item, index) in lineNum"
|
||||
:key="index"
|
||||
:points="getStartPoint(index + 1, 'down')"
|
||||
:stroke="animateCol"
|
||||
fill="none"
|
||||
/>
|
||||
<polyline
|
||||
:stroke-width="lineWidth"
|
||||
v-for="(item, index) in lineNumUp"
|
||||
:key="index"
|
||||
:points="getStartPoint(index + 1, 'up')"
|
||||
:stroke="backgroundCol"
|
||||
fill="none"
|
||||
/>
|
||||
<polyline
|
||||
:stroke-width="lineWidth"
|
||||
class="g-dashed-line"
|
||||
v-for="(item, index) in lineNumUp"
|
||||
:key="index"
|
||||
:points="getStartPoint(index + 1, 'up')"
|
||||
:stroke="animateCol"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, toRefs, computed } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { lineNum, lineNumUp, lineWidth, backgroundCol, animateCol } = toRefs(props.chartConfig.option)
|
||||
const getStartPoint = (num: number, direction: string) => {
|
||||
const lineLength = w.value / 2
|
||||
const lineColLength =
|
||||
h.value / (lineNumUp.value + lineNum.value) - lineWidth.value / (lineNumUp.value + lineNum.value)
|
||||
if (num === -1 && direction === '') {
|
||||
return `0,${h.value / 2} ${lineLength},${h.value / 2} ${lineLength * 2},${h.value / 2}`
|
||||
} else if (num !== -1 && direction === 'down') {
|
||||
return `0,${h.value / 2} ${lineLength},${h.value / 2} ${lineLength},${h.value / 2 + num * lineColLength},${
|
||||
lineLength * 2
|
||||
},${h.value / 2 + num * lineColLength}`
|
||||
} else if (num !== -1 && direction === 'up') {
|
||||
return `0,${h.value / 2} ${lineLength},${h.value / 2} ${lineLength},${h.value / 2 - num * lineColLength},${
|
||||
lineLength * 2
|
||||
},${h.value / 2 - num * lineColLength}`
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.g-dashed-line {
|
||||
stroke-dasharray: 20 130;
|
||||
stroke-dashoffset: 0;
|
||||
animation: move 3s infinite linear;
|
||||
}
|
||||
@keyframes move {
|
||||
0% {
|
||||
stroke-dashoffset: 20;
|
||||
}
|
||||
100% {
|
||||
stroke-dashoffset: -130;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,3 +0,0 @@
|
||||
import { FlowChartLineConfig } from './FlowChartLine/index'
|
||||
|
||||
export default [FlowChartLineConfig]
|
||||
@@ -1,20 +0,0 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { CirclePointConfig } from './index'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import { chartInitConfig } from '@/settings/designSetting'
|
||||
|
||||
export const option = {
|
||||
outCircle: 15,
|
||||
inCircle: 5,
|
||||
outCircleColor: '#3f5261',
|
||||
inCircleColor: '#fff',
|
||||
outCircleWidth: 2
|
||||
}
|
||||
|
||||
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||
public key = CirclePointConfig.key
|
||||
public attr = { ...chartInitConfig, w: 97, h: 97, zIndex: 1 }
|
||||
public chartConfig = cloneDeep(CirclePointConfig)
|
||||
public option = cloneDeep(option)
|
||||
}
|
||||