Browse Source

first commit

main
betaqi 1 week ago
commit
0a90272469
  1. 3
      .commitlintrc.js
  2. 18
      .env
  3. 11
      .eslintignore
  4. 30
      .eslintrc.js
  5. 9
      .gitignore
  6. 21
      LICENSE
  7. 25
      Makefile
  8. 92
      README.md
  9. 41
      build/constant.ts
  10. 85
      index.css
  11. 30
      index.html
  12. 104
      package.json
  13. 5
      plop/plopfile.js
  14. 3
      plop/store-template/index.d.hbs
  15. 11
      plop/store-template/index.hbs
  16. 45
      plop/store-template/prompt.js
  17. 9360
      pnpm-lock.yaml
  18. 12
      prettier.config.js
  19. 10
      preview.yml
  20. BIN
      public/favicon.ico
  21. BIN
      readme/go-view-canvas.png
  22. BIN
      readme/go-view-color.png
  23. BIN
      readme/go-view-doc.png
  24. BIN
      readme/go-view-event.png
  25. BIN
      readme/go-view-fetch.png
  26. BIN
      readme/go-view-filter.png
  27. BIN
      readme/go-view-indexpage.png
  28. BIN
      readme/go-view-qq.png
  29. BIN
      readme/go-view-theme.png
  30. BIN
      readme/logo-poster.png
  31. BIN
      readme/logo-t-y.png
  32. BIN
      readme/logo.png
  33. BIN
      readme/preview.png
  34. 65
      src/App.vue
  35. 12
      src/api/axios.config.ts
  36. 220
      src/api/axios.ts
  37. 254
      src/api/http.ts
  38. 100
      src/api/mock/graph.json
  39. 199
      src/api/mock/heatMapData.json
  40. 120
      src/api/mock/index.ts
  41. 9
      src/api/mock/map.json
  42. 86
      src/api/mock/sankey.json
  43. 56
      src/api/mock/scatter.json
  44. 239
      src/api/mock/test.mock.ts
  45. 50
      src/api/mock/treemap.json
  46. 3
      src/api/path/index.ts
  47. 13
      src/api/path/infra.api.ts
  48. 77
      src/api/path/project.api.ts
  49. 40
      src/api/path/project.d.ts
  50. 66
      src/api/path/system.api.ts
  51. 23
      src/api/path/system.d.ts
  52. 255
      src/assets/images/Error.svg
  53. BIN
      src/assets/images/canvas/noData.png
  54. BIN
      src/assets/images/canvas/noImage.png
  55. BIN
      src/assets/images/chart/charts/bar_line.png
  56. BIN
      src/assets/images/chart/charts/bar_x.png
  57. BIN
      src/assets/images/chart/charts/bar_y.png
  58. BIN
      src/assets/images/chart/charts/capsule.png
  59. BIN
      src/assets/images/chart/charts/dial.png
  60. BIN
      src/assets/images/chart/charts/funnel.png
  61. BIN
      src/assets/images/chart/charts/graph.png
  62. BIN
      src/assets/images/chart/charts/ground_glass.png
  63. BIN
      src/assets/images/chart/charts/grouped_stacked_rose_chart.png
  64. BIN
      src/assets/images/chart/charts/heatmap.png
  65. BIN
      src/assets/images/chart/charts/line.png
  66. BIN
      src/assets/images/chart/charts/line_gradient.png
  67. BIN
      src/assets/images/chart/charts/line_gradient_single.png
  68. BIN
      src/assets/images/chart/charts/line_linear_single.png
  69. BIN
      src/assets/images/chart/charts/map.png
  70. BIN
      src/assets/images/chart/charts/map_amap.png
  71. BIN
      src/assets/images/chart/charts/map_cesium.png
  72. BIN
      src/assets/images/chart/charts/pie-circle.png
  73. BIN
      src/assets/images/chart/charts/pie.png
  74. BIN
      src/assets/images/chart/charts/polar_coordinate_axis.png
  75. BIN
      src/assets/images/chart/charts/process.png
  76. BIN
      src/assets/images/chart/charts/radar.png
  77. BIN
      src/assets/images/chart/charts/sankey.png
  78. BIN
      src/assets/images/chart/charts/scatter-logarithmic-regression.png
  79. BIN
      src/assets/images/chart/charts/scatter-multi.png
  80. BIN
      src/assets/images/chart/charts/scatter.png
  81. BIN
      src/assets/images/chart/charts/tree_map.png
  82. BIN
      src/assets/images/chart/charts/visactor_bar_line.png
  83. BIN
      src/assets/images/chart/charts/visactor_biax_line.png
  84. BIN
      src/assets/images/chart/charts/visactor_instrument.png
  85. BIN
      src/assets/images/chart/charts/visactor_line.png
  86. BIN
      src/assets/images/chart/charts/water_WaterPolo.png
  87. BIN
      src/assets/images/chart/charts/weather.png
  88. BIN
      src/assets/images/chart/decorates/Pipeline_H.png
  89. BIN
      src/assets/images/chart/decorates/Pipeline_V.png
  90. BIN
      src/assets/images/chart/decorates/border.png
  91. BIN
      src/assets/images/chart/decorates/border01.png
  92. BIN
      src/assets/images/chart/decorates/border02.png
  93. BIN
      src/assets/images/chart/decorates/border03.png
  94. BIN
      src/assets/images/chart/decorates/border04.png
  95. BIN
      src/assets/images/chart/decorates/border05.png
  96. BIN
      src/assets/images/chart/decorates/border06.png
  97. BIN
      src/assets/images/chart/decorates/border07.png
  98. BIN
      src/assets/images/chart/decorates/border08.png
  99. BIN
      src/assets/images/chart/decorates/border09.png
  100. BIN
      src/assets/images/chart/decorates/border10.png
  101. Some files were not shown because too many files have changed in this diff Show More

3
.commitlintrc.js

@ -0,0 +1,3 @@
module.exports = {
extends: ["@commitlint/config-conventional"]
};

18
.env

@ -0,0 +1,18 @@
# port
VITE_DEV_PORT = '3000'
# development path
# VITE_DEV_PATH = 'https://demo.mtruning.club'
VITE_DEV_PATH = 'http://127.0.0.1:48080'
# production path
VITE_PRO_PATH = 'https://demo.mtruning.club'
# 租户开关
VITE_APP_TENANT_ENABLE=true
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
#默认路由开关
VITE_ROUTER_DEFAULT=true

11
.eslintignore

@ -0,0 +1,11 @@
node_modules/
public/
es/
lib/
dist/
package.json
src/assets/
plop-templates/
handlebars/
website/
build/

30
.eslintrc.js

@ -0,0 +1,30 @@
module.exports = {
root: true,
parser: 'vue-eslint-parser',
globals: {
postMessage: true
},
parserOptions: {
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
tsx: true
}
},
env: {
node: true,
// The Follow config only works with eslint-plugin-vue v8.0.0+
'vue/setup-compiler-macros': true
},
extends: ['plugin:vue/vue3-essential', 'eslint:recommended'],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-unused-vars': 'off',
'vue/no-unused-vars': 'off',
'vue/multi-word-component-names': 'off',
'vue/valid-template-root': 'off',
'vue/no-mutating-props': 'off'
}
}

9
.gitignore vendored

@ -0,0 +1,9 @@
node_modules
.DS_Store
dist
dist-ssr
*.local
.vscode
.idea
.workflow
.husky

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present GoView
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
Makefile

@ -0,0 +1,25 @@
.PHONY: dist test
default: help
dev:
npm run dev
dist:
npm run build
view:
npm run preview
lint:
npm run lint
new:
npm run new
help:
@echo " make dev [npm run dev] 开发模式"
@echo " make dist [npm run build] 编译模式"
@echo " make view [npm run preview] 预览打包文件"
@echo " make new [npm run lint] 通过自动化流程创建代码"
@echo " make lint [npm run new] 格式校验"

92
README.md

@ -0,0 +1,92 @@
## 总览
<p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
<h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
由 [芋道](https://doc.iocoder.cn/) 与 GoView 共同建设,基于 Vue3 搭建的低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可完成业务需求。
* 框架:基于 Vue3 框架编写,使用 hooks 写法抽离部分逻辑,使代码结构更加清晰
* 类型:使用 TypeScript 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容
* 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度
* 存储:拥有本地记忆,部分配置项采用 storage 存储本地,提升使用体验
* 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
* 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
## 项目地址
![preview](readme/preview.png)
* 前端:<https://gitee.com/zhijiantianya/yudao-ui-go-view>
* Boot 后端:<https://gitee.com/zhijiantianya/ruoyi-vue-pro>
* Cloud 后端:<https://gitee.com/zhijiantianya/yudao-cloud>
## 文档地址
* 演示环境:<http://dashboard.yudao.iocoder.cn/login> 「报表管理 - 大屏设计器」
* 文档地址:<https://doc.iocoder.cn/report/>
## 技术栈
主要技术栈为:
| 名称 | 版本 | 名称 | 版本 |
|-------------------|-------|-------------|--------|
| Vue | 3.2.x | TypeScript4 | 4.6.x |
| Vite | 2.9.x | NaiveUI | 2.27.x |
| ECharts | 5.3.x | Pinia | 2.0.x |
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
开发环境:
| 名称 | 版本 | 名称 | 版本 |
|------|---------|---------|-------|
| node | 16.14.x | npm | 8.5.x |
| pnpm | 7.1.x | windows | 11 |
已完成图表:
| 分类 | 名称 | 名称 | 名称 | 名称 |
|-----|--------------|----------|---------|----------------|
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
| \* | 漏斗图 | 中国地图 | 高德地图 | 🦊 |
| 信息 | 文字 | 渐变文字 | 词云 | 嵌套网页 |
| \* | 图片 | 视频 | 😺 | 🐯 |
| 列表 | 滚动排名列表 | 滚动表格 | 🐮 | 🐐 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 |
## 项目截图
#### 工作台
![工作台](readme/go-view-canvas.png)
#### 请求配置
![请求配置](readme/go-view-fetch.png)
#### 数据过滤
![数据过滤](readme/go-view-filter.png)
#### 高级事件编辑
![高级事件编辑](readme/go-view-event.png)
#### 快捷主页
![快捷主页](readme/go-view-indexpage.png)
#### 主题色
![主题色](readme/go-view-color.png)
#### 亮白主题
![亮白主题](readme/go-view-theme.png)

41
build/constant.ts

@ -0,0 +1,41 @@
import path from 'path'
export const OUTPUT_DIR = 'dist'
// monaco-editor 路径
export const prefix = `monaco-editor/esm/vs`
// chunk 警告大小
export const chunkSizeWarningLimit = 2000
// 禁用 brotliSize 压缩大小报告
export const brotliSize = false
// 分包
export const rollupOptions = {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: (chunkInfo) => {
if(['.png', '.jpg', '.jpeg'].includes(path.extname(chunkInfo.name))) {
return `static/[ext]/[name].[ext]`
}
return `static/[ext]/[name]-[hash].[ext]`
},
manualChunks: {
jsonWorker: [`${prefix}/language/json/json.worker`],
cssWorker: [`${prefix}/language/css/css.worker`],
htmlWorker: [`${prefix}/language/html/html.worker`],
tsWorker: [`${prefix}/language/typescript/ts.worker`],
editorWorker: [`${prefix}/editor/editor.worker`]
}
}
}
// 去除开发代码
export const terserOptions = {
compress: {
keep_infinity: true,
drop_console: true,
drop_debugger: true
}
}

85
index.css

@ -0,0 +1,85 @@
* {
margin: 0;
}
.first-loading-wrp {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #17171a;
}
.first-loading-wrp > h1 {
font-size: 128px;
}
.first-loading-wrp .loading-wrp {
padding: 98px;
display: flex;
justify-content: center;
align-items: center;
}
.dot {
animation: antRotate 1.2s infinite linear;
transform: rotate(45deg);
position: relative;
display: inline-block;
font-size: 32px;
width: 32px;
height: 32px;
box-sizing: border-box;
}
.dot i {
width: 14px;
height: 14px;
position: absolute;
display: block;
background-color: #1890ff;
border-radius: 100%;
transform: scale(0.75);
transform-origin: 50% 50%;
opacity: 0.3;
animation: antSpinMove 1s infinite linear alternate;
}
.dot i:nth-child(1) {
top: 0;
left: 0;
}
.dot i:nth-child(2) {
top: 0;
right: 0;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.dot i:nth-child(3) {
right: 0;
bottom: 0;
-webkit-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.dot i:nth-child(4) {
bottom: 0;
left: 0;
-webkit-animation-delay: 1.2s;
animation-delay: 1.2s;
}
@keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@-webkit-keyframes antRotate {
to {
-webkit-transform: rotate(405deg);
transform: rotate(405deg);
}
}
@keyframes antSpinMove {
to {
opacity: 1;
}
}
@-webkit-keyframes antSpinMove {
to {
opacity: 1;
}
}

30
index.html

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<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.0,maximum-scale=1.0,user-scalable=0"
/>
<link rel="icon" href="./favicon.ico" />
<title>GoView</title>
<link rel="stylesheet" href="./index.css" />
<script src="js/esobjs-xe2-plugin/dist-web/xe2-assets/js/load-common.js"></script>
</head>
<body>
<div id="appProvider" style="display: none;"></div>
<div id="app">
<div class="first-loading-wrp">
<div class="loading-wrp">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

104
package.json

@ -0,0 +1,104 @@
{
"type": "module",
"name": "go-view",
"version": "2.1.6",
"engines": {
"node": ">=12.0"
},
"scripts": {
"dev": "vite --host",
"build": "vue-tsc --noEmit && vite build",
"build:prod": "vite build --mode production",
"preview": "vite preview",
"new": "plop --plopfile ./plop/plopfile.js",
"postinstall": "husky install",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.vue src",
"lint:fix": "eslint --ext .js,.jsx,.ts,.tsx,.vue src --fix"
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@amap/amap-jsapi-types": "^0.0.8",
"@iconify/json": "^2.2.158",
"@types/color": "^3.0.3",
"@types/crypto-js": "^4.1.1",
"@types/keymaster": "^1.6.30",
"@types/lodash": "^4.14.184",
"@visactor/vchart": "^1.12.3",
"@visactor/vchart-theme": "^1.12.1",
"animate.css": "^4.1.1",
"axios": "^1.6.8",
"cesium": "1.99",
"color": "^4.2.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7",
"dom-helpers": "^5.2.1",
"echarts-liquidfill": "^3.1.0",
"echarts-stat": "^1.2.0",
"echarts-wordcloud": "^2.0.0",
"esobjs-xe2-plugin": "^0.1.126-beta-0.3",
"gsap": "^3.11.3",
"highlight.js": "^11.5.0",
"html2canvas": "^1.4.1",
"iconify-icon": "^1.0.8",
"keymaster": "^1.6.2",
"mitt": "^3.0.0",
"monaco-editor": "^0.33.0",
"naive-ui": "2.34.3",
"pinia": "^2.0.13",
"pnpm": "^8.7.0",
"screenfull": "^6.0.1",
"three": "^0.145.0",
"vite-plugin-cesium": "^1.2.23",
"vue": "^3.2.31",
"vue-demi": "^0.13.1",
"vue-i18n": "9.2.2",
"vue-router": "4.0.12",
"vue-xe2-plugin": "^0.1.3",
"vue3-lazyload": "^0.2.5-beta",
"vue3-sketch-ruler": "^1.3.3",
"vuedraggable": "^4.1.0",
"xbsj-xe2": "^0.1.16",
"xbsj-xe2-assets": "^0.1.16",
"smplotting-xe2-plugin": "^0.1.3"
},
"devDependencies": {
"@commitlint/cli": "^17.0.2",
"@commitlint/config-conventional": "^17.0.2",
"@types/node": "^16.11.26",
"@types/three": "^0.144.0",
"@typescript-eslint/eslint-plugin": "^5.18.0",
"@typescript-eslint/parser": "^5.18.0",
"@vicons/carbon": "^0.12.0",
"@vicons/ionicons5": "~0.11.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue/compiler-sfc": "^3.2.31",
"@vueuse/core": "^7.7.1",
"commitlint": "^17.0.2",
"default-passive-events": "^2.0.0",
"echarts": "^5.3.2",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.5.0",
"esobjs-xe2-plugin-assets": "^0.1.14",
"husky": "^8.0.1",
"lodash": "~4.17.21",
"mockjs": "^1.1.0",
"plop": "^3.0.5",
"prettier": "^2.6.2",
"sass": "^1.49.11",
"sass-loader": "^12.6.0",
"typescript": "4.6.3",
"vite": "4.3.6",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-externals": "^0.6.2",
"vite-plugin-importer": "^0.2.5",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-static-copy": "^1.0.6",
"vue-echarts": "^6.0.2",
"vue-tsc": "^0.28.10"
}
}

5
plop/plopfile.js

@ -0,0 +1,5 @@
const storeGenerator = require('./store-template/prompt')
module.exports = (plop) => {
plop.setGenerator('store', storeGenerator)
}

3
plop/store-template/index.d.hbs

@ -0,0 +1,3 @@
export interface {{upperDataName}}StoreType {
}

11
plop/store-template/index.hbs

@ -0,0 +1,11 @@
import { defineStore } from 'pinia'
import { {{upperDataName}}StoreType } from './{{name}}Store.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
export const use{{upperDataName}}Store = defineStore({
id: 'use{{upperDataName}}Store',
state: (): {{upperDataName}}StoreType => ({}),
getters: {},
actions: {}
})

45
plop/store-template/prompt.js

@ -0,0 +1,45 @@
module.exports = {
description: 'create a store',
prompts: [
{
type: 'input',
name: 'name',
message: 'Please enter store name,such as "newStoreName" :',
validate (value) {
if (!value || value.trim === '') {
return 'name is required';
}
return true;
},
}
],
actions: (data) => {
const dataName = data.name
// 首字母大写
const upperDataName = dataName.slice(0, 1).toUpperCase() + dataName.slice(1)
const actions = [
{
type: 'add',
path: `${process.cwd()}/src/store/modules/${dataName}Store/${dataName}Store.ts`, // 这里的name就是上面定义的键
templateFile: './store-template/index.hbs',
data: {
name: data.name,
upperDataName,
}
},
{
type: 'add',
path: `${process.cwd()}/src/store/modules/${dataName}Store/${dataName}Store.d.ts`, // 这里的name就是上面定义的键
templateFile: './store-template/index.d.hbs',
data: {
name: data.name,
upperDataName,
}
},
]
return actions
}
}

9360
pnpm-lock.yaml

File diff suppressed because it is too large Load Diff

12
prettier.config.js

@ -0,0 +1,12 @@
module.exports = {
printWidth: 120,
tabWidth: 2,
useTabs: false,
singleQuote: true,
semi: false,
trailingComma: "none",
bracketSpacing: true,
jsxSingleQuote: true,
jsxBracketSameLine: false,
arrowParens: "avoid"
}

10
preview.yml

@ -0,0 +1,10 @@
# preview.yml
autoOpen: true # 打开工作空间时是否自动开启所有应用的预览
apps:
- port: 3000 # 应用的端口
run: npm i --registry=https://registry.npmmirror.com && npm run dev # 应用的启动命令
command: # 使用此命令启动服务,且不执行run
root: ./ # 应用的启动目录
name: GoView # 应用名称
description: 开源、精美、便捷的「数据可视化」低代码开发平台 # 应用描述
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen)

BIN
public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
readme/go-view-canvas.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 KiB

BIN
readme/go-view-color.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
readme/go-view-doc.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
readme/go-view-event.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
readme/go-view-fetch.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
readme/go-view-filter.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

BIN
readme/go-view-indexpage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

BIN
readme/go-view-qq.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
readme/go-view-theme.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

BIN
readme/logo-poster.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
readme/logo-t-y.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
readme/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
readme/preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

65
src/App.vue

@ -0,0 +1,65 @@
<template>
<n-config-provider
:theme="darkTheme"
:hljs="hljsTheme"
:locale="locale"
:date-locale="dateLocale"
:theme-overrides="overridesTheme"
>
<go-app-provider>
<I18n></I18n>
<router-view></router-view>
</go-app-provider>
</n-config-provider>
</template>
<script lang="ts" setup>
import { NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
//
import vScreenVolcanoBlue from '@visactor/vchart-theme/public/vScreenVolcanoBlue.json';
import VChart from '@visactor/vchart';
import {IGlobalMarkThemeByName, IGlobalMarkThemeByType, ITheme} from "@visactor/vchart/esm/theme/interface";
import {languages} from "monaco-editor";
import type {IColorKey} from "@visactor/vchart/esm/theme/color-scheme/interface";
import type {ITokenKey} from "@visactor/vchart/esm/theme/token";
import type {ISeriesTheme} from "@visactor/vchart/esm/series/interface";
import type {IComponentTheme} from "@visactor/vchart/esm/component/interface";
const myVScreenVolcanoBlue: Partial<ITheme> = {
...vScreenVolcanoBlue,
type:"dark",
background:vScreenVolcanoBlue.background as IColorKey,
fontFamily:vScreenVolcanoBlue.fontFamily as ITokenKey,
mark:vScreenVolcanoBlue.mark as IGlobalMarkThemeByType,
markByName:vScreenVolcanoBlue.markByName as IGlobalMarkThemeByName,
series:vScreenVolcanoBlue.series as ISeriesTheme,
component: vScreenVolcanoBlue.component as unknown as IComponentTheme
//
};
VChart.ThemeManager.registerTheme('vScreenVolcanoBlue',myVScreenVolcanoBlue);
// apply the theme
VChart.ThemeManager.setCurrentTheme('vScreenVolcanoBlue');
//END
//
const darkTheme = useDarkThemeHook()
//
const overridesTheme = useThemeOverridesHook()
//
const hljsTheme = useCode()
//
useSystemInit()
//
const { locale, dateLocale } = useLang()
</script>

12
src/api/axios.config.ts

@ -0,0 +1,12 @@
import { ModuleTypeEnum } from '@/enums/httpEnum'
// 接口白名单(免登录)
export const fetchAllowList = [
// 登录
`${ModuleTypeEnum.SYSTEM}/auth-login`,
// 预览获取数据
`${ModuleTypeEnum.PROJECT}/getData`,
]
// 接口黑名单
export const fetchBlockList = []

220
src/api/axios.ts

@ -0,0 +1,220 @@
import axios, { AxiosResponse, AxiosRequestConfig, Axios,AxiosRequestHeaders,InternalAxiosRequestConfig } from 'axios'
import { ResultEnum, ModuleTypeEnum } from "@/enums/httpEnum"
import {PageEnum, ErrorPageNameMap, PreviewEnum} from "@/enums/pageEnum"
import { StorageEnum } from '@/enums/storageEnum'
import { axiosPre } from '@/settings/httpSetting'
import { SystemStoreEnum, SystemStoreUserInfoEnum,UserInfoType } from '@/store/modules/systemStore/systemStore.d'
import {
redirectErrorPage,
getLocalStorage,
routerTurnByName,
isPreview,
clearAllSessio,
clearAllStorage,
setLocalStorage,
setSessionStorage, fetchRouteParamsLocation, fetchRouteName, logout, fetchRoutePath
} from '@/utils'
import { fetchAllowList } from './axios.config'
import includes from 'lodash/includes'
import {useSystemStore} from "@/store/modules/systemStore/systemStore";
import { useDialog } from 'naive-ui'
// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现
// 请求队列
let requestList: any[] = []
// 是否正在刷新中
let isRefreshToken = false
// 请求路径
let base_url=`${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`
const dialog = useDialog()
export interface MyResponseType<T> extends AxiosResponse<T, any>{
code: ResultEnum
data: T
message: string
}
export interface MyRequestInstance extends Axios {
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
}
const axiosInstance = axios.create({
baseURL: base_url,
timeout: ResultEnum.TIMEOUT,
}) as unknown as MyRequestInstance
axiosInstance.interceptors.request.use(
(config:InternalAxiosRequestConfig) => {
// 获取 tenantId
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
// console.log(window.location)
const tenantId = info ? info[SystemStoreEnum.TENANT_INFO]['tenantId'] : undefined
if (tenantId) (config as Recordable).headers['tenant-id'] = tenantId
// 白名单校验
if (includes(fetchAllowList, config.url)) return config
// 获取 token
// 重新登录
if (!info) {
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return config
}
const userInfo:UserInfoType = info[SystemStoreEnum.USER_INFO] as UserInfoType
(config as Recordable).headers.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
// config.headers = {
// ...config.headers,
// [userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
// }
return config
},
(err: AxiosRequestConfig) => {
Promise.reject(err)
}
)
// 响应拦截器
axiosInstance.interceptors.response.use(
async (res: AxiosResponse<any>) => {
const config = res.config
const { code,msg } = res.data as { code: number,msg:string }
if (code === undefined || code === null) return Promise.resolve(res)
// 预览页面错误不进行处理
if (isPreview()&&code!==ResultEnum.TOKEN_OVERDUE) {
return Promise.resolve(res.data)
}
// 如果是验证码的返回,直接返回数据
// 成功
if (code === ResultEnum.SUCCESS) {
return Promise.resolve(res.data)
}
// 登录过期
if (code === ResultEnum.TOKEN_OVERDUE) {
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
console.log('Auth2:-------------------准备刷新令牌-----------------')
if (!isRefreshToken) {
isRefreshToken = true
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
// console.log(window.location)
const refreshToken = info ? info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_REFRESH_TOKEN] : undefined
// 1. 如果获取不到刷新令牌,则只能执行登出操作
if (!refreshToken) {
console.log('无刷新令牌,即将返回。')
return handleAuthorized()
}
// 2. 进行刷新访问令牌
try {
const systemStore = useSystemStore()
const refreshTokenRes = await getTefreshToken()
// 2.1 刷新成功,则回放队列的请求 + 当前请求
systemStore.setItem(SystemStoreEnum.USER_INFO, {
[SystemStoreUserInfoEnum.USER_TOKEN]: (await refreshTokenRes).data.data.accessToken,
[SystemStoreUserInfoEnum.USER_REFRESH_TOKEN]: (await refreshTokenRes).data.data.refreshToken,
[SystemStoreUserInfoEnum.TOKEN_NAME]: 'Authorization'
})
//修改当前访问令牌
// config.headers!.Authorization = 'Bearer ' + (await refreshTokenRes).data.data.accessToken
const userInfo:UserInfoType = info[SystemStoreEnum.USER_INFO] as UserInfoType
// config.headers = {
// ...config.headers,
// [userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token']: 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
// }
(config as Recordable).headers.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
requestList.forEach((cb: any) => {
cb()
})
requestList = []
console.log('Auth2:-------------------令牌刷新成功-----------------')
return axiosInstance(config)
} catch (e) {
// 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
// 2.2 刷新失败,只回放队列的请求
requestList.forEach((cb: any) => {
cb()
})
// 提示是否要登出。即不回放当前请求!不然会形成递归
return handleAuthorized()
} finally {
requestList = []
isRefreshToken = false
}
} else {
console.log('Auth2:-------------------已添加刷新队列-----------------')
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
// 添加到队列,等待刷新获取到新的令牌
return new Promise((resolve) => {
requestList.push(() => {
const userInfo = info[SystemStoreEnum.USER_INFO]
config.headers!.Authorization = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN] // 让每个请求携带自定义token 请根据实际情况自行修改
resolve(axiosInstance(config))
})
})
}
}
// 固定错误码重定向
if (ErrorPageNameMap.get(code)) {
redirectErrorPage(code)
return Promise.resolve(res.data)
}
if (code !== 200) {
if (msg === '无效的刷新令牌') {
// hard coding:忽略这个提示,直接登出
console.log(msg)
return handleAuthorized()
} else {
window['$message'].error(msg)
}
return Promise.reject('error')
}
// 提示错误
window['$message'].error(window['$t']((res.data as any).msg))
return Promise.resolve(res.data)
},
(err: AxiosResponse) => {
Promise.reject(err)
}
)
const getTefreshToken = async () => {
let tenantData = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
axios.defaults.headers.common['tenant-id'] = tenantData[SystemStoreEnum.TENANT_INFO]['tenantId'] ?? undefined;
return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + tenantData[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_REFRESH_TOKEN] ?? undefined)
}
const handleAuthorized = () =>{
// window['$message'].error(window['$t']('http.token_overdue_message'))
console.log(useDialog())
window['$dialog'].warning( {title: '登录已超时',
content: '登录超时,请重新登录。',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
// session 不需要清除 clearAllSessio() //清除所有Session缓存
clearAllStorage() //清除所有Storage缓存
//临时缓存跳回目录进行登录重新跳回
if('/chart/preview' === fetchRoutePath()){
setSessionStorage('setRedirectPath','/chart/preview')
setSessionStorage('setRedirectPathId', fetchRouteParamsLocation())
}
logout()
return Promise.resolve(window['$t']('http.token_overdue_message'))
}
})
}
export default axiosInstance

254
src/api/http.ts

@ -0,0 +1,254 @@
import axiosInstance from './axios'
import {
RequestHttpEnum,
ContentTypeEnum,
RequestBodyEnum,
RequestDataTypeEnum,
RequestContentTypeEnum,
RequestParamsObjType
} from '@/enums/httpEnum'
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { getLocalStorage } from "@/utils";
import { StorageEnum } from "@/enums/storageEnum";
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
export const get = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.GET,
params: params,
})
}
export const post = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.POST,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const patch = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.PATCH,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.PUT,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const del = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
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.PATCH:
return patch
case RequestHttpEnum.PUT:
return put
case RequestHttpEnum.DELETE:
return del
default:
return get
}
}
const prefix = 'javascript:'
// 对输入字符进行转义处理
export const translateStr = (target: string | Record<any, any>) => {
if (typeof target === 'string') {
if (target.startsWith(prefix)) {
const funcStr = target.split(prefix)[1]
let result
try {
result = new Function(`${funcStr}`)()
} catch (error) {
console.log(error)
window['$message'].error('js内容解析有误!')
}
return result
} else {
return target
}
}
for (const key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
const subTarget = target[key]
target[key] = translateStr(subTarget)
}
}
return target
}
// 处理 token 和多租户的头;注意:只拼接属于 VITE_DEV_PATH 或 VITE_PROD_PATH 开头的 URL 地址,就是自己的后端
export const appendTokenAndTenant = (headers: RequestParamsObjType, requestUrl: string) => {
if (requestUrl.indexOf(import.meta.env.VITE_DEV_PATH) === -1
|| requestUrl.indexOf(import.meta.env.VITE_PROD_PATH) === -1) {
return headers
}
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
if (!info) {
return headers;
}
// ① 获取 tenantId
const tenantId = info ? info[SystemStoreEnum.TENANT_INFO]['tenantId'] : undefined
if (tenantId) {
headers['tenant-id'] = tenantId
}
// ② 获取 token
const userInfo = info[SystemStoreEnum.USER_INFO]
if (!userInfo) {
return headers
}
headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = 'Bearer ' + userInfo[SystemStoreUserInfoEnum.USER_TOKEN]
return headers
}
/**
* *
* @param targetParams
* @param globalParams
*/
export const customizeHttp = (targetParams: RequestConfigType, globalParams: RequestGlobalConfigType) => {
if (!targetParams || !globalParams) {
return
}
// 全局
const {
// 全局请求源地址
requestOriginUrl,
// 全局请求内容
requestParams: globalRequestParams
} = globalParams
// 目标组件(优先级 > 全局组件)
const {
// 请求地址
requestUrl,
// 普通 / sql
requestContentType,
// 获取数据的方式
requestDataType,
// 请求方式 get/post/del/put/patch
requestHttpType,
// 请求体类型 none / form-data / x-www-form-urlencoded / json /xml
requestParamsBodyType,
// SQL 请求对象
requestSQLContent,
// 请求内容 params / cookie / header / body: 同 requestParamsBodyType
requestParams: targetRequestParams
} = targetParams
// 静态排除
if (requestDataType === RequestDataTypeEnum.STATIC) return
if (!requestUrl) {
return
}
// 处理头部
let headers: RequestParamsObjType = {
...globalRequestParams.Header,
...targetRequestParams.Header
}
headers = translateStr(headers)
// 处理 token 和多租户的头
headers = appendTokenAndTenant(headers, requestUrl)
// data 参数
let data: RequestParamsObjType | FormData | string = {}
// params 参数
let params: RequestParamsObjType = { ...targetRequestParams.Params }
params = translateStr(params)
// form 类型处理
let formData: FormData = new FormData()
formData.set('default', 'defaultData')
// 类型处理
switch (requestParamsBodyType) {
case RequestBodyEnum.NONE:
break
case RequestBodyEnum.JSON:
headers['Content-Type'] = ContentTypeEnum.JSON
data = translateStr(JSON.parse(targetRequestParams.Body['json']))
// json 赋值给 data
break
case RequestBodyEnum.XML:
headers['Content-Type'] = ContentTypeEnum.XML
// xml 字符串赋值给 data
data = translateStr(targetRequestParams.Body['xml'])
break
case RequestBodyEnum.X_WWW_FORM_URLENCODED: {
headers['Content-Type'] = ContentTypeEnum.FORM_URLENCODED
const bodyFormData = targetRequestParams.Body['x-www-form-urlencoded']
for (const i in bodyFormData) formData.set(i, translateStr(bodyFormData[i]))
// FormData 赋值给 data
data = formData
break
}
case RequestBodyEnum.FORM_DATA: {
headers['Content-Type'] = ContentTypeEnum.FORM_DATA
const bodyFormUrlencoded = targetRequestParams.Body['form-data']
for (const i in bodyFormUrlencoded) {
formData.set(i, translateStr(bodyFormUrlencoded[i]))
}
// FormData 赋值给 data
data = formData
break
}
}
// sql 处理
if (requestContentType === RequestContentTypeEnum.SQL) {
headers['Content-Type'] = ContentTypeEnum.JSON
data = requestSQLContent
}
try {
const url = (new Function("return `" + `${requestOriginUrl}${requestUrl}`.trim() + "`"))();
return axiosInstance({
url,
method: requestHttpType,
data,
params,
headers
})
} catch (error) {
console.log(error)
window['$message'].error('URL地址格式有误!')
}
}

100
src/api/mock/graph.json

@ -0,0 +1,100 @@
{
"nodes": [
{
"id": "0",
"name": "Myriel",
"symbolSize": "@integer(0, 50)",
"x": -266.82776,
"y": 299.6904,
"value": "@integer(0, 50)",
"category": 3
},
{
"id": "1",
"name": "Napoleon",
"symbolSize": "@integer(0, 50)",
"x": -418.08344,
"y": 446.8853,
"value": "@integer(0, 50)",
"category": 5
},
{
"id": "2",
"name": "MlleBaptistine",
"symbolSize": "@integer(0, 50)",
"x": -212.76357,
"y": 245.29176,
"value": "@integer(0, 50)",
"category": 1
},
{
"id": "3",
"name": "MmeMagloire",
"symbolSize": "@integer(0, 50)",
"x": -242.82404,
"y": 235.26283,
"value": "@integer(0, 50)",
"category": 1
},
{
"id": "4",
"name": "CountessDeLo",
"symbolSize": "@integer(0, 50)",
"x": -379.30386,
"y": 429.06424,
"value": "@integer(0, 50)",
"category": 0
}
],
"links": [
{
"source": "1",
"target": "@integer(2, 4)"
},
{
"source": "2",
"target": "@integer(3, 4)"
},
{
"source": "3",
"target": "@integer(0, 2)"
},
{
"source": "3",
"target": "@integer(0, 1)"
},
{
"source": "4",
"target": "@integer(0, 3)"
}
],
"categories": [
{
"name": "A"
},
{
"name": "B"
},
{
"name": "C"
},
{
"name": "D"
},
{
"name": "E"
},
{
"name": "F"
},
{
"name": "G"
},
{
"name": "H"
},
{
"name": "I"
}
]
}

199
src/api/mock/heatMapData.json

@ -0,0 +1,199 @@
{
"xAxis": [
"12a",
"1a",
"2a",
"3a",
"4a",
"5a",
"6a",
"7a",
"8a",
"9a",
"10a",
"11a",
"12p",
"1p",
"2p",
"3p",
"4p",
"5p",
"6p",
"7p",
"8p",
"9p",
"10p",
"11p"
],
"yAxis": ["Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday"],
"seriesData": [
[0, 0, "@integer(0, 10)"],
[1, 0, "@integer(0, 10)"],
[2, 0, "-"],
[3, 0, "-"],
[4, 0, "-"],
[5, 0, "-"],
[6, 0, "-"],
[7, 0, "-"],
[8, 0, "-"],
[9, 0, "-"],
[10, 0, "-"],
[11, 0, "@integer(0, 10)"],
[12, 0, "@integer(0, 10)"],
[13, 0, "@integer(0, 10)"],
[14, 0, "@integer(0, 10)"],
[15, 0, "@integer(0, 10)"],
[16, 0, "@integer(0, 10)"],
[17, 0, "@integer(0, 10)"],
[18, 0, "@integer(0, 10)"],
[19, 0, "@integer(0, 10)"],
[20, 0, "@integer(0, 10)"],
[21, 0, "@integer(0, 10)"],
[22, 0, "@integer(0, 10)"],
[23, 0, "@integer(0, 10)"],
[0, 1, 7],
[1, 1, "-"],
[2, 1, "-"],
[3, 1, "-"],
[4, 1, "-"],
[5, 1, "-"],
[6, 1, "-"],
[7, 1, "-"],
[8, 1, "-"],
[9, 1, "-"],
[10, 1, "@integer(0, 10)"],
[11, 1, "@integer(0, 10)"],
[12, 1, "@integer(0, 10)"],
[13, 1, "@integer(0, 10)"],
[14, 1, "@integer(0, 10)"],
[15, 1, "@integer(0, 10)"],
[16, 1, "@integer(0, 10)"],
[17, 1, "@integer(0, 10)"],
[18, 1, "@integer(0, 10)"],
[19, 1, "@integer(0, 10)"],
[20, 1, "@integer(0, 10)"],
[21, 1, "@integer(0, 10)"],
[22, 1, "@integer(0, 10)"],
[23, 1, "@integer(0, 10)"],
[0, 2, 1],
[1, 2, 1],
[2, 2, "-"],
[3, 2, "-"],
[4, 2, "-"],
[5, 2, "-"],
[6, 2, "-"],
[7, 2, "-"],
[8, 2, "-"],
[9, 2, "-"],
[10, 2, "@integer(0, 10)"],
[11, 2, "@integer(0, 10)"],
[12, 2, "@integer(0, 10)"],
[13, 2, "@integer(0, 10)"],
[14, 2, "@integer(0, 10)"],
[15, 2, "@integer(0, 10)"],
[16, 2, "@integer(0, 10)"],
[17, 2, "@integer(0, 10)"],
[18, 2, "@integer(0, 10)"],
[19, 2, "@integer(0, 10)"],
[20, 2, "@integer(0, 10)"],
[21, 2, "@integer(0, 10)"],
[22, 2, "@integer(0, 10)"],
[23, 2, "@integer(0, 10)"],
[0, 3, 7],
[1, 3, 3],
[2, 3, "-"],
[3, 3, "-"],
[4, 3, "-"],
[5, 3, "-"],
[6, 3, "-"],
[7, 3, "-"],
[8, 3, 1],
[9, 3, "-"],
[10, 3, "@integer(0, 10)"],
[11, 3, "@integer(0, 10)"],
[12, 3, "@integer(0, 10)"],
[13, 3, "@integer(0, 10)"],
[14, 3, "@integer(0, 10)"],
[15, 3, "@integer(0, 10)"],
[16, 3, "@integer(0, 10)"],
[17, 3, "@integer(0, 10)"],
[18, 3, "@integer(0, 10)"],
[19, 3, "@integer(0, 10)"],
[20, 3, "@integer(0, 10)"],
[21, 3, "@integer(0, 10)"],
[22, 3, "@integer(0, 10)"],
[23, 3, "@integer(0, 10)"],
[0, 4, "@integer(0, 10)"],
[1, 4, "@integer(0, 10)"],
[2, 4, "-"],
[3, 4, "-"],
[4, 4, "-"],
[5, 4, "@integer(0, 10)"],
[6, 4, "-"],
[7, 4, "-"],
[8, 4, "-"],
[9, 4, "@integer(0, 10)"],
[10, 4, "@integer(0, 10)"],
[11, 4, "@integer(0, 10)"],
[12, 4, "@integer(0, 10)"],
[13, 4, "@integer(0, 10)"],
[14, 4, "@integer(0, 10)"],
[15, 4, "@integer(0, 10)"],
[16, 4, "@integer(0, 10)"],
[17, 4, "@integer(0, 10)"],
[18, 4, "@integer(0, 10)"],
[19, 4, "@integer(0, 10)"],
[20, 4, "@integer(0, 10)"],
[21, 4, "@integer(0, 10)"],
[22, 4, "@integer(0, 10)"],
[23, 4, "-"],
[0, 5, "@integer(0, 10)"],
[1, 5, "@integer(0, 10)"],
[2, 5, "-"],
[3, 5, "@integer(0, 10)"],
[4, 5, "-"],
[5, 5, "-"],
[6, 5, "-"],
[7, 5, "-"],
[8, 5, "@integer(0, 10)"],
[9, 5, "-"],
[10, 5, "@integer(0, 10)"],
[11, 5, "@integer(0, 10)"],
[12, 5, "@integer(0, 10)"],
[13, 5, "@integer(0, 10)"],
[14, 5, "@integer(0, 10)"],
[15, 5, "@integer(0, 10)"],
[16, 5, "@integer(0, 10)"],
[17, 5, "@integer(0, 10)"],
[18, 5, "-"],
[19, 5, "@integer(0, 10)"],
[20, 5, "@integer(0, 10)"],
[21, 5, "@integer(0, 10)"],
[22, 5, "@integer(0, 10)"],
[23, 5, "-"],
[0, 6, "@integer(0, 10)"],
[1, 6, "-"],
[2, 6, "-"],
[3, 6, "-"],
[4, 6, "-"],
[5, 6, "-"],
[6, 6, "-"],
[7, 6, "-"],
[8, 6, "-"],
[9, 6, "-"],
[10, 6, "@integer(0, 10)"],
[11, 6, "-"],
[12, 6, "@integer(0, 10)"],
[13, 6, "@integer(0, 10)"],
[14, 6, "@integer(0, 10)"],
[15, 6, "@integer(0, 10)"],
[16, 6, "-"],
[17, 6, "-"],
[18, 6, "-"],
[19, 6, "-"],
[20, 6, "@integer(0, 10)"],
[21, 6, "@integer(0, 10)"],
[22, 6, "@integer(0, 10)"],
[23, 6, "@integer(0, 10)"]
]
}

120
src/api/mock/index.ts

@ -0,0 +1,120 @@
import test from './test.mock'
import { MockMethod } from 'vite-plugin-mock'
import { RequestHttpEnum } from '@/enums/httpEnum'
// 单个X数据
export const chartDataUrl = '/mock/chartData'
export const chartSingleDataUrl = '/mock/chartSingleData'
export const numberFloatUrl = '/mock/number/float'
export const numberIntUrl = '/mock/number/int'
export const textUrl = '/mock/text'
export const imageUrl = '/mock/image'
export const rankListUrl = '/mock/rankList'
export const scrollBoardUrl = '/mock/scrollBoard'
export const radarUrl = '/mock/radarData'
export const heatMapUrl = '/mock/heatMapData'
export const scatterBasicUrl = '/mock/scatterBasic'
export const mapUrl = '/mock/map'
export const capsuleUrl = '/mock/capsule'
export const wordCloudUrl = '/mock/wordCloud'
export const treemapUrl = '/mock/treemap'
export const threeEarth01Url = '/mock/threeEarth01Data'
export const sankeyUrl = '/mock/sankey'
export const graphUrl = '/mock/graphData'
const mockObject: MockMethod[] = [
{
// 正则
// url: /\/mock\/mockData(|\?\S*)$/,
url: chartDataUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchMockData
},
{
url: chartSingleDataUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchMockSingleData
},
{
url: numberFloatUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchNumberFloat
},
{
url: numberIntUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchNumberInt
},
{
url: textUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchText
},
{
url: imageUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchImage(Math.round(Math.random() * 10))
},
{
url: rankListUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchRankList
},
{
url: scrollBoardUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchScrollBoard
},
{
url: radarUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchRadar
},
{
url: heatMapUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchHeatmap
},
{
url: scatterBasicUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchScatterBasic
},
{
url: mapUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchMap
},
{
url: capsuleUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchCapsule
},
{
url: wordCloudUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchWordCloud
},
{
url: treemapUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchTreemap
},
{
url: threeEarth01Url,
method: RequestHttpEnum.GET,
response: () => test.threeEarth01Data
},
{
url: sankeyUrl,
method: RequestHttpEnum.GET,
response: () => test.fetchSankey
},
{
url: graphUrl,
method: RequestHttpEnum.GET,
response: () => test.graphData
},
]
export default mockObject

9
src/api/mock/map.json

@ -0,0 +1,9 @@
{
"markers|50": [
{
"name": "某某地市",
"value": "@integer(2, 20)",
"position": ["@float(115, 117, 1, 6)", "@float(38, 40, 1, 6)"]
}
]
}

86
src/api/mock/sankey.json

@ -0,0 +1,86 @@
{
"label": [
{
"name": "a"
},
{
"name": "b"
},
{
"name": "a1"
},
{
"name": "a2"
},
{
"name": "b1"
},
{
"name": "b2"
}
],
"links": [
{
"source": "a",
"target": "a1",
"value": "@integer(0, 10)"
},
{
"source": "a",
"target": "a2",
"value": "@integer(0, 10)"
},
{
"source": "b",
"target": "b1",
"value": "@integer(0, 10)"
},
{
"source": "a",
"target": "b1",
"value": "@integer(0, 10)"
},
{
"source": "b1",
"target": "a1",
"value": "@integer(0, 10)"
},
{
"source": "b1",
"target": "b2",
"value": "@integer(0, 10)"
}
],
"levels": [
{
"depth": 0,
"itemStyle": {
"color": "#decbe4"
},
"lineStyle": {
"color": "source",
"opacity": 0.9
}
},
{
"depth": 1,
"itemStyle": {
"color": "#b3cde3"
},
"lineStyle": {
"color": "source",
"opacity": 0.6
}
},
{
"depth": 2,
"itemStyle": {
"color": "#ccebc5"
},
"lineStyle": {
"color": "source",
"opacity": 0.6
}
}
]
}

56
src/api/mock/scatter.json

@ -0,0 +1,56 @@
[
{
"dimensions": ["data1"],
"source": [
[10.0, "@integer(0, 100)"],
[8.07, "@integer(0, 100)"],
[13.0, "@integer(0, 100)"],
[9.05, "@integer(0, 100)"],
[11.0, "@integer(0, 100)"],
[14.0, "@integer(0, 100)"],
[13.4, "@integer(0, 100)"],
[10.0, "@integer(0, 100)"],
[14.0, "@integer(0, 100)"],
[12.5, "@integer(0, 100)"],
[9.15, "@integer(0, 100)"],
[11.5, "@integer(0, 100)"],
[3.03, "@integer(0, 100)"],
[12.2, "@integer(0, 100)"],
[2.02, "@integer(0, 100)"],
[1.05, "@integer(0, 100)"],
[4.05, "@integer(0, 100)"],
[6.03, "@integer(0, 100)"],
[12.0, "@integer(0, 100)"],
[12.0, "@integer(0, 100)"],
[7.08, "@integer(0, 100)"],
[5.02, "@integer(0, 100)"]
]
},
{
"dimensions": ["data2"],
"source": [
[10.0, "@integer(0, 70)"],
[8.07, "@integer(0, 70)"],
[13.0, "@integer(0, 70)"],
[9.05, "@integer(0, 70)"],
[11.0, "@integer(0, 70)"],
[14.0, "@integer(0, 70)"],
[13.4, "@integer(0, 70)"],
[10.0, "@integer(0, 70)"],
[14.0, "@integer(0, 70)"],
[12.5, "@integer(0, 70)"],
[9.15, "@integer(0, 70)"],
[11.5, "@integer(0, 70)"],
[3.03, "@integer(0, 70)"],
[12.2, "@integer(0, 70)"],
[2.02, "@integer(0, 70)"],
[1.05, "@integer(0, 70)"],
[4.05, "@integer(0, 70)"],
[6.03, "@integer(0, 70)"],
[12.0, "@integer(0, 70)"],
[12.0, "@integer(0, 70)"],
[7.08, "@integer(0, 70)"],
[5.02, "@integer(0, 70)"]
]
}
]

239
src/api/mock/test.mock.ts

@ -0,0 +1,239 @@
import heatmapJson from './heatMapData.json'
import scatterJson from './scatter.json'
import mapJson from './map.json'
import tTreemapJson from './treemap.json'
import sankeyJson from './sankey.json'
import graphDataJson from './graph.json'
export default {
// 单图表
fetchMockSingleData: {
code: 0,
status: 200,
msg: '请求成功',
data: {
dimensions: ['product', 'dataOne'],
'source|20': [
{
product: '@name',
'dataOne|0-900': 3
}
]
}
},
// 胶囊图
fetchCapsule: {
code: 0,
status: 200,
msg: '请求成功',
data: {
dimensions: ['name', 'value'],
"source|2-5": [
{ 'name|+1': ["厦门","福州","北京","上海","新疆","郑州","湖南","内蒙古"], 'value|0-40': 20 },
]
}
},
// 图表
fetchMockData: {
code: 0,
status: 200,
msg: '请求成功',
data: {
dimensions: ['product', 'dataOne', 'dataTwo', 'dataThree'],
'source|20': [
{
product: '@name',
'dataOne|100-900': 3,
'dataTwo|100-900': 3,
'dataThree|100-900': 3
}
]
}
},
// 排名列表
fetchRankList: {
code: 0,
status: 200,
msg: '请求成功',
'data|50': [{ name: '@name', 'value|100-900': 5 }]
},
// 轮播表格
fetchScrollBoard: {
code: 0,
status: 200,
msg: '请求成功',
data: [
['行1列1', '行1列2', '1'],
['行2列1', '行2列2', '2'],
['行3列1', '行3列2', '3'],
['行4列1', '行4列2', '4'],
['行5列1', '行5列2', '5'],
['行6列1', '行6列2', '6'],
['行7列1', '行7列2', '行7列3'],
['行8列1', '行8列2', '行8列3'],
['行9列1', '行9列2', '行9列3'],
['行10列1', '行10列2', '行10列3']
]
},
// 获取数字-浮点型
fetchNumberFloat: {
code: 0,
status: 200,
msg: '请求成功',
data: '@float(0, 0.99, 1, 4)'
},
// 获取数字-整型
fetchNumberInt: {
code: 0,
status: 200,
msg: '请求成功',
data: '@integer(0, 100)'
},
// 文字
fetchText: {
code: 0,
status: 200,
msg: '请求成功',
data: '@paragraph(1, 10)'
},
// 图片
fetchImage: (num: number) => ({
code: 0,
status: 200,
msg: '请求成功',
data: `https://robohash.org/${num}`
}),
// 雷达
fetchRadar: {
code: 0,
status: 200,
msg: '请求成功',
data: {
radarIndicator: [
{ name: '@name', max: 10000 },
{ name: '@name', max: 10000 },
{ name: '@name', max: 10000 },
{ name: '@name', max: 10000 },
{ name: '@name', max: 10000 },
{ name: '@name', max: 10000 }
],
seriesData: [
{
value: [
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)'
],
name: 'data1'
},
{
value: [
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)',
'@integer(0, 10000)'
],
name: 'data2'
}
]
}
},
// 热力图
fetchHeatmap: {
code: 0,
status: 200,
msg: '请求成功',
data: heatmapJson
},
// 散点图
fetchScatterBasic: {
code: 0,
status: 200,
msg: '请求成功',
data: scatterJson
},
// 中国地图
fetchMap: {
code: 0,
status: 200,
msg: '请求成功',
data: mapJson
},
// 词云
fetchWordCloud: {
code: 0,
status: 200,
msg: '请求成功',
data: [
{
name: '@name',
value: 8000,
textStyle: {
color: '#78fbb2'
},
emphasis: {
textStyle: {
color: 'red'
}
}
},
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' },
{ name: '@name', value: '@integer(10, 8000)' }
]
},
// 树图
fetchTreemap: {
code: 0,
status: 200,
msg: '请求成功',
data: tTreemapJson
},
// 三维地球
threeEarth01Data: {
code: 0,
status: 200,
msg: '请求成功',
data: [
{
startArray: { name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' },
'endArray|10': [{ name: '@name', N: '@integer(10, 100)', E: '@integer(10, 100)' }]
}
]
},
// 桑基图
fetchSankey: {
code: 0,
status: 200,
msg: '请求成功',
data: sankeyJson
},
// 关系图
graphData: {
code: 0,
status: 200,
msg: '请求成功',
data: graphDataJson
},
}

50
src/api/mock/treemap.json

@ -0,0 +1,50 @@
[
{
"name": "@name",
"value": "@integer(0, 1000)",
"children": [
{
"name": "@name",
"value": "@integer(0, 500)"
},
{
"name": "@name",
"value": "@integer(0, 500)"
}
]
},
{
"name": "@name",
"value": "@integer(0, 1000)",
"children": [
{
"name": "@name",
"value": "@integer(0, 00)"
},
{
"name": "@name",
"value": "@integer(0, 500)"
}
]
},
{
"name": "@name",
"value": "@integer(0, 1000)",
"children": [
{
"name": "@name",
"value": "@integer(0, 1000)"
}
]
},
{
"name": "@name",
"value": "@integer(0, 1000)",
"children": [
{
"name": "@name",
"value": "@integer(0, 1000)"
}
]
}
]

3
src/api/path/index.ts

@ -0,0 +1,3 @@
export * from '@/api/path/project.api'
export * from '@/api/path/system.api'
export * from '@/api/path/infra.api'

13
src/api/path/infra.api.ts

@ -0,0 +1,13 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { RequestHttpEnum, ModuleTypeEnum, ContentTypeEnum } from '@/enums/httpEnum'
// * 上传文件
export const uploadFile = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<string>(`${ModuleTypeEnum.INFRA}/file/upload`, data, ContentTypeEnum.FORM_DATA)
return res
} catch {
httpErrorHandle()
}
}

77
src/api/path/project.api.ts

@ -0,0 +1,77 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { ProjectItem, ProjectDetail } from './project' // TODO 分页返回,优化使用 ProjectItem
// * 项目列表
export const projectListApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<{
list: ProjectItem[],
count: number
}>(`${ModuleTypeEnum.PROJECT}/my-page`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 新增项目
export const createProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<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}/get`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 保存项目
export const saveProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 修改项目基础信息
export const updateProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, 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()
}
}
// * 修改发布状态 [0 已发布, 1 未发布]
export const changeProjectReleaseApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/update`, data)
return res
} catch {
httpErrorHandle()
}
}

40
src/api/path/project.d.ts vendored

@ -0,0 +1,40 @@
export type ProjectItem = {
/**
* id
*/
id: string
/**
*
*/
name: string
/**
* :
*
* 0 -
* 1 -
*/
status: number
/**
*
*/
createTime: number
/**
* URL
*/
picUrl: string
/**
*
*/
creator: string
/**
*
*/
remark: string
}
export interface ProjectDetail extends ProjectItem {
/**
*
*/
content: string
}

66
src/api/path/system.api.ts

@ -0,0 +1,66 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import {AuthLoginRespVO, ProfileVO} from './system'
// * 登录
export const loginApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<AuthLoginRespVO>(`${ModuleTypeEnum.SYSTEM}/auth/login`, data)
console.log(res)
return res
} catch (err) {
httpErrorHandle()
}
}
// * 登出
export const logoutApi = async () => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/auth/logout`)
return res
} catch (err) {
httpErrorHandle()
}
}
// 查询用户个人信息
export const getUserProfileApi = async () => {
try {
const res = await http(RequestHttpEnum.GET)<ProfileVO>(`${ModuleTypeEnum.SYSTEM}/user/profile/get`)
return res
} catch (err) {
httpErrorHandle()
}
}
// 获取验证图片 以及token
export const getCodeApi = async (data: any) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/captcha/get`, data)
return res.data
} catch (err) {
httpErrorHandle()
}
}
// 滑动或者点选验证
export const reqCheckApi = async (data: any) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.SYSTEM}/captcha/check`, data)
return res.data
} catch (err) {
httpErrorHandle()
}
}
// 使用租户名,获得租户编号
export const getTenantIdByNameApi = async (name: string) => {
try {
const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.SYSTEM}/tenant/get-id-by-name?name=` + name)
return res
} catch (err) {
httpErrorHandle()
}
}

23
src/api/path/system.d.ts vendored

@ -0,0 +1,23 @@
export interface AuthLoginRespVO {
/**
*
*/
userId: number
/**
* 访
*/
accessToken: string
/**
*
*/
refreshToken: string
/**
*
*/
expiresTime: number
}
export interface ProfileVO {
id: number
nickname: string
}

255
src/assets/images/Error.svg

@ -0,0 +1,255 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px" y="0px"
viewBox="0 0 600 600" enable-background="new 0 0 600 600" xml:space="preserve">
<g id="LEFT_ARM_1">
<g id="XMLID_46_">
<path id="XMLID_290_" fill="#FFB96C" d="M294.4,485.5c-1.2,0.3-2.4,0.4-3.6,0.4c-0.2,0-0.4,0-0.6,0c-8.4-0.3-16.2-6.9-21-15.7
c-21.3-39.2-27.1-63.4-34.8-89.9c-1.9-6.6-1.4-13.3,1.4-18.1c2.2-3.7,5.7-6.4,10.5-6.9c0.6-0.1,1.1-0.1,1.7-0.1
c8.5,0,17.4,6.8,20.9,15.6l36.5,89.4C310,471.5,305,483.1,294.4,485.5z"/>
<path id="XMLID_280_" fill="#FCAF63" d="M290.2,485.9c-8.4-0.3-16.2-6.9-21-15.7c-21.3-39.2-27.1-63.4-34.8-89.9
c-1.9-6.6-1.4-13.3,1.4-18.1c9.5,23,40.7,98.5,50.3,116.1C287.6,481.1,289,483.6,290.2,485.9z"/>
</g>
</g>
<g id="LEFT_ARM_2">
<g id="XMLID_10_">
<g id="XMLID_42_">
<path id="XMLID_293_" fill="#FFB96C" d="M340.2,472c-0.9,2.3-2.1,4.1-3.3,5c-7.2,5.7-14.3,7-26.2,9.6c-11.9,2.6-24.2,2-29.9-3.4
c-1.9-1.8-3.3-3.8-4.1-5.9c-2.5-6-0.3-12.3,6.8-15c4.2-1.6,42.4-10.6,48.7-9.4C343.1,455,342.9,465.3,340.2,472z"/>
<path id="XMLID_279_" fill="#FCAF63" d="M340.2,472c-0.9,2.3-2.1,4.1-3.3,5c-7.2,5.7-14.3,7-26.2,9.6c-11.9,2.6-24.2,2-29.9-3.4
c-1.9-1.8-3.3-3.8-4.1-5.9c3.2,0.9,9.6,2.1,20.5,0.9C306.4,477.2,325.3,474.3,340.2,472z"/>
</g>
<g id="XMLID_41_">
<path id="XMLID_49_" fill="#FEA691" d="M330.2,453.6c-11.9,4-10.6,11.9-8.8,19.6c1.8,7.7,16.6,27.5,21.1,28.5s4.8-0.8,3.6-4.5
c-1.2-3.7-9.7-16.6-9.7-16.6s9.4,12.8,13.3,16.6c3.9,3.8,7.2,3.5,7.1-0.7c-0.2-4.2-9.5-18.3-9.5-18.3s8.2,10.8,11.6,14.5
s7.9,3.1,6.3-1.9c-1.5-5-8.3-15.9-8.3-15.9s6.6,11,11,12.1c4.4,1.1,1.7-5.5-3-13.9C360.3,464.5,345,448.6,330.2,453.6z"/>
<path id="XMLID_50_" fill="#FEA691" d="M320.2,464.6c0,0-2.5,9.8-0.9,18.4s4.3,10.3,6.1,10.7s2.4-1.9,1.5-5.6
c-0.9-3.7,1.5-11,1.5-11S325.8,462.4,320.2,464.6z"/>
</g>
</g>
</g>
<g id="BODY">
<g id="XMLID_70_">
<path id="XMLID_45_" fill="#FEC272" d="M273.1,496H172.2c0,0-13.9-97.2-5.1-121.1c2.5-6.8,5.8-12.3,9.6-16.9
c9.5-11.6,21.7-16.9,30-19c10.9-2.8,20.4-2.9,28.6-0.9c21.8,5.2,33.9,25.1,37.8,46.8C278.5,414.8,273.1,496,273.1,496z"/>
<path id="XMLID_43_" fill="#F9B35F" d="M207.6,358.5c-13.2,3.4-25.3,3-31-0.5c9.5-11.6,21.7-16.9,30-19
c10.9-2.8,20.4-2.9,28.6-0.9C237,344.9,224.6,354.1,207.6,358.5z"/>
</g>
</g>
<g id="RIGHT_ARM_1">
<g id="XMLID_16_">
<path id="XMLID_278_" fill="#FFCD92" d="M199,381.3c0,1.6-0.1,3.2-0.4,4.7c-4.1,26.6-27.7,90.6-27.7,90.6c-1.7,5.1-5.3,8.9-9.7,11
c-4.4,2-9.5,2.4-14.4,0.5c-7.6-3-11.2-10.2-11.2-18.1c0-1.7,0.2-3.4,0.5-5.1c6.9-37.3,19.2-68.2,29.3-90
c4.4-9.6,15.2-15.6,24.7-10.8c2.9,1.4,4.9,3.7,6.4,6.3C198.3,373.6,199,377.4,199,381.3z"/>
<path id="XMLID_273_" fill="#FCB765" d="M199,381.3c0,1.6-0.1,3.2-0.4,4.7c-4.1,26.6-27.7,90.6-27.7,90.6c-1.7,5.1-5.3,8.9-9.7,11
l35.2-117.3C198.3,373.6,199,377.4,199,381.3z"/>
</g>
</g>
<g id="RIGHT_ARM_2">
<g id="XMLID_17_">
<g id="XMLID_20_">
<path id="XMLID_285_" fill="#FFCD92" d="M230.5,487.4c-2.2,5.4-9.4,5.6-9.4,5.6s-20.2,1.2-37.7,1.2c-17.5,0-34.7,0-41.7-7.9
c-1.4-1.6-2.5-3.4-3.1-5.3c-2.6-7.3,0.7-16,11.1-20.4c7.5-3.2,16.1-2.1,25.5-1.2c9.4,0.9,27.5,5.1,38,7.9
c10.6,2.7,16.9,5.4,17.8,15.4C231.3,484.6,231,486.1,230.5,487.4z"/>
<path id="XMLID_284_" fill="#FCB765" d="M230.5,487.4c-2.2,5.4-9.4,5.6-9.4,5.6s-20.2,1.2-37.7,1.2c-17.5,0-34.7,0-41.7-7.9
c-1.4-1.6-2.5-3.4-3.1-5.3c7.8,2.4,18.3,5.2,26.7,5.9C189,488.9,220.4,487.9,230.5,487.4z"/>
</g>
<g id="XMLID_2_">
<g id="XMLID_18_">
<path id="XMLID_47_" fill="#FEA691" d="M251.6,471.3c0,1.6-0.2,3.3-0.6,5.1c-2.1,8.6-13.2,15.2-30.1,16.1
c-7.5,0.4-12.6,0.4-16-0.4c-4.4-1.1-6.1-3.7-6.5-9.1c-0.5-6.9,4.7-13.2,8.6-15.9c11.7-7.9,22.6-8.5,32.1-7.6
C247.6,460.4,251.5,465.1,251.6,471.3z"/>
<path id="XMLID_44_" fill="#FC8172" d="M251.6,471.3c0,1.6-0.2,3.3-0.6,5.1c-2.1,8.6-13.2,15.2-30.1,16.1
c-7.5,0.4-12.6,0.4-16-0.4c-0.4-1-0.7-2.2-0.8-3.7c-0.5-5.9,4.4-11.4,8.2-13.7c11.1-6.8,21.5-7.4,30.5-6.5
C246.8,468.5,249.7,469.6,251.6,471.3z"/>
</g>
<g id="XMLID_19_">
<path id="XMLID_48_" fill="#C7DCF9" d="M264.7,488.7c0,1.1-0.2,2.1-0.5,3.2h-55c-0.3-1-0.5-2.1-0.5-3.2c0-9.6,12.5-17.4,28-17.4
C252.2,471.3,264.7,479.1,264.7,488.7z"/>
<path id="XMLID_254_" opacity="0.55" fill="#C7DCF9" d="M263.5,490.2c0,0.6-0.1,1.1-0.4,1.7h-50.3c-0.3-0.6-0.4-1.1-0.4-1.7
c0-5.1,11.4-9.3,25.5-9.3C252.1,480.9,263.5,485.1,263.5,490.2z"/>
</g>
<g id="XMLID_37_">
<path id="XMLID_28_" fill="#FEA691" d="M252.6,456.6c3.6,0.4,6.1,2.7,7.5,7.5c1.4,4.8,1.7,11.9,0.2,14.4
c-1.5,2.5-4.3,3.6-7.4,1.1c-3.1-2.5-4.8-9.5-5.8-13C245.9,462,244.5,455.8,252.6,456.6z"/>
<g id="XMLID_4_">
<path id="XMLID_38_" fill="#FEA691" d="M239.2,454.3c3.9,0.4,5.5,3.7,7,8.7c1.5,5,1.8,12.6,0.2,15.3c-1.6,2.6-4.6,3.8-7.9,1.2
c-3.3-2.6-5.2-10.1-6.2-13.8C231,460.8,230.4,453.5,239.2,454.3z"/>
<path id="XMLID_79_" fill="#FF8D76" d="M243.1,480.8c-1.4,0.3-3,0-4.6-1.4c-3.3-2.6-5.1-10.1-6.2-13.8c-1.1-4-1.7-9.7,3-11.1
c-0.9,2.7-0.4,6.4,0.3,9.2c1,4.3,2.9,13,6.2,16C242.3,480.2,242.7,480.6,243.1,480.8z"/>
</g>
<path id="XMLID_39_" fill="#FEA691" d="M224.6,456.6c3.9,0.4,6.5,2.9,8,7.9s1.8,12.6,0.2,15.3c-1.6,2.6-4.6,3.8-7.9,1.2
c-3.3-2.6-5.2-10.1-6.2-13.8C217.4,462.3,215.9,455.7,224.6,456.6z"/>
<path id="XMLID_81_" fill="#FF8D76" d="M228.5,482.4c-1.1,0-2.3-0.5-3.5-1.5c-3.3-2.6-5.1-10.1-6.2-13.8
c-1-3.8-2.2-8.6,1.5-10.2c-0.3,2.5,0.4,5.7,1.1,8.3c1.2,4.5,3.3,13.7,7,17C228.4,482.4,228.4,482.4,228.5,482.4z"/>
<path id="XMLID_40_" fill="#FEA691" d="M211.5,459.4c3.4-1,6,2.7,7.3,7.3c1.3,4.6,1.7,11.6,0.2,14c-1.4,2.4-4.2,3.5-7.2,1.1
c-3-2.4-3.8-7-4.7-10.4C205.9,467,204.9,461.4,211.5,459.4z"/>
<path id="XMLID_82_" fill="#FF8D76" d="M215.2,483.2c-1.1,0-2.2-0.4-3.4-1.4c-3-2.4-3.8-7-4.7-10.4c-1.1-3.8-1.9-8.5,2.1-11
c-0.3,2.7,0.2,5.6,0.7,8.2c0.9,4.6,1.6,10.9,5,14.3C215,483,215.1,483.1,215.2,483.2z"/>
<path id="XMLID_78_" fill="#FF8D76" d="M256.8,480.9c-1.2,0.1-2.5-0.3-3.8-1.4c-3.1-2.5-4.8-9.5-5.8-13c-1-3.7-2.2-8.5,1.8-9.7
c0,2.2,0.5,4.7,1,6.9c1,4.5,2.9,13.5,6.1,16.7C256.4,480.6,256.6,480.8,256.8,480.9z"/>
</g>
</g>
</g>
</g>
<g id="HEAD">
<g id="XMLID_89_">
<path id="XMLID_6_" fill="#FF8D76"
d="M208.8,235c0,0,9.3-3.8,15.6,8.8c6.3,12.7-0.5,20.8-0.5,20.8S217.7,246.3,208.8,235z"/>
<path id="XMLID_173_" fill="#FEA691" d="M215.2,350.9c-8.8,4.1-14.9-1.6-14.9-1.6l-5.5-11.9l-9.9-21.4c14.9-3.2,27.9-5.7,27.9-5.7
l2.3,9.5l4.3,17.7C219.2,337.6,224,346.9,215.2,350.9z"/>
<path id="XMLID_171_" fill="#FF8D76" d="M215,319.9c-1.3,1.9-2.7,3.9-4.4,5.8c-4.3,5.1-10.5,9-15.9,11.7l-9.9-21.4
c14.9-3.2,27.9-5.7,27.9-5.7L215,319.9z"/>
<ellipse id="XMLID_3_" transform="matrix(0.8545 -0.5194 0.5194 0.8545 -114.0092 131.008)"
fill="#FEA691" cx="176.9" cy="269" rx="47.2" ry="57.7"/>
<path id="XMLID_12_" fill="#FF8D76" d="M217.4,308.8c-2.9,3.7-6.5,6.9-10.6,9.5c-22.3,13.5-53.7,2.4-70.3-24.8
c-16.4-26.9-12-59.6,9.7-73.4c-12.6,16.2-13.2,42.2,0.3,64.3c16.5,27.2,48,38.3,70.3,24.8C217,309.1,217.2,309,217.4,308.8z"/>
<path id="XMLID_5_" fill="#283575" d="M157.2,309.5c0,0-17-13.4-21.3-37.4s0.5-33.7,20.2-45.3c19.7-11.5,34.4-7.4,34.4-7.4
s-14-10.5-36.9-6.6c-22.9,3.8-46.2,25.6-41.4,58.4C117.2,306.2,138,316.5,157.2,309.5z"/>
<path id="XMLID_11_" fill="#F76F59" d="M177.8,246.8c-2.7,1.9,1.1,12,9.3,19.5c8.2,7.5,16.1,3.6,16.3-3.8
C203.6,254.9,187.1,240.2,177.8,246.8z"/>
<path id="XMLID_7_" fill="#FF8D76"
d="M137.5,291.4c0,0-16,15.7-1.6,29.4c13.8,13.1,31.2-4.5,31.2-4.5S142.7,303.2,137.5,291.4z"
/>
<path id="XMLID_250_" fill="#F76F59"
d="M139.4,300.5c0,0-9,8.8-0.9,16.6c7.8,7.4,17.6-2.5,17.6-2.5S142.3,307.2,139.4,300.5z"/>
</g>
</g>
<g id="HAIR">
<g id="XMLID_84_">
<path id="XMLID_8_" fill="#283575" d="M188.5,218.1c0,0,1.7-30.2-15.5-42.5c-19.4-13.8-30.3,6.1-23.9,22.4
c2.8,7.3,5.8,11.7,8.2,14.3c2.2,2.4,5.2,3.8,8.4,4L188.5,218.1z"/>
<path id="XMLID_9_" fill="#283575" d="M122.7,192.6c-15.3,12.2-2.1,29.7,4.2,34.4c2.7,2,5.6,3.6,8.1,4.8c3.4,1.6,7.4,1.4,10.6-0.6
l21.6-13.7C167.2,217.6,143,176.5,122.7,192.6z"/>
<path id="XMLID_51_" fill="#3C4E8E"
d="M159,172.3c-4.8,0.6,0.5,9.8,7.5,11S171.3,170.8,159,172.3z"/>
<path id="XMLID_61_" fill="#3C4E8E"
d="M128.7,192.8c-2.8,3.2,4.5,7.3,10.4,5.3C145.1,196.2,134.9,185.8,128.7,192.8z"/>
</g>
</g>
<g id="MOUTH">
<g id="XMLID_83_">
<path id="XMLID_177_" fill="#F76F59" d="M217.7,285c-0.5,1-1.2,1.9-2.2,2.7c-3.7,2.9-6.5,7.1-8.5,11.5c-1.8,3.9-6.4,8.5-10.7,5.2
c-0.5-0.4-1-0.8-1.4-1.4c-4.5-5.7-2.8-20.4,4.2-26.9c5.4-5,12.1-3.7,15.5-0.9C217.9,277.7,219.3,281.7,217.7,285z"/>
<path id="XMLID_175_" fill="#FF6EA9" d="M217.7,285c-0.5,1-1.2,1.9-2.2,2.7c-3.7,2.9-6.5,7.1-8.5,11.5c-1.8,3.9-6.4,8.5-10.7,5.2
c0-6.3,2.3-13.7,6.7-17.7C208.1,282.1,214.1,282.7,217.7,285z"/>
</g>
</g>
<g id="EYE_1">
<g id="XMLID_14_">
<path id="XMLID_86_" fill="#1C3177" d="M155.8,267.7c-3.2,0-5.7-1-5.9-1.1c-1.3-0.5-1.9-2-1.4-3.3c0.5-1.3,2-1.9,3.3-1.4
c0.1,0,5.6,2.2,8.6-1.1c3.9-4.1-0.2-9.4-0.3-9.6c-0.9-1.1-0.7-2.7,0.4-3.6c1.1-0.9,2.7-0.7,3.6,0.4c2.4,3.1,5.5,10.4,0,16.2
C161.6,266.9,158.5,267.7,155.8,267.7z"/>
</g>
</g>
<g id="EYE_2">
<g id="XMLID_15_">
<path id="XMLID_85_" fill="#1C3177" d="M193,242.6c-5.1,0-9.4-3.8-9.7-4c-1.1-0.9-1.1-2.6-0.2-3.6c0.9-1,2.5-1.1,3.6-0.2
c0,0,4.6,3.9,8,2.4c1.5-0.7,0.4-3.8,0.3-3.9c-0.5-1.3,0.1-2.8,1.5-3.3c1.3-0.5,2.8,0.1,3.3,1.4c1.5,3.7,1.1,8.6-3,10.4
C195.5,242.4,194.2,242.6,193,242.6z"/>
</g>
</g>
<g id="EYEBROW_1">
<g id="XMLID_1_">
<path id="XMLID_88_" fill="#1C3177" d="M142.4,261.7c-0.1,0-0.2,0-0.3,0c-1.4-0.2-2.4-1.4-2.3-2.8c0-0.3,0.7-6.3,4.9-12.4
c4.1-6.1,8.3-8.2,8.5-8.3c1.3-0.6,2.8-0.1,3.4,1.2c0.6,1.3,0.1,2.8-1.2,3.4c0,0-3.2,1.7-6.5,6.5c-3.4,5-4,10-4,10.1
C144.8,260.7,143.7,261.7,142.4,261.7z"/>
</g>
</g>
<g id="EYEBROW_2">
<g id="XMLID_13_">
<path id="XMLID_87_" fill="#1C3177" d="M179,232.1c-0.7,0-1.5-0.3-2-0.9c-0.9-1.1-0.7-2.7,0.4-3.6c0.3-0.2,2.6-2.1,6.7-3.3
c4.1-1.2,7.5-1.1,7.6-1.1c1.4,0,2.5,1.2,2.5,2.6c0,1.4-1.3,2.5-2.6,2.5c0,0-2.7-0.1-6,0.9c-3.2,1-5,2.4-5,2.4
C180.1,231.9,179.6,232.1,179,232.1z"/>
</g>
</g>
<g id="TABLE">
<g id="XMLID_248_">
<path id="XMLID_22_" fill="#99ADF9" d="M505.9,506.3H98.3c-4,0-7.2-3.2-7.2-7.2l0,0c0-4,3.2-7.2,7.2-7.2h407.6
c4,0,7.2,3.2,7.2,7.2l0,0C513.1,503,509.9,506.3,505.9,506.3z"/>
<path id="XMLID_198_" fill="#789FEF" d="M505.2,506.3H157.1c-4,0-7.2-3.2-7.2-7.2l0,0c0-4,3.2-7.2,7.2-7.2h348.1
c4,0,7.2,3.2,7.2,7.2l0,0C512.5,503,509.2,506.3,505.2,506.3z"/>
</g>
</g>
<g id="DESKTOP">
<g id="XMLID_186_">
<g id="XMLID_182_">
<path id="XMLID_25_" fill="#E1ECFF" d="M457.6,444.7h-186c-3.3,0-5.9-3-5.3-6.3l19.8-118.7c0.4-2.6,2.7-4.5,5.3-4.5h186
c3.3,0,5.9,3,5.3,6.3L463,440.2C462.5,442.8,460.3,444.7,457.6,444.7z"/>
<path id="XMLID_29_" fill="#C7DCF9" d="M461.6,444.7H278c-3.3,0-5.9-3-5.3-6.3l19.8-118.7c0.4-2.6,2.7-4.5,5.3-4.5h183.6
c3.3,0,5.9,3,5.3,6.3l-19.8,118.7C466.5,442.8,464.2,444.7,461.6,444.7z"/>
<path id="XMLID_31_" fill="#B7D4F7" d="M442.2,432H302c-2.6,0-4.5-2.3-4.1-4.8l15.1-90.6c0.3-2,2.1-3.5,4.1-3.5h140.1
c2.6,0,4.5,2.3,4.1,4.8l-15.1,90.6C445.9,430.5,444.2,432,442.2,432z"/>
</g>
<g id="XMLID_183_">
<path id="XMLID_24_" fill="#E1ECFF" d="M382.3,484.5h-25.5c-2.4,0-4.2-2-4-4.4l6.7-66.5c0.2-2,1.9-3.6,4-3.6H389
c2.4,0,4.2,2,4,4.4l-6.7,66.5C386.1,483,384.4,484.5,382.3,484.5z"/>
<path id="XMLID_26_" fill="#C7DCF9" d="M384.1,484.5h-23.4c-1.5,0-2.7-1.3-2.6-2.8l7-69.4c0.1-1.3,1.2-2.3,2.6-2.3h23.4
c1.5,0,2.7,1.3,2.6,2.8l-7,69.4C386.5,483.5,385.4,484.5,384.1,484.5z"/>
</g>
<g id="XMLID_185_">
<path id="XMLID_27_" fill="#E1ECFF" d="M424.7,491.8H318.5c-2.2,0-4-1.8-4-4V479c0-2.2,1.8-4,4-4h106.2c2.2,0,4,1.8,4,4v8.8
C428.7,490,426.9,491.8,424.7,491.8z"/>
<path id="XMLID_30_" fill="#C7DCF9" d="M426.9,491.8H327c-2.3,0-4.2-1.9-4.2-4.2v-8.4c0-2.3,1.9-4.2,4.2-4.2h99.9
c2.3,0,4.2,1.9,4.2,4.2v8.4C431,489.9,429.2,491.8,426.9,491.8z"/>
</g>
</g>
</g>
<g id="SIGN">
<g id="XMLID_21_">
<path id="XMLID_77_" fill="#FF97C9" d="M501.5,298.7c-1,0.7-2.3,1.2-3.7,1.2H402c-4.8,0-7.8-5-5.6-9.3l34.8-66.9l12.8-24.6
c2.4-4.5,8.8-4.5,11.2,0l48.2,91.5C505,293.6,503.9,297,501.5,298.7z"/>
<path id="XMLID_74_" fill="#FC72BB" d="M501.5,298.7c-1,0.7-2.3,1.2-3.7,1.2H402c-4.8,0-7.8-5-5.6-9.3l34.8-66.9L420.6,280
c-0.9,4.8,2.4,9.3,7.3,9.9L501.5,298.7z"/>
<g id="XMLID_32_">
<g id="XMLID_34_">
<path id="XMLID_35_" fill="#FFFFFF" d="M445.2,264.1l-5-35.8c-0.2-1.2,0.8-2.3,2-2.3h14.2c1.2,0,2.1,1.1,2,2.3l-5,35.8
c-0.1,1-1,1.7-2,1.7h-4.3C446.1,265.9,445.3,265.1,445.2,264.1z"/>
</g>
<circle id="XMLID_33_" fill="#FFFFFF" cx="449.3" cy="279.1" r="7.1"/>
</g>
</g>
</g>
<g id="STAR">
<path id="XMLID_195_" fill="#FEC272" d="M189.7,141.2l1.8,3.7c0.2,0.5,0.7,0.8,1.2,0.8l4,0.6c1.3,0.2,1.8,1.7,0.8,2.6l-2.9,2.8
c-0.4,0.4-0.5,0.9-0.4,1.4l0.7,4c0.2,1.2-1.1,2.2-2.2,1.6l-3.6-1.9c-0.4-0.2-1-0.2-1.4,0l-3.6,1.9c-1.1,0.6-2.4-0.4-2.2-1.6l0.7-4
c0.1-0.5-0.1-1-0.4-1.4l-2.9-2.8c-0.9-0.9-0.4-2.4,0.8-2.6l4-0.6c0.5-0.1,0.9-0.4,1.2-0.8l1.8-3.7
C187.5,140.1,189.1,140.1,189.7,141.2"/>
</g>
<g id="BUBBLE_1">
<path id="XMLID_23_" fill="#F0F6FF" d="M384.3,170.2c0,13.8-4,26.6-10.9,37.5c0,0,0,0,0,0c-2.5,5.8-15.1,30.3-57.9,49.9
c-44.9,20.6-84.7,5.9-84.7,5.9s24.5-16.1,19.9-43c-3.6-21.2-6.1-36.4-5.9-49.2c0-0.4,0-0.7,0-1.1c0-38.5,31.2-69.7,69.7-69.7
S384.3,131.7,384.3,170.2z"/>
</g>
<g id="BUBBLE_2">
<path id="XMLID_187_" fill="#C7DCF9" d="M238.1,216.5c-3.7-9.5-7.4-9.1-9.9-7.3c-2.3,1.7-2.8,7.6,0,13.2s5.6,5.2,8.4,3.7
S239.8,220.9,238.1,216.5z"/>
</g>
<g id="BUBBLE_3">
<path id="XMLID_249_" fill="#C7DCF9" d="M361.6,237.5c-15.4,8.2-14,14.5-10.4,18.3c3.4,3.6,13.5,3.2,22.4-2.6s7.8-10.5,4.7-15
C375.2,233.7,368.7,233.6,361.6,237.5z"/>
</g>
<g id="Layer_23">
<g id="XMLID_75_">
<g id="XMLID_73_">
<path id="XMLID_274_" fill="#99ADF9" d="M364.6,191.8c0,3.8-1.8,7.6-5.2,9.9c-7.4,5.2-19.2,12.9-32.2,19.7
c-8.3,4.4-15.5,7.8-21.3,10.3c-4.8,2.1-10.1,1.7-14.4-0.7c-2.9-1.6-5.3-4.1-6.8-7.3c-1-2.2-1.6-4.6-1.6-7c0-2,0.4-4,1.1-6
l0.4-1.1l17.2-43.6l-23,12.4c-6.4,3.4-14.3,1.2-18-5.1c-0.1-0.2-0.2-0.4-0.3-0.6c-1-2-1.5-4.1-1.5-6.2c0-4.4,2.2-8.8,6.2-11.3
c7.3-4.7,17.9-11.1,30.5-17.8c24.2-12.9,36.2-11.3,39.6-4.8c3.4,6.6-16.1,61.8-16.1,61.8s26.1-13.1,28.9-14.1
c6-2.3,12.7,0.5,15.4,6.3c0.6,1.3,0.9,2.7,1,4.1C364.6,191.2,364.6,191.5,364.6,191.8z"/>
<path id="XMLID_267_" fill="#7D9AF9" d="M309.1,158.8c-5.8,14.3-19.5,47.2-24.3,50.9l17.2-43.6l-23,12.4
c-6.4,3.5-14.5,1.2-18.1-5.2c0.2-0.2,0,0,0.2-0.2c2.3,1.1,6.4,2.1,12.5-0.9c11.4-5.4,24.4-12.5,31.9-16.6
C307.6,154.5,310,156.6,309.1,158.8z"/>
<path id="XMLID_264_" fill="#7D9AF9" d="M364.6,191.8c0,3.8-1.8,7.6-5.2,9.9c-7.4,5.2-19.2,12.9-32.2,19.7
c-8.3,4.4-15.5,7.8-21.3,10.3c-4.8,2.1-10.1,1.7-14.4-0.7c0.9-0.2,1.8-0.4,2.6-0.7c4.5-1.5,24.8-12.2,44.7-22.9
c13-7,21.8-12.6,25.7-16.4C364.6,191.2,364.6,191.5,364.6,191.8z"/>
</g>
<path id="XMLID_76_" opacity="0.49" fill="#FFFFFF" d="M314.2,131.6c-9,3-13.6,8.6-2.8,8s16.5-6.1,14.6-7.9
C324.1,130,318.3,130.2,314.2,131.6z"/>
<path id="XMLID_80_" opacity="0.49" fill="#FFFFFF" d="M348.7,182.6c-5.7,1.9-8.7,5.5-1.8,5.1c6.9-0.4,10.5-3.9,9.3-5
C354.9,181.6,351.3,181.7,348.7,182.6z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/images/canvas/noData.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
src/assets/images/canvas/noImage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
src/assets/images/chart/charts/bar_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/assets/images/chart/charts/bar_x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/assets/images/chart/charts/bar_y.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/images/chart/charts/capsule.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
src/assets/images/chart/charts/dial.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/assets/images/chart/charts/funnel.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/images/chart/charts/graph.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

BIN
src/assets/images/chart/charts/ground_glass.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
src/assets/images/chart/charts/grouped_stacked_rose_chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/images/chart/charts/heatmap.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/assets/images/chart/charts/line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
src/assets/images/chart/charts/line_gradient.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src/assets/images/chart/charts/line_gradient_single.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
src/assets/images/chart/charts/line_linear_single.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
src/assets/images/chart/charts/map.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
src/assets/images/chart/charts/map_amap.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
src/assets/images/chart/charts/map_cesium.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
src/assets/images/chart/charts/pie-circle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
src/assets/images/chart/charts/pie.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
src/assets/images/chart/charts/polar_coordinate_axis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src/assets/images/chart/charts/process.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/images/chart/charts/radar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src/assets/images/chart/charts/sankey.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
src/assets/images/chart/charts/scatter-logarithmic-regression.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
src/assets/images/chart/charts/scatter-multi.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
src/assets/images/chart/charts/scatter.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/images/chart/charts/tree_map.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
src/assets/images/chart/charts/visactor_bar_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src/assets/images/chart/charts/visactor_biax_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
src/assets/images/chart/charts/visactor_instrument.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/images/chart/charts/visactor_line.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/assets/images/chart/charts/water_WaterPolo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/assets/images/chart/charts/weather.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
src/assets/images/chart/decorates/Pipeline_H.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

BIN
src/assets/images/chart/decorates/Pipeline_V.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

BIN
src/assets/images/chart/decorates/border.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
src/assets/images/chart/decorates/border01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/assets/images/chart/decorates/border02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
src/assets/images/chart/decorates/border03.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/images/chart/decorates/border04.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/images/chart/decorates/border05.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
src/assets/images/chart/decorates/border06.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/images/chart/decorates/border07.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/assets/images/chart/decorates/border08.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/images/chart/decorates/border09.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/images/chart/decorates/border10.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save