mirror of
https://gitee.com/dromara/go-view.git
synced 2025-02-24 00:02:51 +08:00
Merge branch 'dev'
This commit is contained in:
commit
a2f32b0289
@ -75,7 +75,7 @@
|
|||||||
"sass": "^1.49.11",
|
"sass": "^1.49.11",
|
||||||
"sass-loader": "^12.6.0",
|
"sass-loader": "^12.6.0",
|
||||||
"typescript": "4.6.3",
|
"typescript": "4.6.3",
|
||||||
"vite": "2.9.9",
|
"vite": "4.2.1",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-importer": "^0.2.5",
|
"vite-plugin-importer": "^0.2.5",
|
||||||
"vite-plugin-mock": "^2.9.6",
|
"vite-plugin-mock": "^2.9.6",
|
||||||
|
2831
pnpm-lock.yaml
2831
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
100
src/api/mock/graph.json
Normal file
100
src/api/mock/graph.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -19,6 +19,8 @@ export const capsuleUrl = '/mock/capsule'
|
|||||||
export const wordCloudUrl = '/mock/wordCloud'
|
export const wordCloudUrl = '/mock/wordCloud'
|
||||||
export const treemapUrl = '/mock/treemap'
|
export const treemapUrl = '/mock/treemap'
|
||||||
export const threeEarth01Url = '/mock/threeEarth01Data'
|
export const threeEarth01Url = '/mock/threeEarth01Data'
|
||||||
|
export const sankeyUrl = '/mock/sankey'
|
||||||
|
export const graphUrl = '/mock/graphData'
|
||||||
|
|
||||||
const mockObject: MockMethod[] = [
|
const mockObject: MockMethod[] = [
|
||||||
{
|
{
|
||||||
@ -103,6 +105,16 @@ const mockObject: MockMethod[] = [
|
|||||||
method: RequestHttpEnum.GET,
|
method: RequestHttpEnum.GET,
|
||||||
response: () => test.threeEarth01Data
|
response: () => test.threeEarth01Data
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
url: sankeyUrl,
|
||||||
|
method: RequestHttpEnum.GET,
|
||||||
|
response: () => test.fetchSankey
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: graphUrl,
|
||||||
|
method: RequestHttpEnum.GET,
|
||||||
|
response: () => test.graphData
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export default mockObject
|
export default mockObject
|
||||||
|
86
src/api/mock/sankey.json
Normal file
86
src/api/mock/sankey.json
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -2,6 +2,8 @@ import heatmapJson from './heatMapData.json'
|
|||||||
import scatterJson from './scatter.json'
|
import scatterJson from './scatter.json'
|
||||||
import mapJson from './map.json'
|
import mapJson from './map.json'
|
||||||
import tTreemapJson from './treemap.json'
|
import tTreemapJson from './treemap.json'
|
||||||
|
import sankeyJson from './sankey.json'
|
||||||
|
import graphDataJson from './graph.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// 单图表
|
// 单图表
|
||||||
@ -219,5 +221,19 @@ export default {
|
|||||||
'endArray|10': [{ 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
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
BIN
src/assets/images/chart/charts/dial.png
Normal file
BIN
src/assets/images/chart/charts/dial.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
BIN
src/assets/images/chart/charts/graph.png
Normal file
BIN
src/assets/images/chart/charts/graph.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 377 KiB |
BIN
src/assets/images/chart/charts/sankey.png
Normal file
BIN
src/assets/images/chart/charts/sankey.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -12,6 +12,7 @@ export enum DragKeyEnum {
|
|||||||
// 不同页面保存操作
|
// 不同页面保存操作
|
||||||
export enum SavePageEnum {
|
export enum SavePageEnum {
|
||||||
CHART = 'SaveChart',
|
CHART = 'SaveChart',
|
||||||
|
CHART_TO_PREVIEW = 'ChartToPreview',
|
||||||
JSON = 'SaveJSON',
|
JSON = 'SaveJSON',
|
||||||
CLOSE = 'close'
|
CLOSE = 'close'
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-view>
|
<router-view>
|
||||||
<template #default="{ Component, route }">
|
<template #default="{ Component, route }">
|
||||||
<component
|
<component v-if="route.meta.noKeepAlive" :is="Component"></component>
|
||||||
v-if="route.noKeepAlive"
|
|
||||||
:is="Component"
|
|
||||||
:key="route.fullPath"
|
|
||||||
></component>
|
|
||||||
<keep-alive v-else>
|
<keep-alive v-else>
|
||||||
<component :is="Component" :key="route.fullPath"></component>
|
<component :is="Component"></component>
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</template>
|
</template>
|
||||||
</router-view>
|
</router-view>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<router-view #default="{ Component, route }">
|
<router-view #default="{ Component, route }">
|
||||||
<transition name="fade" mode="out-in" appear>
|
<transition name="fade" mode="out-in" appear>
|
||||||
<component
|
<component
|
||||||
v-if="route.noKeepAlive"
|
v-if="route.meta.noKeepAlive"
|
||||||
:is="Component"
|
:is="Component"
|
||||||
:key="route.fullPath"
|
:key="route.fullPath"
|
||||||
></component>
|
></component>
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-chart
|
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()"
|
||||||
ref="vChartRef"
|
|
||||||
:init-options="initOptions"
|
|
||||||
:theme="themeColor"
|
|
||||||
:option="option"
|
|
||||||
:manual-update="isPreview()"
|
|
||||||
:update-options="{
|
:update-options="{
|
||||||
replaceMerge: replaceMergeArr
|
replaceMerge: replaceMergeArr
|
||||||
}"
|
}" autoresize></v-chart>
|
||||||
autoresize
|
|
||||||
></v-chart>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -27,6 +20,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
|
|||||||
import { isPreview } from '@/utils'
|
import { isPreview } from '@/utils'
|
||||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||||
import isObject from 'lodash/isObject'
|
import isObject from 'lodash/isObject'
|
||||||
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
themeSetting: {
|
themeSetting: {
|
||||||
@ -61,11 +55,20 @@ watch(
|
|||||||
if (!isObject(newData) || !('dimensions' in newData)) return
|
if (!isObject(newData) || !('dimensions' in newData)) return
|
||||||
if (Array.isArray(newData?.dimensions)) {
|
if (Array.isArray(newData?.dimensions)) {
|
||||||
const seriesArr = []
|
const seriesArr = []
|
||||||
for (let i = 0; i < newData.dimensions.length - 1; i++) {
|
// 对oldData进行判断,防止传入错误数据之后对旧维度判断产生干扰
|
||||||
seriesArr.push(seriesItem)
|
// 此处计算的是dimensions的Y轴维度,若是dimensions.length为0或1,则默认为1,排除X轴维度干扰
|
||||||
|
const oldDimensions = Array.isArray(oldData?.dimensions)&&oldData.dimensions.length >= 1 ? oldData.dimensions.length : 1;
|
||||||
|
const newDimensions = newData.dimensions.length >= 1 ? newData.dimensions.length : 1;
|
||||||
|
const dimensionsGap = newDimensions - oldDimensions;
|
||||||
|
if (dimensionsGap < 0) {
|
||||||
|
props.chartConfig.option.series.splice(newDimensions - 1)
|
||||||
|
} else if (dimensionsGap > 0) {
|
||||||
|
for (let i = 0; i < dimensionsGap; i++) {
|
||||||
|
seriesArr.push(cloneDeep(seriesItem))
|
||||||
|
}
|
||||||
|
props.chartConfig.option.series.push(...seriesArr)
|
||||||
}
|
}
|
||||||
replaceMergeArr.value = ['series']
|
replaceMergeArr.value = ['series']
|
||||||
props.chartConfig.option.series = seriesArr
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
replaceMergeArr.value = []
|
replaceMergeArr.value = []
|
||||||
})
|
})
|
||||||
|
@ -26,6 +26,7 @@ import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore
|
|||||||
import { isPreview } from '@/utils'
|
import { isPreview } from '@/utils'
|
||||||
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||||
import isObject from 'lodash/isObject'
|
import isObject from 'lodash/isObject'
|
||||||
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
themeSetting: {
|
themeSetting: {
|
||||||
@ -61,7 +62,7 @@ watch(
|
|||||||
if (Array.isArray(newData?.dimensions)) {
|
if (Array.isArray(newData?.dimensions)) {
|
||||||
const seriesArr = []
|
const seriesArr = []
|
||||||
for (let i = 0; i < newData.dimensions.length - 1; i++) {
|
for (let i = 0; i < newData.dimensions.length - 1; i++) {
|
||||||
seriesArr.push(seriesItem)
|
seriesArr.push(cloneDeep(seriesItem))
|
||||||
}
|
}
|
||||||
replaceMergeArr.value = ['series']
|
replaceMergeArr.value = ['series']
|
||||||
props.chartConfig.option.series = seriesArr
|
props.chartConfig.option.series = seriesArr
|
||||||
|
91
src/packages/components/Charts/Mores/Dial/config.ts
Normal file
91
src/packages/components/Charts/Mores/Dial/config.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
|
||||||
|
import { DialConfig } from './index'
|
||||||
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
|
||||||
|
export const includes = []
|
||||||
|
const option = {
|
||||||
|
backgroundColor: '#0E1327',
|
||||||
|
dataset:70,
|
||||||
|
series: [{
|
||||||
|
type: "gauge",
|
||||||
|
data: [{
|
||||||
|
value: 70,
|
||||||
|
itemStyle: { // 指针样式
|
||||||
|
color: '#2AF4FF'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
min: 0, //最小刻度
|
||||||
|
max: 100, //最大刻度
|
||||||
|
splitNumber: 10, //刻度数量
|
||||||
|
center: ['50%', '55%'],
|
||||||
|
radius: '80%',
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: [
|
||||||
|
[0, 'rgba(0,212,230,0.5)'],
|
||||||
|
[1, 'rgba(28,128,245,0)']
|
||||||
|
],
|
||||||
|
width: 170
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: { // 文字样式
|
||||||
|
color: '#eee',
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
length: '80%',
|
||||||
|
width: 4
|
||||||
|
},
|
||||||
|
animationDuration: 2000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '外部刻度',
|
||||||
|
type: 'gauge',
|
||||||
|
center: ['50%', '55%'],
|
||||||
|
radius: '90%',
|
||||||
|
axisLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
width: 25,
|
||||||
|
color: [ // 表盘外部颜色
|
||||||
|
[0, '#1369E380'],
|
||||||
|
[1, '#1369E380']
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show:false,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
splitNumber: 5,
|
||||||
|
lineStyle: { //刻度颜色
|
||||||
|
color: '#42E5FB',
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
length: 15,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#42E5FB',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||||
|
public key: string = DialConfig.key
|
||||||
|
public chartConfig = cloneDeep(DialConfig)
|
||||||
|
// 图表配置项
|
||||||
|
public option = echartOptionProfixHandle(option, includes)
|
||||||
|
}
|
84
src/packages/components/Charts/Mores/Dial/config.vue
Normal file
84
src/packages/components/Charts/Mores/Dial/config.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 遍历 seriesList -->
|
||||||
|
<CollapseItem :name="`圆环`" :expanded="true">
|
||||||
|
<SettingItemBox name="数据">
|
||||||
|
<SettingItem name="数值">
|
||||||
|
<n-input-number v-model:value="config.dataset" :min="dialConfig.min" :max="dialConfig.max" :step="1" size="small" placeholder="数值">
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
<!-- Echarts 全局设置 -->
|
||||||
|
<!-- 表盘刻度字体 -->
|
||||||
|
<SettingItemBox name="字体">
|
||||||
|
<SettingItem name="颜色">
|
||||||
|
<n-color-picker size="small" :modes="['hex']" v-model:value="dialConfig.axisLabel.color"></n-color-picker>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="字体大小">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="dialConfig.axisLabel.fontSize"
|
||||||
|
:min="0"
|
||||||
|
:step="1"
|
||||||
|
size="small"
|
||||||
|
placeholder="字体大小"
|
||||||
|
>
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
<!-- 表盘 -->
|
||||||
|
<SettingItemBox name="表盘外部">
|
||||||
|
<SettingItem name="颜色" >
|
||||||
|
<n-color-picker size="small" :modes="['hex']" v-model:value="config.series[1].axisLine.lineStyle.color[1][1]"></n-color-picker>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
<!-- 指针 -->
|
||||||
|
<SettingItemBox name="指针">
|
||||||
|
<SettingItem name="颜色" >
|
||||||
|
<n-color-picker size="small" :modes="['hex']" v-model:value="dialConfig.data[0].itemStyle.color"></n-color-picker>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="宽度">
|
||||||
|
<n-input-number v-model:value="dialConfig.pointer.width" :min="0" :step="1" size="small" placeholder="数值">
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
<SettingItemBox name="刻度">
|
||||||
|
<SettingItem name="最小值">
|
||||||
|
<n-input-number v-model:value="dialConfig.min" :min="0" :step="1" size="small" placeholder="数值">
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="最大值">
|
||||||
|
<n-input-number v-model:value="dialConfig.max" :min="0" :step="1" size="small" placeholder="数值">
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="颜色" >
|
||||||
|
<n-color-picker size="small" :modes="['hex']" v-model:value="config.series[1].axisTick.lineStyle.color" @update:value="updateClick"></n-color-picker>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
|
||||||
|
</CollapseItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, computed } from 'vue'
|
||||||
|
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||||
|
import { GlobalThemeJsonType } from '@/settings/chartThemes'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
optionData: {
|
||||||
|
type: Object as PropType<GlobalThemeJsonType>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const config = computed(() => {
|
||||||
|
return props.optionData
|
||||||
|
})
|
||||||
|
|
||||||
|
const dialConfig = computed(() => {
|
||||||
|
return props.optionData.series[0]
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateClick = (val: any) => {
|
||||||
|
props.optionData.series[1].splitLine.lineStyle.color=val
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
14
src/packages/components/Charts/Mores/Dial/index.ts
Normal file
14
src/packages/components/Charts/Mores/Dial/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||||
|
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||||
|
|
||||||
|
export const DialConfig: ConfigType = {
|
||||||
|
key: 'Dial',
|
||||||
|
chartKey: 'VDial',
|
||||||
|
conKey: 'VCDial',
|
||||||
|
title: '表盘',
|
||||||
|
category: ChatCategoryEnum.MORE,
|
||||||
|
categoryName: ChatCategoryEnumName.MORE,
|
||||||
|
package: PackagesCategoryEnum.CHARTS,
|
||||||
|
chartFrame: ChartFrameEnum.COMMON,
|
||||||
|
image:'dial.png'
|
||||||
|
}
|
69
src/packages/components/Charts/Mores/Dial/index.vue
Normal file
69
src/packages/components/Charts/Mores/Dial/index.vue
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart :theme="themeColor" :init-options="initOptions" :option="option.value" autoresize> </v-chart>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, reactive, watch } from 'vue'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||||
|
import { use } from 'echarts/core'
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
|
import { PieChart } from 'echarts/charts'
|
||||||
|
import { mergeTheme } from '@/packages/public/chart'
|
||||||
|
import config, { includes } from './config'
|
||||||
|
import { useChartDataFetch } from '@/hooks'
|
||||||
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
themeSetting: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
themeColor: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chartConfig: {
|
||||||
|
type: Object as PropType<config>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
||||||
|
|
||||||
|
use([DatasetComponent, CanvasRenderer, PieChart, GridComponent, TooltipComponent, LegendComponent, TitleComponent])
|
||||||
|
|
||||||
|
const option = reactive({
|
||||||
|
value: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataHandle = (newData: any) => {
|
||||||
|
let config = props.chartConfig.option
|
||||||
|
config.series[0].data[0].value = newData
|
||||||
|
option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||||
|
option.value = props.chartConfig.option
|
||||||
|
}
|
||||||
|
|
||||||
|
// 配置时
|
||||||
|
watch(
|
||||||
|
() => props.chartConfig.option.dataset,
|
||||||
|
newData => {
|
||||||
|
try {
|
||||||
|
dataHandle(newData)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
deep: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 预览时
|
||||||
|
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
|
||||||
|
// @ts-ignore
|
||||||
|
option.value.series[0].data[0].value = resData
|
||||||
|
})
|
||||||
|
</script>
|
71
src/packages/components/Charts/Mores/Graph/config.ts
Normal file
71
src/packages/components/Charts/Mores/Graph/config.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
|
||||||
|
import { GraphConfig } from './index'
|
||||||
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
import dataJson from './data.json'
|
||||||
|
|
||||||
|
export const includes = []
|
||||||
|
|
||||||
|
// 关系图布局
|
||||||
|
export const GraphLayout = [
|
||||||
|
{ label: '无', value: 'none' },
|
||||||
|
{ label: '环形', value: 'circular' }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 标签开关
|
||||||
|
export const LabelSwitch = [
|
||||||
|
{ label: '开启', value: 1 },
|
||||||
|
{ label: '关闭', value: 0 }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 标签位置
|
||||||
|
export const LabelPosition = [
|
||||||
|
{ label: '左侧', value: 'left' },
|
||||||
|
{ label: '右侧', value: 'right' },
|
||||||
|
{ label: '顶部', value: 'top' },
|
||||||
|
{ label: '底部', value: 'bottom' },
|
||||||
|
{ label: '内部', value: 'inside' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export const option = {
|
||||||
|
dataset: { ...dataJson },
|
||||||
|
tooltip: {},
|
||||||
|
legend:{
|
||||||
|
show:true,
|
||||||
|
textStyle:{
|
||||||
|
color:"#eee",
|
||||||
|
fontSize: 14 ,
|
||||||
|
},
|
||||||
|
data: dataJson.categories.map(function (a) {
|
||||||
|
return a.name;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'graph',
|
||||||
|
layout: 'none', // none circular环形布局
|
||||||
|
data: dataJson.nodes,
|
||||||
|
links: dataJson.links,
|
||||||
|
categories: dataJson.categories,
|
||||||
|
label: { // 标签
|
||||||
|
show: 1,
|
||||||
|
position: 'right',
|
||||||
|
formatter: '{b}'
|
||||||
|
},
|
||||||
|
labelLayout: {
|
||||||
|
hideOverlap: true
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: 'source', // 线条颜色
|
||||||
|
curveness: 0.2 // 线条卷曲程度
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||||
|
public key = GraphConfig.key
|
||||||
|
public chartConfig = cloneDeep(GraphConfig)
|
||||||
|
// 图表配置项
|
||||||
|
public option = echartOptionProfixHandle(option, includes)
|
||||||
|
}
|
62
src/packages/components/Charts/Mores/Graph/config.vue
Normal file
62
src/packages/components/Charts/Mores/Graph/config.vue
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<CollapseItem name="关系图" :expanded="true">
|
||||||
|
<SettingItemBox name="样式">
|
||||||
|
<setting-item name="布局">
|
||||||
|
<n-select v-model:value="graphConfig.layout" :options="GraphLayout" size="small" />
|
||||||
|
</setting-item>
|
||||||
|
</SettingItemBox>
|
||||||
|
<SettingItemBox name="标签">
|
||||||
|
<setting-item name="展示">
|
||||||
|
<n-select v-model:value="graphConfig.label.show" :options="LabelSwitch" size="small" />
|
||||||
|
</setting-item>
|
||||||
|
<setting-item name="位置">
|
||||||
|
<n-select v-model:value="graphConfig.label.position" :options="LabelPosition" size="small" />
|
||||||
|
</setting-item>
|
||||||
|
</SettingItemBox>
|
||||||
|
<SettingItemBox name="线条">
|
||||||
|
<SettingItem name="弧线">
|
||||||
|
<!-- 需要输入两位的小数才会变化 -->
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="optionData.series[0].lineStyle.curveness"
|
||||||
|
:min="0"
|
||||||
|
:step="0.01"
|
||||||
|
placeholder="弯曲程度"
|
||||||
|
size="small"
|
||||||
|
></n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
<SettingItemBox name="图例">
|
||||||
|
<SettingItem name="颜色">
|
||||||
|
<n-color-picker
|
||||||
|
size="small"
|
||||||
|
:modes="['hex']"
|
||||||
|
v-model:value="optionData.legend.textStyle.color"
|
||||||
|
></n-color-picker>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="文本">
|
||||||
|
<n-input-number v-model:value="optionData.legend.textStyle.fontSize" :min="0" :step="1" size="small" placeholder="文字大小">
|
||||||
|
</n-input-number>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
</CollapseItem>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, computed } from 'vue'
|
||||||
|
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||||
|
import { option, GraphLayout, LabelSwitch, LabelPosition } from './config'
|
||||||
|
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
optionData: {
|
||||||
|
type: Object as PropType<typeof option & GlobalThemeJsonType>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const graphConfig = computed<typeof option.series[0]>(() => {
|
||||||
|
return props.optionData.series[0]
|
||||||
|
})
|
||||||
|
</script>
|
1744
src/packages/components/Charts/Mores/Graph/data.json
Normal file
1744
src/packages/components/Charts/Mores/Graph/data.json
Normal file
File diff suppressed because it is too large
Load Diff
14
src/packages/components/Charts/Mores/Graph/index.ts
Normal file
14
src/packages/components/Charts/Mores/Graph/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||||
|
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||||
|
|
||||||
|
export const GraphConfig: ConfigType = {
|
||||||
|
key: 'Graph',
|
||||||
|
chartKey: 'VGraph',
|
||||||
|
conKey: 'VCGraph',
|
||||||
|
title: '关系图',
|
||||||
|
category: ChatCategoryEnum.MORE,
|
||||||
|
categoryName: ChatCategoryEnumName.MORE,
|
||||||
|
package: PackagesCategoryEnum.CHARTS,
|
||||||
|
chartFrame: ChartFrameEnum.COMMON,
|
||||||
|
image: 'graph.png'
|
||||||
|
}
|
80
src/packages/components/Charts/Mores/Graph/index.vue
Normal file
80
src/packages/components/Charts/Mores/Graph/index.vue
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()" autoresize></v-chart>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, PropType, watch } from 'vue'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||||
|
import dataJson from './data.json'
|
||||||
|
import { use } from 'echarts/core'
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
|
import { RadarChart } from 'echarts/charts'
|
||||||
|
import { includes } from './config'
|
||||||
|
import { mergeTheme, setOption } from '@/packages/public/chart'
|
||||||
|
import { useChartDataFetch } from '@/hooks'
|
||||||
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
|
import { isPreview } from '@/utils'
|
||||||
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
themeSetting: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
themeColor: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chartConfig: {
|
||||||
|
type: Object as PropType<CreateComponentType>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
||||||
|
|
||||||
|
use([DatasetComponent, CanvasRenderer, RadarChart, GridComponent, TooltipComponent, LegendComponent])
|
||||||
|
|
||||||
|
const vChartRef = ref<typeof VChart>()
|
||||||
|
|
||||||
|
const option = computed(() => {
|
||||||
|
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataSetHandle = (dataset: typeof dataJson) => {
|
||||||
|
if (dataset.nodes) {
|
||||||
|
props.chartConfig.option.series[0].data = dataset.nodes
|
||||||
|
}
|
||||||
|
if (dataset.links) {
|
||||||
|
props.chartConfig.option.series[0].links = dataset.links
|
||||||
|
}
|
||||||
|
if (dataset.categories) {
|
||||||
|
props.chartConfig.option.series[0].categories = dataset.categories
|
||||||
|
// @ts-ignore
|
||||||
|
props.chartConfig.option.legend.data = dataset.categories.map((i: { name: string }) => i.name)
|
||||||
|
}
|
||||||
|
if (vChartRef.value && isPreview()) {
|
||||||
|
setOption(vChartRef.value, props.chartConfig.option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.chartConfig.option.dataset,
|
||||||
|
newData => {
|
||||||
|
try {
|
||||||
|
dataSetHandle(newData)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
|
||||||
|
dataSetHandle(newData)
|
||||||
|
})
|
||||||
|
</script>
|
43
src/packages/components/Charts/Mores/Sankey/config.ts
Normal file
43
src/packages/components/Charts/Mores/Sankey/config.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
|
||||||
|
import { SankeyConfig } from './index'
|
||||||
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
|
import dataJson from './data.json'
|
||||||
|
|
||||||
|
export const includes = ['legend']
|
||||||
|
|
||||||
|
// 图表方向
|
||||||
|
export const orientList = [
|
||||||
|
{ label: '水平', value: 'horizontal' },
|
||||||
|
{ label: '垂直', value: 'vertical' }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 标签展示
|
||||||
|
export const toolTipSwitch = [
|
||||||
|
{ label: '开启', value: 1 },
|
||||||
|
{ label: '关闭', value: 0 }
|
||||||
|
]
|
||||||
|
|
||||||
|
export const option = {
|
||||||
|
dataset: { ...dataJson },
|
||||||
|
tooltip: {
|
||||||
|
show: 1,
|
||||||
|
trigger: 'item',
|
||||||
|
triggerOn: 'mousemove'
|
||||||
|
},
|
||||||
|
series: {
|
||||||
|
type: 'sankey',
|
||||||
|
layout: 'none',
|
||||||
|
orient:'horizontal',
|
||||||
|
data: dataJson.label,
|
||||||
|
links: dataJson.links,
|
||||||
|
levels: dataJson.levels
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Config extends PublicConfigClass implements CreateComponentType {
|
||||||
|
public key = SankeyConfig.key
|
||||||
|
public chartConfig = cloneDeep(SankeyConfig)
|
||||||
|
// 图表配置项
|
||||||
|
public option = echartOptionProfixHandle(option, includes)
|
||||||
|
}
|
43
src/packages/components/Charts/Mores/Sankey/config.vue
Normal file
43
src/packages/components/Charts/Mores/Sankey/config.vue
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<CollapseItem name="桑基图" :expanded="true">
|
||||||
|
<SettingItemBox name="样式">
|
||||||
|
<SettingItem name="方向">
|
||||||
|
<n-select
|
||||||
|
v-model:value="sankeyConfig.orient"
|
||||||
|
size="small"
|
||||||
|
:options="orientList"
|
||||||
|
placeholder="选择方向"
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
<SettingItem name="提示标签">
|
||||||
|
<n-select
|
||||||
|
v-model:value="optionData.tooltip.show"
|
||||||
|
size="small"
|
||||||
|
:options="toolTipSwitch"
|
||||||
|
placeholder="是否开启"
|
||||||
|
/>
|
||||||
|
</SettingItem>
|
||||||
|
</SettingItemBox>
|
||||||
|
</CollapseItem>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { PropType, computed } from 'vue'
|
||||||
|
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
|
||||||
|
import { option, orientList, toolTipSwitch } from './config'
|
||||||
|
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
optionData: {
|
||||||
|
type: Object as PropType<typeof option & GlobalThemeJsonType>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const sankeyConfig = computed<typeof option.series>(() => {
|
||||||
|
return props.optionData.series
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
86
src/packages/components/Charts/Mores/Sankey/data.json
Normal file
86
src/packages/components/Charts/Mores/Sankey/data.json
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"label": [
|
||||||
|
{
|
||||||
|
"name": "a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"source": "a",
|
||||||
|
"target": "a1",
|
||||||
|
"value": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "a",
|
||||||
|
"target": "a2",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "b",
|
||||||
|
"target": "b1",
|
||||||
|
"value": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "a",
|
||||||
|
"target": "b1",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "b1",
|
||||||
|
"target": "a1",
|
||||||
|
"value": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "b1",
|
||||||
|
"target": "b2",
|
||||||
|
"value": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
14
src/packages/components/Charts/Mores/Sankey/index.ts
Normal file
14
src/packages/components/Charts/Mores/Sankey/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||||
|
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
|
||||||
|
|
||||||
|
export const SankeyConfig: ConfigType = {
|
||||||
|
key: 'Sankey',
|
||||||
|
chartKey: 'VSankey',
|
||||||
|
conKey: 'VCSankey',
|
||||||
|
title: '桑基图',
|
||||||
|
category: ChatCategoryEnum.MORE,
|
||||||
|
categoryName: ChatCategoryEnumName.MORE,
|
||||||
|
package: PackagesCategoryEnum.CHARTS,
|
||||||
|
chartFrame: ChartFrameEnum.COMMON,
|
||||||
|
image: 'sankey.png'
|
||||||
|
}
|
78
src/packages/components/Charts/Mores/Sankey/index.vue
Normal file
78
src/packages/components/Charts/Mores/Sankey/index.vue
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()" autoresize></v-chart>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, PropType, watch } from 'vue'
|
||||||
|
import VChart from 'vue-echarts'
|
||||||
|
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
|
||||||
|
import dataJson from './data.json'
|
||||||
|
import { use } from 'echarts/core'
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers'
|
||||||
|
import { RadarChart } from 'echarts/charts'
|
||||||
|
import { includes } from './config'
|
||||||
|
import { mergeTheme, setOption } from '@/packages/public/chart'
|
||||||
|
import { useChartDataFetch } from '@/hooks'
|
||||||
|
import { CreateComponentType } from '@/packages/index.d'
|
||||||
|
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||||
|
import { isPreview } from '@/utils'
|
||||||
|
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
themeSetting: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
themeColor: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chartConfig: {
|
||||||
|
type: Object as PropType<CreateComponentType>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
|
||||||
|
|
||||||
|
use([DatasetComponent, CanvasRenderer, RadarChart, GridComponent, TooltipComponent, LegendComponent])
|
||||||
|
|
||||||
|
const vChartRef = ref<typeof VChart>()
|
||||||
|
|
||||||
|
const option = computed(() => {
|
||||||
|
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataHandle = (dataset: typeof dataJson) => {
|
||||||
|
if (dataset.label) {
|
||||||
|
props.chartConfig.option.series.data = dataset.label
|
||||||
|
}
|
||||||
|
if (dataset.links) {
|
||||||
|
props.chartConfig.option.series.links = dataset.links
|
||||||
|
}
|
||||||
|
if (dataset.levels) {
|
||||||
|
props.chartConfig.option.series.levels = dataset.levels
|
||||||
|
}
|
||||||
|
if (vChartRef.value && isPreview()) {
|
||||||
|
setOption(vChartRef.value, props.chartConfig.option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.chartConfig.option.dataset,
|
||||||
|
newData => {
|
||||||
|
try {
|
||||||
|
dataHandle(newData)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
|
||||||
|
dataHandle(newData)
|
||||||
|
})
|
||||||
|
</script>
|
@ -4,5 +4,8 @@ import { FunnelConfig } from './Funnel/index'
|
|||||||
import { HeatmapConfig } from './Heatmap/index'
|
import { HeatmapConfig } from './Heatmap/index'
|
||||||
import { WaterPoloConfig } from './WaterPolo/index'
|
import { WaterPoloConfig } from './WaterPolo/index'
|
||||||
import { TreeMapConfig } from './TreeMap/index'
|
import { TreeMapConfig } from './TreeMap/index'
|
||||||
|
import { DialConfig } from './Dial/index'
|
||||||
|
import { SankeyConfig } from './Sankey/index'
|
||||||
|
import { GraphConfig } from './Graph/index'
|
||||||
|
|
||||||
export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, WaterPoloConfig, TreeMapConfig]
|
export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, WaterPoloConfig, TreeMapConfig, GraphConfig, SankeyConfig, DialConfig]
|
||||||
|
@ -15,7 +15,7 @@ export interface IResources {
|
|||||||
const fileSuffix = ['earth', 'gradient', 'redCircle', 'label', 'aperture', 'glow', 'light_column', 'aircraft']
|
const fileSuffix = ['earth', 'gradient', 'redCircle', 'label', 'aperture', 'glow', 'light_column', 'aircraft']
|
||||||
const textures: ITextures[] = []
|
const textures: ITextures[] = []
|
||||||
|
|
||||||
const modules = import.meta.globEager("../../images/earth/*");
|
const modules: Record<string, { default: string }> = import.meta.glob("../../images/earth/*", { eager: true })
|
||||||
|
|
||||||
for(let item in modules) {
|
for(let item in modules) {
|
||||||
const n = item.split('/').pop()
|
const n = item.split('/').pop()
|
||||||
|
@ -4,9 +4,15 @@ import { InformationList } from '@/packages/components/Informations/index'
|
|||||||
import { TableList } from '@/packages/components/Tables/index'
|
import { TableList } from '@/packages/components/Tables/index'
|
||||||
import { PackagesCategoryEnum, PackagesType, ConfigType, FetchComFlagType } from '@/packages/index.d'
|
import { PackagesCategoryEnum, PackagesType, ConfigType, FetchComFlagType } from '@/packages/index.d'
|
||||||
|
|
||||||
const configModules = import.meta.globEager('./components/**/config.vue')
|
const configModules: Record<string, { default: string }> = import.meta.glob('./components/**/config.vue', {
|
||||||
const indexModules = import.meta.globEager('./components/**/index.vue')
|
eager: true
|
||||||
const imagesModules = import.meta.globEager('../assets/images/chart/**')
|
})
|
||||||
|
const indexModules: Record<string, { default: string }> = import.meta.glob('./components/**/index.vue', {
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
const imagesModules: Record<string, { default: string }> = import.meta.glob('../assets/images/chart/**', {
|
||||||
|
eager: true
|
||||||
|
})
|
||||||
|
|
||||||
// * 所有图表
|
// * 所有图表
|
||||||
export let packagesList: PackagesType = {
|
export let packagesList: PackagesType = {
|
||||||
|
@ -65,6 +65,7 @@ import { RequestHeader } from '../RequestHeader'
|
|||||||
import { isDev } from '@/utils'
|
import { isDev } from '@/utils'
|
||||||
import { icon } from '@/plugins'
|
import { icon } from '@/plugins'
|
||||||
import {
|
import {
|
||||||
|
graphUrl,
|
||||||
chartDataUrl,
|
chartDataUrl,
|
||||||
chartSingleDataUrl,
|
chartSingleDataUrl,
|
||||||
rankListUrl,
|
rankListUrl,
|
||||||
@ -80,7 +81,8 @@ import {
|
|||||||
capsuleUrl,
|
capsuleUrl,
|
||||||
wordCloudUrl,
|
wordCloudUrl,
|
||||||
treemapUrl,
|
treemapUrl,
|
||||||
threeEarth01Url
|
threeEarth01Url,
|
||||||
|
sankeyUrl
|
||||||
} from '@/api/mock'
|
} from '@/api/mock'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -142,6 +144,12 @@ const apiList = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: `【三维地球】${threeEarth01Url}`
|
value: `【三维地球】${threeEarth01Url}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: `【桑基图】${sankeyUrl}`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: `【关系图】${graphUrl}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
</script>
|
</script>
|
||||||
|
@ -24,6 +24,11 @@ export const syncData = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步数据到预览页
|
||||||
|
export const syncDataToPreview = () => {
|
||||||
|
dispatchEvent(new CustomEvent(SavePageEnum.CHART_TO_PREVIEW, { detail: chartEditStore.getStorageInfo }))
|
||||||
|
}
|
||||||
|
|
||||||
// 侦听器更新
|
// 侦听器更新
|
||||||
const useSyncUpdateHandle = () => {
|
const useSyncUpdateHandle = () => {
|
||||||
// 定义侦听器变量
|
// 定义侦听器变量
|
||||||
@ -48,8 +53,8 @@ const useSyncUpdateHandle = () => {
|
|||||||
// document.hasFocus() && syncData()
|
// document.hasFocus() && syncData()
|
||||||
// }, editToJsonInterval)
|
// }, editToJsonInterval)
|
||||||
|
|
||||||
// 失焦同步数据(暂不开启)
|
// 失焦同步数据
|
||||||
// addEventListener('blur', syncData)
|
addEventListener('blur', syncDataToPreview)
|
||||||
|
|
||||||
// 监听编辑器保存事件 刷新工作台图表
|
// 监听编辑器保存事件 刷新工作台图表
|
||||||
addEventListener(SavePageEnum.JSON, updateFn)
|
addEventListener(SavePageEnum.JSON, updateFn)
|
||||||
@ -61,7 +66,7 @@ const useSyncUpdateHandle = () => {
|
|||||||
// 关闭侦听
|
// 关闭侦听
|
||||||
const unUse = () => {
|
const unUse = () => {
|
||||||
// clearInterval(timer)
|
// clearInterval(timer)
|
||||||
// removeEventListener('blur', syncData)
|
removeEventListener('blur', syncDataToPreview)
|
||||||
removeEventListener(SavePageEnum.JSON, updateFn)
|
removeEventListener(SavePageEnum.JSON, updateFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +322,15 @@ $asideBottom: 70px;
|
|||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 10px;
|
||||||
|
bottom: -10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* 最小化 */
|
/* 最小化 */
|
||||||
&.isMini {
|
&.isMini {
|
||||||
@ -348,6 +357,7 @@ $asideBottom: 70px;
|
|||||||
50% {
|
50% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
bottom: calc(#{$dockMiniBottom} - 10px);
|
bottom: calc(#{$dockMiniBottom} - 10px);
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -362,15 +372,6 @@ $asideBottom: 70px;
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 20px;
|
|
||||||
bottom: -20px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<!-- 模块展示按钮 -->
|
<!-- 模块展示按钮 -->
|
||||||
<n-tooltip v-for="item in btnList" :key="item.key" placement="bottom" trigger="hover">
|
<n-tooltip v-for="item in btnList" :key="item.key" placement="bottom" trigger="hover">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<n-button size="small" ghost :type="styleHandle(item)" @click="clickHandle(item)">
|
<n-button size="small" ghost :type="styleHandle(item)" :focusable="false" @click="clickHandle(item)">
|
||||||
<component :is="item.icon"></component>
|
<component :is="item.icon"></component>
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
|
@ -14,7 +14,7 @@ import Preview from './index.vue'
|
|||||||
let key = ref(Date.now())
|
let key = ref(Date.now())
|
||||||
|
|
||||||
// 数据变更 -> 组件销毁重建
|
// 数据变更 -> 组件销毁重建
|
||||||
;[SavePageEnum.JSON, SavePageEnum.CHART].forEach((saveEvent: string) => {
|
;[SavePageEnum.JSON, SavePageEnum.CHART_TO_PREVIEW].forEach((saveEvent: string) => {
|
||||||
if (!window.opener) return
|
if (!window.opener) return
|
||||||
window.opener.addEventListener(saveEvent, async (e: any) => {
|
window.opener.addEventListener(saveEvent, async (e: any) => {
|
||||||
const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
|
const localStorageInfo: ChartEditStorageType = await getSessionStorageInfo() as unknown as ChartEditStorageType
|
||||||
|
@ -45,8 +45,7 @@ const collapsed = ref<boolean>(false)
|
|||||||
const { getAsideCollapsedWidth } = toRefs(useSettingStore())
|
const { getAsideCollapsedWidth } = toRefs(useSettingStore())
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const routeRame = computed(() => route.name)
|
const menuValue = computed(() => route.name)
|
||||||
const menuValue = ref(routeRame)
|
|
||||||
|
|
||||||
const menuOptions = menuOptionsInit()
|
const menuOptions = menuOptionsInit()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user