lw-cdp-ui 1.3.24 → 1.3.26

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.
@@ -0,0 +1,218 @@
1
+ <template>
2
+ <v-chart class="chart"
3
+ :style="{ height }"
4
+ :option="option"
5
+ autoresize />
6
+ </template>
7
+
8
+ <script>
9
+ import {use} from 'echarts/core'
10
+ import {LineChart} from 'echarts/charts'
11
+ import {CanvasRenderer} from 'echarts/renderers'
12
+ import {TitleComponent, TooltipComponent, LegendComponent, GridComponent, ToolboxComponent} from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+
15
+ use([CanvasRenderer, LineChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent, ToolboxComponent])
16
+
17
+ export default {
18
+ name: 'AreaChart',
19
+ components: {
20
+ VChart
21
+ },
22
+ props: {
23
+ rawData: {
24
+ type: Object,
25
+ required: true,
26
+ validator: value => {
27
+ return value.dataSet && value.dataSet.tables && value.setting
28
+ }
29
+ },
30
+ height: {
31
+ type: String,
32
+ default: '300px'
33
+ }
34
+ },
35
+ data() {
36
+ return {
37
+ option: {}
38
+ }
39
+ },
40
+ watch: {
41
+ rawData: {
42
+ handler: 'updateChart',
43
+ deep: true,
44
+ immediate: true
45
+ }
46
+ },
47
+ methods: {
48
+ updateChart() {
49
+ const {setting, dataSet} = this.rawData
50
+ const {tables} = dataSet
51
+
52
+ if (!tables || tables.length === 0) return
53
+
54
+ this.option = {
55
+ title: this.getTitleOption(setting),
56
+ tooltip: this.getTooltipOption(setting),
57
+ legend: this.getLegendOption(setting, tables),
58
+ grid: this.getGridOption(setting),
59
+ toolbox: this.getToolboxOption(setting),
60
+ xAxis: this.getXAxisOption(tables),
61
+ yAxis: this.getYAxisOption(),
62
+ series: this.getSeriesData(setting, tables),
63
+ color: setting.color || this.getDefaultColors()
64
+ }
65
+ },
66
+
67
+ getTitleOption(setting) {
68
+ return {
69
+ show: setting.title?.show !== false,
70
+ text: setting.title?.text || '',
71
+ textStyle: setting.title?.textStyle || {
72
+ fontSize: 16,
73
+ fontWeight: 'bold',
74
+ color: '#333'
75
+ },
76
+ left: setting.title?.left || 'center',
77
+ top: setting.title?.top || 'top',
78
+ padding: setting.title?.padding || [5, 5, 5, 5]
79
+ }
80
+ },
81
+
82
+ getTooltipOption(setting) {
83
+ return {
84
+ ...(setting.tooltip || {}),
85
+ trigger: 'axis',
86
+ axisPointer: {
87
+ type: 'cross',
88
+ label: {
89
+ backgroundColor: '#6a7985'
90
+ }
91
+ }
92
+ }
93
+ },
94
+
95
+ getLegendOption(setting, tables) {
96
+ return {
97
+ ...(setting.legend || {}),
98
+ data: tables.map(table => table.metricName),
99
+ type: 'scroll',
100
+ bottom: 0,
101
+ textStyle: {
102
+ fontSize: 12
103
+ }
104
+ }
105
+ },
106
+
107
+ getGridOption(setting) {
108
+ return {
109
+ ...(setting.grid || {}),
110
+ left: '3%',
111
+ right: '4%',
112
+ bottom: setting.legend?.show !== false ? '15%' : '3%',
113
+ containLabel: true
114
+ }
115
+ },
116
+
117
+ getToolboxOption(setting) {
118
+ if (setting.toolbox?.show === false) {
119
+ return {show: false}
120
+ }
121
+
122
+ return {
123
+ feature: {
124
+ saveAsImage: {
125
+ title: '保存为图片',
126
+ pixelRatio: 2
127
+ },
128
+ dataView: {
129
+ readOnly: true,
130
+ title: '数据视图'
131
+ },
132
+ magicType: {
133
+ title: {
134
+ line: '切换为折线图',
135
+ bar: '切换为柱状图'
136
+ },
137
+ type: ['line', 'bar']
138
+ },
139
+ restore: {
140
+ title: '还原'
141
+ }
142
+ },
143
+ right: 10,
144
+ top: 0
145
+ }
146
+ },
147
+
148
+ getXAxisOption(tables) {
149
+ return {
150
+ type: 'category',
151
+ boundaryGap: false,
152
+ data: tables[0].headers,
153
+ axisLabel: {
154
+ rotate: 30,
155
+ interval: 0
156
+ }
157
+ }
158
+ },
159
+
160
+ getYAxisOption() {
161
+ return {
162
+ type: 'value',
163
+ axisLabel: {
164
+ formatter: value => {
165
+ if (value >= 10000) {
166
+ return value / 10000 + '万'
167
+ }
168
+ return value
169
+ }
170
+ }
171
+ }
172
+ },
173
+
174
+ getSeriesData(setting, tables) {
175
+ return tables.map((table, index) => ({
176
+ name: table.metricName,
177
+ type: 'line',
178
+ stack: 'total',
179
+ areaStyle: {
180
+ opacity: 0.8,
181
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
182
+ {offset: 0, color: 'rgba(58, 77, 233, 0.8)'},
183
+ {offset: 1, color: 'rgba(58, 77, 233, 0.1)'}
184
+ ])
185
+ },
186
+ emphasis: {
187
+ focus: 'series'
188
+ },
189
+ smooth: setting.smooth || true,
190
+ symbol: 'circle',
191
+ symbolSize: 6,
192
+ lineStyle: {
193
+ width: 2
194
+ },
195
+ data: table.rows[0].values,
196
+ label: {
197
+ show: setting.label?.show || false,
198
+ position: 'top',
199
+ formatter: setting.label?.formatter || '{@value}',
200
+ fontSize: 12
201
+ }
202
+ }))
203
+ },
204
+
205
+ getDefaultColors() {
206
+ return ['#3A4DE9', '#4BC0C0', '#FF9F43', '#ED5565', '#A0A7E6', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
207
+ }
208
+ }
209
+ }
210
+ </script>
211
+
212
+ <style scoped>
213
+ .chart {
214
+ width: 100%;
215
+ height: 100%;
216
+ min-height: 300px;
217
+ }
218
+ </style>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <v-chart class="chart"
3
+ :style="{ height }"
4
+ :option="option"
5
+ autoresize />
6
+ </template>
7
+
8
+ <script>
9
+ import {use} from 'echarts/core'
10
+ import {BarChart} from 'echarts/charts'
11
+ import {CanvasRenderer} from 'echarts/renderers'
12
+ import {TitleComponent, TooltipComponent, LegendComponent, GridComponent} from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+
15
+ use([CanvasRenderer, BarChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent])
16
+
17
+ export default {
18
+ name: 'BarChart',
19
+ components: {
20
+ VChart
21
+ },
22
+ props: {
23
+ rawData: {
24
+ type: Object,
25
+ required: true
26
+ },
27
+ height: {
28
+ type: String,
29
+ default: '300px'
30
+ }
31
+ },
32
+ data() {
33
+ return {
34
+ option: {}
35
+ }
36
+ },
37
+ watch: {
38
+ rawData: {
39
+ handler: 'updateOption',
40
+ deep: true,
41
+ immediate: true
42
+ }
43
+ },
44
+ methods: {
45
+ updateOption() {
46
+ const {setting, dataSet} = this.rawData
47
+ const {tables} = dataSet
48
+
49
+ if (!tables || tables.length === 0) return
50
+
51
+ this.option = {
52
+ title: this.getTitleOption(setting),
53
+ legend: this.getLegendOption(setting, tables),
54
+ grid: setting.grid || {},
55
+ tooltip: setting.tooltip || {},
56
+ color: setting.color,
57
+ xAxis: this.getXAxisOption(setting, tables),
58
+ yAxis: this.getYAxisOption(setting),
59
+ series: this.getSeries(setting, tables)
60
+ }
61
+ },
62
+
63
+ getTitleOption(setting) {
64
+ return {
65
+ show: setting.title?.show || false,
66
+ text: setting.title?.text || '',
67
+ textStyle: setting.title?.textStyle || {},
68
+ left: setting.title?.left || 'center',
69
+ padding: setting.title?.padding || [5, 5, 5, 5]
70
+ }
71
+ },
72
+
73
+ getLegendOption(setting, tables) {
74
+ return {
75
+ ...(setting.legend || {}),
76
+ data: tables.map(table => table.metricName)
77
+ }
78
+ },
79
+
80
+ getXAxisOption(setting, tables) {
81
+ return setting.revertAxis
82
+ ? {type: 'value'}
83
+ : {
84
+ type: 'category',
85
+ data: tables[0].headers
86
+ }
87
+ },
88
+
89
+ getYAxisOption(setting) {
90
+ return setting.revertAxis
91
+ ? {
92
+ type: 'category',
93
+ data: this.rawData.dataSet.tables[0].headers
94
+ }
95
+ : {type: 'value'}
96
+ },
97
+
98
+ getSeries(setting, tables) {
99
+ return tables.map(table => ({
100
+ name: table.metricName,
101
+ type: 'bar',
102
+ data: setting.revertAxis
103
+ ? table.rows[0].values.map((value, index) => ({
104
+ value,
105
+ name: table.headers[index]
106
+ }))
107
+ : table.rows[0].values,
108
+ barMaxWidth: setting.barMaxWidth,
109
+ barMinWidth: setting.barMinWidth,
110
+ label: {
111
+ show: setting.label?.show || false,
112
+ position: setting.label?.position || 'outside',
113
+ formatter: setting.label?.formatter || '{@value}'
114
+ }
115
+ }))
116
+ }
117
+ }
118
+ }
119
+ </script>
120
+
121
+ <style scoped>
122
+ .chart {
123
+ width: 100%;
124
+ height: 100%;
125
+ }
126
+ </style>
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <div class="chart-title-container"
3
+ :style="titleStyle">
4
+ <div class="title-text"
5
+ :style="textStyle">
6
+ {{ titleText }}
7
+ </div>
8
+ <div v-if="subtitle"
9
+ class="subtitle-text"
10
+ :style="subtitleStyle">
11
+ {{ subtitle }}
12
+ </div>
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ export default {
18
+ name: 'ChartTitle',
19
+ props: {
20
+ title: {
21
+ type: String,
22
+ default: ''
23
+ },
24
+ subtitle: {
25
+ type: String,
26
+ default: ''
27
+ },
28
+ align: {
29
+ type: String,
30
+ default: 'center',
31
+ validator: value => ['left', 'center', 'right'].includes(value)
32
+ },
33
+ titleStyle: {
34
+ type: Object,
35
+ default: () => ({
36
+ color: '#333',
37
+ fontSize: '18px',
38
+ fontWeight: 'bold',
39
+ marginBottom: '10px'
40
+ })
41
+ },
42
+ subtitleStyle: {
43
+ type: Object,
44
+ default: () => ({
45
+ color: '#666',
46
+ fontSize: '14px',
47
+ marginTop: '4px'
48
+ })
49
+ },
50
+ showDivider: {
51
+ type: Boolean,
52
+ default: false
53
+ },
54
+ dividerColor: {
55
+ type: String,
56
+ default: '#eee'
57
+ }
58
+ },
59
+ computed: {
60
+ titleText() {
61
+ return this.title || '图表标题'
62
+ },
63
+ textStyle() {
64
+ return {
65
+ textAlign: this.align,
66
+ ...this.titleStyle
67
+ }
68
+ },
69
+ containerStyle() {
70
+ return {
71
+ borderBottom: this.showDivider ? `1px solid ${this.dividerColor}` : 'none',
72
+ paddingBottom: this.showDivider ? '10px' : '0'
73
+ }
74
+ }
75
+ }
76
+ }
77
+ </script>
78
+
79
+ <style scoped>
80
+ .chart-title-container {
81
+ width: 100%;
82
+ margin-bottom: 16px;
83
+ }
84
+
85
+ .title-text {
86
+ font-size: 18px;
87
+ font-weight: bold;
88
+ color: #333;
89
+ }
90
+
91
+ .subtitle-text {
92
+ font-size: 14px;
93
+ color: #666;
94
+ margin-top: 4px;
95
+ }
96
+ </style>
@@ -0,0 +1,149 @@
1
+ <template>
2
+ <v-chart class="chart"
3
+ :style="{ height }"
4
+ :option="option"
5
+ autoresize />
6
+ </template>
7
+
8
+ <script>
9
+ import {use} from 'echarts/core'
10
+ import {FunnelChart} from 'echarts/charts'
11
+ import {CanvasRenderer} from 'echarts/renderers'
12
+ import {TitleComponent, TooltipComponent, LegendComponent, GridComponent} from 'echarts/components'
13
+ import VChart from 'vue-echarts'
14
+
15
+ use([CanvasRenderer, FunnelChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent])
16
+
17
+ export default {
18
+ name: 'FunnelChart',
19
+ components: {
20
+ VChart
21
+ },
22
+ props: {
23
+ rawData: {
24
+ type: Object,
25
+ required: true,
26
+ validator: value => {
27
+ return value.dataSet && value.dataSet.tables && value.setting
28
+ }
29
+ },
30
+ height: {
31
+ type: String,
32
+ default: '300px'
33
+ }
34
+ },
35
+ data() {
36
+ return {
37
+ option: {}
38
+ }
39
+ },
40
+ watch: {
41
+ rawData: {
42
+ handler: 'updateChart',
43
+ deep: true,
44
+ immediate: true
45
+ }
46
+ },
47
+ methods: {
48
+ updateChart() {
49
+ const {setting, dataSet} = this.rawData
50
+ const {tables} = dataSet
51
+
52
+ if (!tables || tables.length === 0) return
53
+
54
+ this.option = {
55
+ title: this.getTitleOption(setting),
56
+ tooltip: this.getTooltipOption(setting),
57
+ legend: this.getLegendOption(setting, tables),
58
+ series: this.getSeriesData(setting, tables),
59
+ color: setting.color || this.getDefaultColors()
60
+ }
61
+ },
62
+
63
+ getTitleOption(setting) {
64
+ return {
65
+ show: setting.title?.show !== false,
66
+ text: setting.title?.text || '',
67
+ left: setting.title?.left || 'center',
68
+ textStyle: setting.title?.textStyle || {
69
+ fontSize: 16,
70
+ fontWeight: 'bold'
71
+ }
72
+ }
73
+ },
74
+
75
+ getTooltipOption(setting) {
76
+ return {
77
+ trigger: 'item',
78
+ formatter: setting.tooltip?.formatter || '{a} <br/>{b}: {c} ({d}%)'
79
+ }
80
+ },
81
+
82
+ getLegendOption(setting, tables) {
83
+ return {
84
+ show: setting.legend?.show !== false,
85
+ data: tables[0].headers,
86
+ textStyle: setting.legend?.textStyle || {
87
+ fontSize: 12
88
+ }
89
+ }
90
+ },
91
+
92
+ getSeriesData(setting, tables) {
93
+ return [
94
+ {
95
+ name: tables[0].metricName,
96
+ type: 'funnel',
97
+ left: '10%',
98
+ top: 60,
99
+ bottom: 60,
100
+ width: '80%',
101
+ min: 0,
102
+ max: 100,
103
+ minSize: '0%',
104
+ maxSize: '100%',
105
+ sort: setting.sort || 'descending',
106
+ gap: 2,
107
+ label: {
108
+ show: setting.label?.show !== false,
109
+ position: 'inside',
110
+ formatter: setting.label?.formatter || '{b}: {c}'
111
+ },
112
+ labelLine: {
113
+ length: 10,
114
+ lineStyle: {
115
+ width: 1,
116
+ type: 'solid'
117
+ }
118
+ },
119
+ itemStyle: {
120
+ borderColor: '#fff',
121
+ borderWidth: 1
122
+ },
123
+ emphasis: {
124
+ label: {
125
+ fontSize: 16
126
+ }
127
+ },
128
+ data: tables[0].headers.map((name, index) => ({
129
+ value: tables[0].rows[0].values[index],
130
+ name: name
131
+ }))
132
+ }
133
+ ]
134
+ },
135
+
136
+ getDefaultColors() {
137
+ return ['#3A4DE9', '#4BC0C0', '#FF9F43', '#ED5565', '#A0A7E6', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
138
+ }
139
+ }
140
+ }
141
+ </script>
142
+
143
+ <style scoped>
144
+ .chart {
145
+ width: 100%;
146
+ height: 100%;
147
+ min-height: 300px;
148
+ }
149
+ </style>