Pre Merge pull request !170 from tanhao/dev

This commit is contained in:
tanhao 2023-08-15 01:29:15 +00:00 committed by Gitee
commit b365db0f3a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
19 changed files with 411 additions and 112 deletions

185
README.md
View File

@ -1,30 +1,89 @@
## 总览
#### 总览
![logo](readme/logo-t-y.png)
<p align="center">
<img src="readme/logo-t-y.png" alt="go-view" />
</p>
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
<h4 align="center">开源、精美、便捷的「数据可视化」低代码开发平台</h4>
### 😶 纯 **前端** 分支: **`master`**
#### 长期赞助商
### 👻 携带 **后端** 请求分支: **`master-fetch`**
<div>
<div align="center" style="column-gap: 20px;">
<a
href="http://www.ccflow.org/?from=goviewGitee"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/ccflow-banner.png" alt="go-view" style="width: 250px;" width="250px" />
</a>
<span> &nbsp;</span>
<a
href="https://fastbee.cn/"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/fb-banner.gif" alt="go-view" style="width: 250px;" width="250px"/>
</a>
<br/>
<br/>
<a
href="https://www.qeasy.cloud/"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/qyy-banner.png" alt="go-view" style="width: 250px;" width="250px"/>
</a>
<span> &nbsp;</span>
<a
href="http://doc.zyplayer.com/#/integrate/zyplayer-doc?utm=goview"
target="_blank"
style="
padding: 10px 20px;
display: inline-block;
border-radius: 10px;
background: #f9f9f9;
">
<img src="readme/sponsors/zyplayer-banner.png" alt="go-view" style="width: 250px;" width="250px"/>
</a>
</div>
</div>
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
#### 😶 **纯前端** 分支: **`master`**
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
#### 👻 携带 **后端** 请求分支: **`master-fetch`**
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
#### 📚 GoView **文档** 地址:[https://www.mtruning.club/](https://www.mtruning.club/)
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
项目纯前端-Demo 地址:[https://vue.mtruning.club/](https://vue.mtruning.club/)
文档-源码地址:[https://gitee.com/MTrun/go-view-doc](https://gitee.com/MTrun/go-view-doc)
项目带后端-Demo 地址:[https://demo.mtruning.club/](https://demo.mtruning.club/)
### 🤯 后端项目
Cloud IDE 代码在线预览地址:[https://idegitee.com/dromara/go-view](https://idegitee.com/dromara/go-view)
后端项目 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)
后端地址(社区实现,仅供参考):
技术点:
- `JAVA` [https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve) (当前使用)
- `.NET` [https://gitee.com/sun_xiang_yu/go-view-dotnet](https://gitee.com/sun_xiang_yu/go-view-dotnet)
- `NODE` [https://gitee.com/qwdingyu/led](https://gitee.com/qwdingyu/led)
- `Docker 镜像` [https://gitee.com/AHEAD4/go-view-docker](https://gitee.com/AHEAD4/go-view-docker)
- `接口文档`[https://docs.apipost.cn](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3) (不是最新, 以前端代码为准)
#### 整体介绍
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
@ -36,17 +95,34 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
- 入选 NaiveUI 社区精选资源推荐:[查看 NaiveUI 推荐列表](https://www.naiveui.com/zh-CN/light/docs/community)
说明文档:
![说明文档](readme/go-view-doc.png)
工作台:
![项目截图](readme/go-view-canvas.png)
![工作台](readme/go-view-canvas.png)
请求配置:
![项目截图](readme/go-view-fetch.png)
![请求配置](readme/go-view-fetch.png)
数据过滤:
![项目截图](readme/go-view-filter.png)
![数据过滤](readme/go-view-filter.png)
高级事件编辑:
![高级事件编辑](readme/go-view-event.png)
自定义组件颜色:
![高级事件编辑](readme/go-view-echarts-color.png)
快捷主页:
![快捷主页](readme/go-view-indexpage.png)
主题色:
![项目截图](readme/go-view-color.png)
![主题色](readme/go-view-color.png)
亮白主题:
![亮白主题](readme/go-view-theme.png)
主要技术栈为:
@ -66,14 +142,17 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
已完成图表:
| 分类 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------------- | -------- |
| 图表 | 柱状图 | 横向柱状图 | 折线图 |
| \* | 单/多 折线面积图 | 饼图 | 水球图 |
| \* | 环形图 | NaiveUI 多种进度 | 🤠 |
| 信息 | 文字 | 图片 | 😶 |
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 |
| 分类 | 名称 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------- | -------------- | ------------------------ |
| 图表 | 柱状图 | 横向柱状图 | 折线图 | 单/多 折线面积图(渐变色) |
| \* | 饼图 | 环形图 | 水球图 | 雷达图 |
| \* | NaiveUI 多种进度 | 散点图 | 对数回归散点图 | 热力图 |
| \* | 漏斗图 | 中国地图 | 高德地图 | 🦊 |
| 信息 | 文字 | 渐变文字 | 词云 | 嵌套网页 |
| \* | 图片 | 视频 | 😺 | 🐯 |
| 列表 | 滚动排名列表 | 滚动表格 | 🐮 | 🐐 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 | 通用时间 |
| \* | 数字计数 | 倒计时 | 时钟 | 🦁 |
## 浏览器支持
@ -81,52 +160,7 @@ GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图
## 安装
本项目采用` pnpm` 进行包管理
```shell
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
#pnpm
pnpm install
#yarn
yarn install
#npm
npm install
```
## 启动
```shell
#pnpm
pnpm dev
# npm
npm run dev
#yarn
yarn dev
#Makefile
make dev
```
## 编译
```shell
#pnpm
pnpm run build
# npm
npm run build
#yarn
yarn run build
#Makefile
make dist
```
请查看文档:[https://www.mtruning.club/](https://www.mtruning.club/)
## 代码提交
@ -142,10 +176,9 @@ make dist
- style: 不影响程序逻辑的代码修改
- chore: 不属于以上类型的其他类型(日常事务)
## 交流
## 交流
QQ 群1030129384
![QQ群](readme/go-view-qq.png)
QQ 群663629294
<img width="260px" src="readme/go-view-qq.png" alt="QQ群" style="border-radius: 20px" />
![渲染海报](readme/logo-poster.png)

View File

@ -1,8 +1,8 @@
{
"name": "go-view",
"version": "1.1.11",
"version": "1.2.6",
"engines": {
"node": ">=16.14 <18.0.0"
"node": ">=12.0"
},
"scripts": {
"dev": "vite --host",

10
preview.yml Normal file
View File

@ -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
readme/go-view-doc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

BIN
readme/go-view-event.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 70 KiB

BIN
readme/go-view-theme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -11,7 +11,10 @@ export const option = {
dataset: dataJson,
mapRegion: {
adcode: 'china',
showHainanIsLands: true
enter: false,
showHainanIsLands: false,
backSize: 50,
backColor: '#ffffff'
},
tooltip: {
show: true,
@ -148,6 +151,26 @@ export const option = {
shadowOffsetY: 2,
shadowBlur: 10
}
},
{
type: 'lines',
zlevel: 2,
effect: {
show: true,
period: 4, //箭头指向速度,值越小速度越快
trailLength: 0.4, //特效尾迹长度[0,1]值越大,尾迹越长重
symbol: 'arrow', //箭头图标
symbolSize: 7, //图标大小
},
lineStyle: {
normal: {
color:'#4fb6d2',
width: 1, //线条宽度
opacity: 0.1, //尾迹线条透明度
curveness: .3 //尾迹线条曲直度
}
},
data: []
}
]
}

View File

@ -1,7 +1,7 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem name="地图" :expanded="true">
<CollapseItem name="地图" :expanded="false">
<SettingItemBox name="地图区域">
<SettingItem name="默认中国">
<n-select
@ -180,9 +180,25 @@
<SettingItem>
<n-checkbox v-model:checked="mapRegion.showHainanIsLands" size="small">显示南海群岛</n-checkbox>
</SettingItem>
<SettingItem>
<n-checkbox v-model:checked="mapRegion.enter" size="small">点击进入下级</n-checkbox>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="返回图标" v-if="mapRegion.enter">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="mapRegion.backColor"></n-color-picker>
</SettingItem>
<SettingItem name="大小">
<n-input-number
v-model:value="mapRegion.backSize"
:min="1"
size="small"
placeholder="请输入字体大小"
></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="标记" :expanded="true">
<CollapseItem name="标记" :expanded="false">
<SettingItemBox name="样式">
<SettingItem name="大小">
<n-input-number v-model:value="seriesList[0].symbolSize" size="small" :min="0"></n-input-number>
@ -223,6 +239,38 @@
</SettingItem>
</SettingItemBox>
</CollapseItem>
<CollapseItem name="线条" :expanded="true">
<SettingItemBox name="箭头">
<SettingItem name="速度">
<n-tooltip trigger="hover">
<template #trigger>
<n-input-number v-model:value="seriesList[2].effect.period" size="small" :min="0"></n-input-number>
</template>
值越小速度越快
</n-tooltip>
</SettingItem>
<SettingItem name="尾迹">
<n-tooltip trigger="hover">
<template #trigger>
<n-input-number v-model:value="seriesList[2].effect.trailLength" size="small" :min="0" :max="1"></n-input-number>
</template>
特效尾迹长度[0,1]值越大尾迹越长重
</n-tooltip>
</SettingItem>
<SettingItem name="大小">
<n-input-number v-model:value="seriesList[2].effect.symbolSize" size="small" :min="0"></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="配置">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[2].lineStyle.normal.color"></n-color-picker>
</SettingItem>
<SettingItem name="宽度">
<n-input-number v-model:value="seriesList[2].lineStyle.normal.width" size="small" :min="1"></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">

View File

@ -2,23 +2,93 @@
"point": [
{
"name": "北京",
"value": [116.405285, 39.904989, 200]
"value": [
116.405285,
39.904989,
200
]
},
{
"name": "郑州",
"value": [113.665412, 34.757975, 888]
"value": [
113.665412,
34.757975,
888
]
},
{
"name": "青海",
"value": [101.778916, 36.623178, 666]
"value": [
101.778916,
36.623178,
666
]
},
{
"name": "宁夏回族自治区",
"value": [106.278179, 38.46637, 66]
"value": [
106.278179,
38.46637,
66
]
},
{
"name": "哈尔滨市",
"value": [126.642464, 45.756967, 101]
"value": [
126.642464,
45.756967,
101
]
}
],
"line": [
{
"coords": [
[
113.665412,
34.757975
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
101.778916,
36.623178
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
106.278179,
38.46637
],
[
116.405285,
39.904989
]
]
},
{
"coords": [
[
126.642464,
45.756967
],
[
116.405285,
39.904989
]
]
}
],
"map": [
@ -30,7 +100,6 @@
"name": "河北省",
"value": 98
},
{
"name": "江苏省",
"value": 300
@ -69,11 +138,33 @@
}
],
"pieces": [
{ "gte": 1000, "label": ">1000" },
{ "gte": 600, "lte": 999, "label": "600-999" },
{ "gte": 200, "lte": 599, "label": "200-599" },
{ "gte": 50, "lte": 199, "label": "49-199" },
{ "gte": 10, "lte": 49, "label": "10-49" },
{ "lte": 9, "label": "<9" }
{
"gte": 1000,
"label": ">1000"
},
{
"gte": 600,
"lte": 999,
"label": "600-999"
},
{
"gte": 200,
"lte": 599,
"label": "200-599"
},
{
"gte": 50,
"lte": 199,
"label": "49-199"
},
{
"gte": 10,
"lte": 49,
"label": "10-49"
},
{
"lte": 9,
"label": "<9"
}
]
}
}

View File

@ -1,12 +1,23 @@
<template>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize>
<div>
<n-icon
v-if="(enter && levelHistory.length !== 0) || (enter && !isPreview())"
:color="backColor"
@click="backLevel"
:size="backSize" class="back-icon">
<ArrowBackIcon />
</n-icon>
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option.value" :manual-update="isPreview()" autoresize @click="chartPEvents">
</v-chart>
</div>
</template>
<script setup lang="ts">
import { PropType, reactive, watch, ref, nextTick } from 'vue'
import { PropType, reactive, watch, ref, nextTick, toRefs } from 'vue'
import config, { includes } from './config'
import VChart from 'vue-echarts'
import { icon } from '@/plugins'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use, registerMap } from 'echarts/core'
import { EffectScatterChart, MapChart } from 'echarts/charts'
@ -16,8 +27,12 @@ import { mergeTheme, setOption } from '@/packages/public/chart'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import mapJsonWithoutHainanIsLands from './mapWithoutHainanIsLands.json'
import mapChinaJson from './mapGeojson/china.json'
import { DatasetComponent, GridComponent, TooltipComponent, GeoComponent, VisualMapComponent } from 'echarts/components'
const { ArrowBackIcon } = icon.ionicons5
let levelHistory: any = ref([])
const props = defineProps({
themeSetting: {
type: Object,
@ -33,6 +48,8 @@ const props = defineProps({
}
})
const { backColor, backSize, enter } = toRefs(props.chartConfig.option.mapRegion)
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([
@ -87,6 +104,16 @@ const vEchartsSetOption = () => {
const dataSetHandle = async (dataset: any) => {
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'effectScatter' && dataset.point) item.data = dataset.point
else if (item.type === 'lines' && dataset.line) {
item.data = dataset.line.map((it: any) => {
return {
...it,
lineStyle: {
color: props.chartConfig.option.series[2].lineStyle.normal.color
}
}
})
}
else if (item.type === 'map' && dataset.map) item.data = dataset.map
})
if (dataset.pieces) props.chartConfig.option.visualMap.pieces = dataset.pieces
@ -101,6 +128,44 @@ const hainanLandsHandle = async (newData: boolean) => {
registerMap('china', { geoJSON: mapJsonWithoutHainanIsLands as any, specialAreas: {} })
}
}
//
const chartPEvents = (e: any) => {
if (!props.chartConfig.option.mapRegion.enter) {
return
}
mapChinaJson.features.forEach((item) => {
var pattern = new RegExp(e.name);
if (pattern.test(item.properties.name)) {
let code = String(item.properties.adcode)
levelHistory.value.push(code)
checkOrMap(code)
}
})
}
//
const backLevel = () => {
levelHistory.value = []
if (levelHistory.value.length > 1) {
levelHistory.value.pop()
const code = levelHistory[levelHistory.value.length -1]
checkOrMap(code)
} else {
checkOrMap('china')
}
}
//
const checkOrMap = async (newData: string) => {
await getGeojson(newData)
props.chartConfig.option.geo.map = newData
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'map') item.map = newData
})
vEchartsSetOption()
}
// dataset
watch(
() => props.chartConfig.option.dataset,
@ -113,6 +178,17 @@ watch(
}
)
// 线
watch(
() => props.chartConfig.option.series[2].lineStyle.normal.color,
() => {
dataSetHandle(props.chartConfig.option.dataset)
},
{
deep: false
}
)
//
watch(
() => props.chartConfig.option.mapRegion.showHainanIsLands,
@ -132,14 +208,9 @@ watch(
//
watch(
() => `${props.chartConfig.option.mapRegion.adcode}`,
async newData => {
newData => {
try {
await getGeojson(newData)
props.chartConfig.option.geo.map = newData
props.chartConfig.option.series.forEach((item: any) => {
if (item.type === 'map') item.map = newData
})
vEchartsSetOption()
checkOrMap(newData)
} catch (error) {
console.log(error)
}
@ -154,3 +225,13 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
dataSetHandle(newData)
})
</script>
<style scope lang="scss">
.back-icon {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
z-index: 50;
}
</style>

View File

@ -18,18 +18,14 @@
>
<div class="list-header">
<mac-os-control-btn class="list-header-control-btn" :mini="true" :disabled="true"></mac-os-control-btn>
<n-text class="list-header-text" depth="3">
<n-ellipsis>{{ item.title }}</n-ellipsis>
</n-text>
<span class="list-header-text">{{ item.title }}</span>
</div>
<div class="list-center go-flex-center go-transition" draggable="true">
<Icon v-if="item.icon" class="list-img" :icon="item.icon" color="#999" width="48" />
<chart-glob-image v-else class="list-img" :chartConfig="item" />
</div>
<div class="list-bottom">
<n-text class="list-bottom-text" depth="3">
<n-ellipsis style="max-width: 90%">{{ item.title }}</n-ellipsis>
</n-text>
<span class="list-bottom-text">{{ item.title }}</span>
</div>
<!-- 遮罩 -->
<div v-if="item.disabled" class="list-model"></div>
@ -206,12 +202,21 @@ $halfCenterHeight: 50px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 2px 15px;
padding: 2px 6px 2px 15px;
@include fetch-bg-color('background-color3');
&-text {
font-size: 12px;
margin-left: 8px;
user-select: none;
white-space: nowrap;
flex: 1;
width: 0;
text-align: right;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
transition: color .3s var(--n-bezier);
color: #99999a;
}
}
.list-center {
@ -231,6 +236,13 @@ $halfCenterHeight: 50px;
.list-bottom-text {
font-size: 12px;
padding-left: 5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
transition: color .3s var(--n-bezier);
color: #99999a;
max-width: 90%;
}
}
.list-model {
@ -294,7 +306,8 @@ $halfCenterHeight: 50px;
}
}
.list-bottom {
display: block;
display: flex;
align-items: center;
}
}
/* 缩小展示 */

View File

@ -58,7 +58,7 @@ const previewHandle = () => {
//
const sendHandle = () => {
goDialog({
message: '想体验发布功能,请前往 master-fetch 分支查看: https://gitee.com/MTrun/go-view/tree/master-fetch',
message: '想体验发布功能,请前往查看: https://demo.mtruning.club/#/login。源码需切换到master-fetch 分支。',
positiveText: '了然',
closeNegativeText: true,
onPositiveCallback: () => {}