!148 feat: 增加桑基图组件,桑基图mock接口

Merge pull request !148 from szy/feat-sankey
This commit is contained in:
奔跑的面条 2023-04-01 06:41:15 +00:00 committed by Gitee
commit 27c28d68ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
11 changed files with 371 additions and 2 deletions

View File

@ -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
View 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
}
}
]
}

View File

@ -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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View 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)
}

View 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>

View 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
}
}
]
}

View 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'
}

View 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>

View File

@ -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]

View File

@ -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}`
} }