@vela-studio/ui 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +152 -0
  2. package/dist/index.d.ts +696 -0
  3. package/dist/index.js +10 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +11786 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/dist/index.umd.js +10 -0
  8. package/dist/index.umd.js.map +1 -0
  9. package/dist/style.css +1 -0
  10. package/index.ts +150 -0
  11. package/package.json +73 -0
  12. package/src/components/advanced/scripting/Scripting.vue +189 -0
  13. package/src/components/advanced/state/State.vue +231 -0
  14. package/src/components/advanced/trigger/Trigger.vue +256 -0
  15. package/src/components/basic/button/Button.vue +120 -0
  16. package/src/components/basic/container/Container.vue +22 -0
  17. package/src/components/chart/barChart/barChart.vue +176 -0
  18. package/src/components/chart/doughnutChart/doughnutChart.vue +128 -0
  19. package/src/components/chart/funnelChart/funnelChart.vue +128 -0
  20. package/src/components/chart/gaugeChart/gaugeChart.vue +144 -0
  21. package/src/components/chart/lineChart/lineChart.vue +188 -0
  22. package/src/components/chart/pieChart/pieChart.vue +114 -0
  23. package/src/components/chart/radarChart/radarChart.vue +115 -0
  24. package/src/components/chart/sankeyChart/sankeyChart.vue +144 -0
  25. package/src/components/chart/scatterChart/scatterChart.vue +162 -0
  26. package/src/components/chart/stackedBarChart/stackedBarChart.vue +184 -0
  27. package/src/components/content/html/Html.vue +104 -0
  28. package/src/components/content/iframe/Iframe.vue +111 -0
  29. package/src/components/content/markdown/Markdown.vue +174 -0
  30. package/src/components/controls/breadcrumb/Breadcrumb.vue +79 -0
  31. package/src/components/controls/buttonGroup/ButtonGroup.vue +93 -0
  32. package/src/components/controls/checkboxGroup/CheckboxGroup.vue +147 -0
  33. package/src/components/controls/dateRange/DateRange.vue +174 -0
  34. package/src/components/controls/multiSelect/MultiSelect.vue +155 -0
  35. package/src/components/controls/navButton/NavButton.vue +97 -0
  36. package/src/components/controls/pagination/Pagination.vue +94 -0
  37. package/src/components/controls/searchBox/SearchBox.vue +170 -0
  38. package/src/components/controls/select/Select.vue +134 -0
  39. package/src/components/controls/slider/Slider.vue +167 -0
  40. package/src/components/controls/switch/Switch.vue +107 -0
  41. package/src/components/data/cardGrid/CardGrid.vue +318 -0
  42. package/src/components/data/list/List.vue +282 -0
  43. package/src/components/data/pivot/Pivot.vue +270 -0
  44. package/src/components/data/table/Table.vue +150 -0
  45. package/src/components/data/timeline/Timeline.vue +315 -0
  46. package/src/components/group/Group.vue +75 -0
  47. package/src/components/kpi/box/Box.vue +98 -0
  48. package/src/components/kpi/countUp/CountUp.vue +193 -0
  49. package/src/components/kpi/progress/Progress.vue +159 -0
  50. package/src/components/kpi/stat/Stat.vue +205 -0
  51. package/src/components/kpi/text/Text.vue +74 -0
  52. package/src/components/layout/badge/Badge.vue +105 -0
  53. package/src/components/layout/col/Col.vue +114 -0
  54. package/src/components/layout/flex/Flex.vue +105 -0
  55. package/src/components/layout/grid/Grid.vue +89 -0
  56. package/src/components/layout/modal/Modal.vue +118 -0
  57. package/src/components/layout/panel/Panel.vue +162 -0
  58. package/src/components/layout/row/Row.vue +99 -0
  59. package/src/components/layout/tabs/Tabs.vue +117 -0
  60. package/src/components/media/image/Image.vue +132 -0
  61. package/src/components/media/video/Video.vue +115 -0
  62. package/src/components/v2/basic/BaseButton.vue +179 -0
  63. package/src/components/v2/kpi/KpiCard.vue +215 -0
  64. package/src/components/v2/layout/GridBox.vue +55 -0
  65. package/src/hooks/useDataSource.ts +123 -0
  66. package/src/types/gis.ts +251 -0
  67. package/src/utils/chartUtils.ts +349 -0
  68. package/src/utils/dataUtils.ts +403 -0
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <div class="v-funnel-chart" :style="{ width: '100%', height: '100%' }">
3
+ <v-chart :option="finalOption" autoresize class="echart" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import { use } from 'echarts/core'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import { FunnelChart } from 'echarts/charts'
12
+ import { TitleComponent, TooltipComponent, LegendComponent } from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+ import type { EChartsOption } from 'echarts'
15
+
16
+ // 注册 ECharts 组件
17
+ use([TitleComponent, TooltipComponent, LegendComponent, FunnelChart, CanvasRenderer])
18
+
19
+ // 定义标准的 Props,不含任何业务逻辑 ID
20
+ const props = defineProps<{
21
+ // 基础数据 Props
22
+ data?: Array<{ name: string; value: number }>
23
+
24
+ // 样式配置 Props
25
+ title?: string
26
+ seriesName?: string
27
+ left?: string
28
+ top?: string
29
+ bottom?: string
30
+ width?: string
31
+ min?: number
32
+ max?: number
33
+ minSize?: string
34
+ maxSize?: string
35
+ sort?: 'descending' | 'ascending' | 'none'
36
+ gap?: number
37
+ showLabel?: boolean
38
+ labelPosition?: 'left' | 'right' | 'inside'
39
+ labelFormatter?: string
40
+ showLabelLine?: boolean
41
+ labelLineLength?: number
42
+ borderColor?: string
43
+ borderWidth?: number
44
+
45
+ // 高级覆盖
46
+ option?: EChartsOption
47
+ }>()
48
+
49
+ // 默认值配置
50
+ const defaultData = [
51
+ { name: '展示', value: 100 },
52
+ { name: '访问', value: 80 },
53
+ { name: '咨询', value: 60 },
54
+ { name: '订单', value: 40 },
55
+ { name: '成交', value: 20 },
56
+ ]
57
+
58
+ // 计算最终 Option
59
+ const finalOption = computed<EChartsOption>(() => {
60
+ // 如果有高级配置 option,优先使用
61
+ if (props.option && Object.keys(props.option).length > 0) return props.option
62
+
63
+ const data = props.data && props.data.length ? props.data : defaultData
64
+ const seriesName = props.seriesName || 'Funnel'
65
+
66
+ return {
67
+ title: {
68
+ text: props.title || '',
69
+ left: 'center',
70
+ },
71
+ tooltip: {
72
+ trigger: 'item',
73
+ formatter: '{b}: {c}',
74
+ },
75
+ legend: {
76
+ bottom: 10,
77
+ data: data.map((d) => d.name),
78
+ },
79
+ series: [
80
+ {
81
+ name: seriesName,
82
+ type: 'funnel',
83
+ left: props.left || '10%',
84
+ top: props.top || '20%',
85
+ bottom: props.bottom || '20%',
86
+ width: props.width || '80%',
87
+ min: props.min || 0,
88
+ max: props.max || 100,
89
+ minSize: props.minSize || '0%',
90
+ maxSize: props.maxSize || '100%',
91
+ sort: props.sort || 'descending',
92
+ gap: props.gap || 2,
93
+ label: {
94
+ show: props.showLabel !== false,
95
+ position: props.labelPosition || 'inside',
96
+ formatter: props.labelFormatter || '{b}: {c}',
97
+ },
98
+ labelLine: {
99
+ show: props.showLabelLine !== false,
100
+ length: props.labelLineLength || 10,
101
+ },
102
+ itemStyle: {
103
+ borderColor: props.borderColor || '#fff',
104
+ borderWidth: props.borderWidth || 1,
105
+ },
106
+ emphasis: {
107
+ label: {
108
+ fontSize: 20,
109
+ },
110
+ },
111
+ data: data,
112
+ },
113
+ ],
114
+ }
115
+ })
116
+ </script>
117
+
118
+ <style scoped>
119
+ .v-funnel-chart {
120
+ width: 100%;
121
+ height: 100%;
122
+ }
123
+
124
+ .echart {
125
+ width: 100%;
126
+ height: 100%;
127
+ }
128
+ </style>
@@ -0,0 +1,144 @@
1
+ <template>
2
+ <div class="v-gauge-chart" :style="{ width: '100%', height: '100%' }">
3
+ <v-chart :option="finalOption" autoresize class="echart" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import { use } from 'echarts/core'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import { GaugeChart } from 'echarts/charts'
12
+ import { TitleComponent, TooltipComponent } from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+ import type { EChartsOption } from 'echarts'
15
+
16
+ // 注册 ECharts 组件
17
+ use([TitleComponent, TooltipComponent, GaugeChart, CanvasRenderer])
18
+
19
+ // 定义标准的 Props,不含任何业务逻辑 ID
20
+ const props = defineProps<{
21
+ // 基础数据 Props
22
+ value?: number
23
+ name?: string
24
+ min?: number
25
+ max?: number
26
+
27
+ // 样式配置 Props
28
+ title?: string
29
+ startAngle?: number
30
+ endAngle?: number
31
+ splitNumber?: number
32
+ showProgress?: boolean
33
+ progressWidth?: number
34
+ axisLineWidth?: number
35
+ axisLineColor?: Array<[number, string]>
36
+ pointerColor?: string
37
+ pointerLength?: string
38
+ pointerWidth?: number
39
+ showAxisTick?: boolean
40
+ axisTickSplitNumber?: number
41
+ showSplitLine?: boolean
42
+ splitLineLength?: number
43
+ showAxisLabel?: boolean
44
+ axisLabelDistance?: number
45
+ axisLabelFontSize?: number
46
+ detailFormatter?: string
47
+ detailFontSize?: number
48
+ detailOffsetX?: string
49
+ detailOffsetY?: string
50
+
51
+ // 高级覆盖
52
+ option?: EChartsOption
53
+ }>()
54
+
55
+ // 计算最终 Option
56
+ const finalOption = computed<EChartsOption>(() => {
57
+ // 如果有高级配置 option,优先使用
58
+ if (props.option && Object.keys(props.option).length > 0) return props.option
59
+
60
+ const value = props.value ?? 75
61
+ const name = props.name || 'Progress'
62
+ const min = props.min ?? 0
63
+ const max = props.max ?? 100
64
+
65
+ return {
66
+ title: {
67
+ text: props.title || '',
68
+ left: 'center',
69
+ },
70
+ tooltip: {
71
+ formatter: '{b}: {c}',
72
+ },
73
+ series: [
74
+ {
75
+ name: name,
76
+ type: 'gauge',
77
+ min: min,
78
+ max: max,
79
+ startAngle: props.startAngle || 225,
80
+ endAngle: props.endAngle || -45,
81
+ splitNumber: props.splitNumber || 10,
82
+ progress: {
83
+ show: props.showProgress !== false,
84
+ width: props.progressWidth || 10,
85
+ },
86
+ axisLine: {
87
+ lineStyle: {
88
+ width: props.axisLineWidth || 10,
89
+ color: props.axisLineColor || [
90
+ [0.3, '#67e0e3'],
91
+ [0.7, '#37a2da'],
92
+ [1, '#fd666d'],
93
+ ],
94
+ },
95
+ },
96
+ pointer: {
97
+ itemStyle: {
98
+ color: props.pointerColor || 'auto',
99
+ },
100
+ length: props.pointerLength || '70%',
101
+ width: props.pointerWidth || 8,
102
+ },
103
+ axisTick: {
104
+ show: props.showAxisTick !== false,
105
+ splitNumber: props.axisTickSplitNumber || 5,
106
+ },
107
+ splitLine: {
108
+ show: props.showSplitLine !== false,
109
+ length: props.splitLineLength || 15,
110
+ },
111
+ axisLabel: {
112
+ show: props.showAxisLabel !== false,
113
+ distance: props.axisLabelDistance || 25,
114
+ fontSize: props.axisLabelFontSize || 12,
115
+ },
116
+ detail: {
117
+ valueAnimation: true,
118
+ formatter: props.detailFormatter || '{value}',
119
+ fontSize: props.detailFontSize || 20,
120
+ offsetCenter: [props.detailOffsetX || '0%', props.detailOffsetY || '70%'],
121
+ },
122
+ data: [
123
+ {
124
+ value: value,
125
+ name: name,
126
+ },
127
+ ],
128
+ },
129
+ ],
130
+ }
131
+ })
132
+ </script>
133
+
134
+ <style scoped>
135
+ .v-gauge-chart {
136
+ width: 100%;
137
+ height: 100%;
138
+ }
139
+
140
+ .echart {
141
+ width: 100%;
142
+ height: 100%;
143
+ }
144
+ </style>
@@ -0,0 +1,188 @@
1
+ <template>
2
+ <div class="v-line-chart" :style="{ width: '100%', height: '100%' }">
3
+ <v-chart :option="finalOption" autoresize class="echart" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import { use } from 'echarts/core'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import { LineChart } from 'echarts/charts'
12
+ import {
13
+ TitleComponent,
14
+ TooltipComponent,
15
+ GridComponent,
16
+ LegendComponent,
17
+ } from 'echarts/components'
18
+ import VChart from 'vue-echarts'
19
+ import type { EChartsOption } from 'echarts'
20
+
21
+ // 注册 ECharts 组件
22
+ use([TitleComponent, TooltipComponent, GridComponent, LegendComponent, LineChart, CanvasRenderer])
23
+
24
+ // 定义标准的 Props,不含任何业务逻辑 ID
25
+ const props = defineProps<{
26
+ // 基础数据 Props
27
+ data?: number[]
28
+ xAxisData?: string[]
29
+ seriesName?: string
30
+
31
+ // 样式配置 Props
32
+ title?: string
33
+ lineColor?: string
34
+ smooth?: boolean
35
+ showArea?: boolean
36
+ showTooltip?: boolean
37
+ showLegend?: boolean
38
+ legendPosition?: 'top' | 'bottom' | 'left' | 'right'
39
+ showGrid?: boolean
40
+ xAxisName?: string
41
+ yAxisName?: string
42
+ showXAxisLine?: boolean
43
+ showXAxisLabel?: boolean
44
+ showYAxisLine?: boolean
45
+ showYAxisLabel?: boolean
46
+ symbolSize?: number
47
+ lineWidth?: number
48
+ lineType?: 'solid' | 'dashed' | 'dotted'
49
+ areaOpacity?: number
50
+ showSymbol?: boolean
51
+
52
+ // 高级覆盖
53
+ option?: EChartsOption
54
+ }>()
55
+
56
+ // 默认值配置
57
+ const defaultData = [150, 230, 224, 218, 135, 147, 260]
58
+ const defaultXAxis = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
59
+
60
+ // 计算最终 Option
61
+ const finalOption = computed<EChartsOption>(() => {
62
+ // 如果有高级配置 option,优先使用
63
+ if (props.option && Object.keys(props.option).length > 0) return props.option
64
+
65
+ const data = props.data && props.data.length ? props.data : defaultData
66
+ const xAxisData = props.xAxisData && props.xAxisData.length ? props.xAxisData : defaultXAxis
67
+ const seriesName = props.seriesName || 'Series'
68
+
69
+ return {
70
+ // 标题
71
+ title: props.title
72
+ ? {
73
+ text: props.title,
74
+ left: 'center',
75
+ textStyle: {
76
+ fontSize: 16,
77
+ },
78
+ }
79
+ : undefined,
80
+
81
+ // 提示框
82
+ tooltip:
83
+ props.showTooltip !== false
84
+ ? {
85
+ trigger: 'axis',
86
+ axisPointer: {
87
+ type: 'cross',
88
+ label: {
89
+ backgroundColor: '#6a7985',
90
+ },
91
+ },
92
+ }
93
+ : undefined,
94
+
95
+ // 图例
96
+ legend:
97
+ props.showLegend !== false
98
+ ? {
99
+ [(props.legendPosition as string) || 'top']: 10,
100
+ data: [seriesName],
101
+ }
102
+ : undefined,
103
+
104
+ // 网格
105
+ grid: {
106
+ left: '6%',
107
+ right: '6%',
108
+ bottom: '8%',
109
+ top: props.title ? '15%' : '10%',
110
+ containLabel: true,
111
+ show: props.showGrid !== false,
112
+ },
113
+
114
+ // X 轴
115
+ xAxis: {
116
+ type: 'category',
117
+ data: xAxisData,
118
+ name: props.xAxisName || '',
119
+ nameLocation: 'middle',
120
+ nameGap: 30,
121
+ axisLine: {
122
+ show: props.showXAxisLine !== false,
123
+ },
124
+ axisLabel: {
125
+ show: props.showXAxisLabel !== false,
126
+ },
127
+ splitLine: {
128
+ show: props.showGrid !== false,
129
+ },
130
+ },
131
+
132
+ // Y 轴
133
+ yAxis: {
134
+ type: 'value',
135
+ name: props.yAxisName || '',
136
+ nameLocation: 'middle',
137
+ nameGap: 50,
138
+ axisLine: {
139
+ show: props.showYAxisLine !== false,
140
+ },
141
+ axisLabel: {
142
+ show: props.showYAxisLabel !== false,
143
+ },
144
+ splitLine: {
145
+ show: props.showGrid !== false,
146
+ },
147
+ },
148
+
149
+ // 系列
150
+ series: [
151
+ {
152
+ name: seriesName,
153
+ type: 'line',
154
+ data: data,
155
+ smooth: props.smooth !== false,
156
+ showSymbol: props.showSymbol !== false,
157
+ symbolSize: props.symbolSize || 6,
158
+ lineStyle: {
159
+ color: props.lineColor || '#5470c6',
160
+ width: props.lineWidth || 2,
161
+ type: props.lineType || 'solid',
162
+ },
163
+ itemStyle: {
164
+ color: props.lineColor || '#5470c6',
165
+ },
166
+ areaStyle: props.showArea
167
+ ? {
168
+ color: props.lineColor || '#5470c6',
169
+ opacity: props.areaOpacity || 0.3,
170
+ }
171
+ : undefined,
172
+ },
173
+ ],
174
+ }
175
+ })
176
+ </script>
177
+
178
+ <style scoped>
179
+ .v-line-chart {
180
+ width: 100%;
181
+ height: 100%;
182
+ }
183
+
184
+ .echart {
185
+ width: 100%;
186
+ height: 100%;
187
+ }
188
+ </style>
@@ -0,0 +1,114 @@
1
+ <template>
2
+ <div class="v-pie-chart" :style="{ width: '100%', height: '100%' }">
3
+ <v-chart :option="finalOption" autoresize class="echart" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import { use } from 'echarts/core'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import { PieChart } from 'echarts/charts'
12
+ import { TitleComponent, TooltipComponent, LegendComponent } from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+ import type { EChartsOption } from 'echarts'
15
+
16
+ // 注册 ECharts 组件
17
+ use([TitleComponent, TooltipComponent, LegendComponent, PieChart, CanvasRenderer])
18
+
19
+ // 定义标准的 Props,不含任何业务逻辑 ID
20
+ const props = defineProps<{
21
+ // 基础数据 Props
22
+ data?: Array<{ name: string; value: number }>
23
+
24
+ // 样式配置 Props
25
+ title?: string
26
+ titleAlign?: 'left' | 'center' | 'right'
27
+ titleSize?: number
28
+ titleColor?: string
29
+ seriesName?: string
30
+ radius?: string
31
+ centerX?: string
32
+ centerY?: string
33
+ showLegend?: boolean
34
+ legendOrient?: 'horizontal' | 'vertical'
35
+ legendLeft?: string
36
+ legendTop?: string
37
+ showLabel?: boolean
38
+ labelFormatter?: string
39
+
40
+ // 高级覆盖
41
+ option?: EChartsOption
42
+ }>()
43
+
44
+ // 默认值配置
45
+ const defaultData = [
46
+ { name: 'Category A', value: 335 },
47
+ { name: 'Category B', value: 310 },
48
+ { name: 'Category C', value: 234 },
49
+ { name: 'Category D', value: 135 },
50
+ { name: 'Category E', value: 148 },
51
+ ]
52
+
53
+ // 计算最终 Option
54
+ const finalOption = computed<EChartsOption>(() => {
55
+ // 如果有高级配置 option,优先使用
56
+ if (props.option && Object.keys(props.option).length > 0) return props.option
57
+
58
+ const data = props.data && props.data.length ? props.data : defaultData
59
+ const seriesName = props.seriesName || 'Data'
60
+
61
+ return {
62
+ title: {
63
+ text: props.title || '',
64
+ left: props.titleAlign || 'center',
65
+ textStyle: {
66
+ fontSize: props.titleSize || 16,
67
+ color: props.titleColor || '#333',
68
+ },
69
+ },
70
+ tooltip: {
71
+ trigger: 'item',
72
+ formatter: '{a} <br/>{b}: {c} ({d}%)',
73
+ },
74
+ legend: {
75
+ show: props.showLegend !== false,
76
+ orient: props.legendOrient || 'horizontal',
77
+ left: props.legendLeft || 'center',
78
+ top: props.legendTop || 'bottom',
79
+ },
80
+ series: [
81
+ {
82
+ name: seriesName,
83
+ type: 'pie',
84
+ radius: props.radius || '60%',
85
+ center: [props.centerX || '50%', props.centerY || '50%'],
86
+ data: data,
87
+ label: {
88
+ show: props.showLabel !== false,
89
+ formatter: props.labelFormatter || '{b}: {c}',
90
+ },
91
+ emphasis: {
92
+ itemStyle: {
93
+ shadowBlur: 10,
94
+ shadowOffsetX: 0,
95
+ shadowColor: 'rgba(0, 0, 0, 0.5)',
96
+ },
97
+ },
98
+ },
99
+ ],
100
+ }
101
+ })
102
+ </script>
103
+
104
+ <style scoped>
105
+ .v-pie-chart {
106
+ width: 100%;
107
+ height: 100%;
108
+ }
109
+
110
+ .echart {
111
+ width: 100%;
112
+ height: 100%;
113
+ }
114
+ </style>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <div class="v-radar-chart" :style="{ width: '100%', height: '100%' }">
3
+ <v-chart :option="finalOption" autoresize class="echart" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { computed } from 'vue'
9
+ import { use } from 'echarts/core'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import { RadarChart } from 'echarts/charts'
12
+ import {
13
+ TitleComponent,
14
+ TooltipComponent,
15
+ LegendComponent,
16
+ RadarComponent,
17
+ } from 'echarts/components'
18
+ import VChart from 'vue-echarts'
19
+ import type { EChartsOption } from 'echarts'
20
+
21
+ // 注册 ECharts 组件
22
+ use([TitleComponent, TooltipComponent, LegendComponent, RadarComponent, RadarChart, CanvasRenderer])
23
+
24
+ // 定义标准的 Props,不含任何业务逻辑 ID
25
+ const props = defineProps<{
26
+ // 基础数据 Props
27
+ indicators?: Array<{ name: string; max: number }>
28
+ seriesData?: Array<{ name: string; value: number[] }>
29
+
30
+ // 样式配置 Props
31
+ title?: string
32
+ seriesName?: string
33
+ radarShape?: 'polygon' | 'circle'
34
+ splitNumber?: number
35
+ axisNameColor?: string
36
+ showArea?: boolean
37
+ areaOpacity?: number
38
+
39
+ // 高级覆盖
40
+ option?: EChartsOption
41
+ }>()
42
+
43
+ // 默认值配置
44
+ const defaultIndicators = [
45
+ { name: '销售', max: 100 },
46
+ { name: '管理', max: 100 },
47
+ { name: '技术', max: 100 },
48
+ { name: '客服', max: 100 },
49
+ { name: '研发', max: 100 },
50
+ { name: '市场', max: 100 },
51
+ ]
52
+
53
+ const defaultSeriesData = [
54
+ { name: '预算', value: [43, 85, 70, 75, 68, 92] },
55
+ { name: '实际开销', value: [50, 90, 60, 82, 73, 85] },
56
+ ]
57
+
58
+ // 计算最终 Option
59
+ const finalOption = computed<EChartsOption>(() => {
60
+ // 如果有高级配置 option,优先使用
61
+ if (props.option && Object.keys(props.option).length > 0) return props.option
62
+
63
+ const indicators =
64
+ props.indicators && props.indicators.length ? props.indicators : defaultIndicators
65
+ const seriesData =
66
+ props.seriesData && props.seriesData.length ? props.seriesData : defaultSeriesData
67
+ const seriesName = props.seriesName || 'Radar'
68
+
69
+ return {
70
+ title: {
71
+ text: props.title || '',
72
+ left: 'center',
73
+ },
74
+ tooltip: {
75
+ trigger: 'item',
76
+ },
77
+ legend: {
78
+ bottom: 10,
79
+ data: seriesData.map((s) => s.name),
80
+ },
81
+ radar: {
82
+ indicator: indicators,
83
+ shape: props.radarShape || 'polygon',
84
+ splitNumber: props.splitNumber || 5,
85
+ axisName: {
86
+ color: props.axisNameColor || '#333',
87
+ },
88
+ },
89
+ series: [
90
+ {
91
+ name: seriesName,
92
+ type: 'radar',
93
+ data: seriesData,
94
+ areaStyle: props.showArea
95
+ ? {
96
+ opacity: props.areaOpacity || 0.3,
97
+ }
98
+ : undefined,
99
+ },
100
+ ],
101
+ }
102
+ })
103
+ </script>
104
+
105
+ <style scoped>
106
+ .v-radar-chart {
107
+ width: 100%;
108
+ height: 100%;
109
+ }
110
+
111
+ .echart {
112
+ width: 100%;
113
+ height: 100%;
114
+ }
115
+ </style>