mirror of
https://gitee.com/dromara/go-view.git
synced 2025-02-25 00:33:00 +08:00
!148 feat: 增加桑基图组件,桑基图mock接口
Merge pull request !148 from szy/feat-sankey
This commit is contained in:
commit
27c28d68ec
@ -19,6 +19,7 @@ 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'
|
export const graphUrl = '/mock/graphData'
|
||||||
|
|
||||||
const mockObject: MockMethod[] = [
|
const mockObject: MockMethod[] = [
|
||||||
@ -104,6 +105,11 @@ 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,
|
url: graphUrl,
|
||||||
method: RequestHttpEnum.GET,
|
method: RequestHttpEnum.GET,
|
||||||
|
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,7 @@ 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'
|
import graphDataJson from './graph.json'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -221,6 +222,13 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// 桑基图
|
||||||
|
fetchSankey: {
|
||||||
|
code: 0,
|
||||||
|
status: 200,
|
||||||
|
msg: '请求成功',
|
||||||
|
data: sankeyJson
|
||||||
|
},
|
||||||
// 关系图
|
// 关系图
|
||||||
graphData: {
|
graphData: {
|
||||||
code: 0,
|
code: 0,
|
||||||
|
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 |
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,6 +4,7 @@ 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 { SankeyConfig } from './Sankey/index'
|
||||||
import { GraphConfig } from './Graph/index'
|
import { GraphConfig } from './Graph/index'
|
||||||
|
|
||||||
export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, WaterPoloConfig, TreeMapConfig, GraphConfig]
|
export default [ProcessConfig, RadarConfig, FunnelConfig, HeatmapConfig, WaterPoloConfig, TreeMapConfig, GraphConfig, SankeyConfig]
|
||||||
|
@ -81,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({
|
||||||
@ -144,6 +145,9 @@ const apiList = [
|
|||||||
{
|
{
|
||||||
value: `【三维地球】${threeEarth01Url}`
|
value: `【三维地球】${threeEarth01Url}`
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: `【桑基图】${sankeyUrl}`
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: `【关系图】${graphUrl}`
|
value: `【关系图】${graphUrl}`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user