verce-vue-test 0.0.19 → 0.0.21

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.
@@ -1,29 +1,100 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, ref } from 'vue'
2
+ import { nextTick, onMounted, onUnmounted, ref } from 'vue'
3
3
  import { ArrowDown, Minus, RefreshRight, Setting } from '@element-plus/icons-vue'
4
- import { ringOption, sparkOption, useChartRegistry } from './chart'
4
+ import * as echarts from 'echarts'
5
+ import type { ECharts, EChartsOption } from 'echarts'
5
6
 
6
7
  const reliableChart = ref<HTMLElement>()
7
8
  const pressureChart = ref<HTMLElement>()
8
9
  const trendChart = ref<HTMLElement>()
9
10
  const pressureTrendChart = ref<HTMLElement>()
10
- const { panelChart, mountCharts } = useChartRegistry()
11
+ const charts: ECharts[] = []
11
12
 
12
- onMounted(() => {
13
- mountCharts(() => {
14
- panelChart(reliableChart.value, ringOption('低靠', [
13
+ function createChart(el: HTMLElement | undefined, option: EChartsOption) {
14
+ if (!el) return
15
+ const chart = echarts.init(el)
16
+ chart.setOption(option)
17
+ charts.push(chart)
18
+ }
19
+
20
+ function resizeCharts() {
21
+ charts.forEach((chart) => chart.resize())
22
+ }
23
+
24
+ function ringOption(
25
+ centerText: string,
26
+ data: Array<{ value: number; name: string; itemStyle?: object }>,
27
+ ): EChartsOption {
28
+ return {
29
+ color: ['#1267f2', '#e7f0ff'],
30
+ animationDuration: 900,
31
+ title: {
32
+ text: centerText,
33
+ left: 'center',
34
+ top: '42%',
35
+ textStyle: { color: '#05070b', fontSize: 30, fontWeight: 800 },
36
+ },
37
+ series: [
38
+ {
39
+ type: 'pie',
40
+ radius: ['57%', '77%'],
41
+ center: ['50%', '51%'],
42
+ startAngle: 90,
43
+ avoidLabelOverlap: false,
44
+ label: { show: false },
45
+ labelLine: { show: false },
46
+ itemStyle: { borderColor: '#fff', borderWidth: 4 },
47
+ data,
48
+ },
49
+ ],
50
+ }
51
+ }
52
+
53
+ function sparkOption(values: number[]): EChartsOption {
54
+ return {
55
+ animationDuration: 700,
56
+ grid: { left: 2, right: 2, top: 8, bottom: 7 },
57
+ xAxis: { type: 'category', show: false, data: values.map((_, index) => index) },
58
+ yAxis: { type: 'value', show: false },
59
+ series: [
60
+ {
61
+ type: 'line',
62
+ data: values,
63
+ symbol: 'none',
64
+ smooth: false,
65
+ lineStyle: { color: '#1267f2', width: 2 },
66
+ },
67
+ ],
68
+ }
69
+ }
70
+
71
+ onMounted(async () => {
72
+ await nextTick()
73
+ createChart(
74
+ reliableChart.value,
75
+ ringOption('低靠', [
15
76
  { value: 65, name: '巨靠系数', itemStyle: { color: '#1267f2' } },
16
77
  { value: 35, name: '其他', itemStyle: { color: '#e7f0ff' } },
17
- ]))
78
+ ]),
79
+ )
18
80
 
19
- panelChart(pressureChart.value, ringOption('逾期概率', [
81
+ createChart(
82
+ pressureChart.value,
83
+ ringOption('逾期概率', [
20
84
  { value: 34, name: '高压力', itemStyle: { color: '#18c7c0' } },
21
85
  { value: 66, name: '低压力', itemStyle: { color: '#1267f2' } },
22
- ]))
86
+ ]),
87
+ )
88
+
89
+ createChart(trendChart.value, sparkOption([15, 34, 18, 8, 27, 55, 36, 48]))
90
+ createChart(pressureTrendChart.value, sparkOption([12, 24, 18, 49, 62, 30, 52, 72]))
91
+
92
+ window.addEventListener('resize', resizeCharts)
93
+ })
23
94
 
24
- panelChart(trendChart.value, sparkOption([15, 34, 18, 8, 27, 55, 36, 48]))
25
- panelChart(pressureTrendChart.value, sparkOption([12, 24, 18, 49, 62, 30, 52, 72]))
26
- })
95
+ onUnmounted(() => {
96
+ window.removeEventListener('resize', resizeCharts)
97
+ charts.forEach((chart) => chart.dispose())
27
98
  })
28
99
  </script>
29
100
 
@@ -69,3 +140,252 @@ onMounted(() => {
69
140
  </div>
70
141
  </article>
71
142
  </template>
143
+
144
+ <style scoped>
145
+ .reliable-board {
146
+ --blue: #1267f2;
147
+ --line: #dce4ef;
148
+ min-width: 0;
149
+ height: calc(100vh - 190px);
150
+ min-height: 700px;
151
+ padding: 14px;
152
+ display: flex;
153
+ flex-direction: column;
154
+ background: rgba(255, 255, 255, .96);
155
+ border-radius: 10px;
156
+ box-shadow: 0 10px 22px rgba(34, 67, 123, .16);
157
+ }
158
+
159
+ .board-head {
160
+ height: 38px;
161
+ display: flex;
162
+ align-items: flex-start;
163
+ justify-content: space-between;
164
+ }
165
+
166
+ .board-head h2 {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: 10px;
170
+ font-size: 20px;
171
+ line-height: 1.1;
172
+ font-weight: 900;
173
+ }
174
+
175
+ .board-head h2 span {
176
+ width: 13px;
177
+ height: 14px;
178
+ border-radius: 4px;
179
+ background: var(--blue);
180
+ box-shadow: inset 0 0 4px rgba(255, 255, 255, .35);
181
+ }
182
+
183
+ .actions {
184
+ display: flex;
185
+ align-items: center;
186
+ gap: 16px;
187
+ color: #6c7480;
188
+ font-size: 15px;
189
+ }
190
+
191
+ .actions button {
192
+ height: 26px;
193
+ display: flex;
194
+ align-items: center;
195
+ gap: 3px;
196
+ border: 0;
197
+ background: transparent;
198
+ color: #6c7480;
199
+ font-size: 13px;
200
+ font-weight: 600;
201
+ }
202
+
203
+ .actions button.active {
204
+ padding: 0 13px;
205
+ border-radius: 14px;
206
+ background: var(--blue);
207
+ color: #fff;
208
+ }
209
+
210
+ .reliable-layout {
211
+ display: grid;
212
+ flex: 1;
213
+ margin-top: 8px;
214
+ gap: 12px;
215
+ grid-template-columns: 1fr 1fr;
216
+ grid-template-rows: minmax(0, 1fr) auto;
217
+ }
218
+
219
+ .metric-box {
220
+ min-width: 0;
221
+ position: relative;
222
+ height: 100%;
223
+ min-height: 0;
224
+ border: 1px solid var(--line);
225
+ border-radius: 10px;
226
+ background: #fff;
227
+ }
228
+
229
+ .metric-box h3 {
230
+ position: absolute;
231
+ left: 18px;
232
+ top: 18px;
233
+ z-index: 1;
234
+ font-size: 18px;
235
+ font-weight: 900;
236
+ }
237
+
238
+ .ring {
239
+ position: absolute;
240
+ left: 35%;
241
+ top: 53%;
242
+ width: min(56%, 330px);
243
+ height: min(72%, 330px);
244
+ transform: translate(-50%, -50%);
245
+ }
246
+
247
+ .legend-list {
248
+ position: absolute;
249
+ top: 50%;
250
+ right: 9%;
251
+ transform: translateY(-55%);
252
+ display: grid;
253
+ gap: 18px;
254
+ list-style: none;
255
+ }
256
+
257
+ .legend-list li {
258
+ display: flex;
259
+ align-items: center;
260
+ gap: 10px;
261
+ color: #56606d;
262
+ font-size: 15px;
263
+ white-space: nowrap;
264
+ }
265
+
266
+ .legend-list b {
267
+ width: 8px;
268
+ height: 8px;
269
+ border-radius: 50%;
270
+ background: var(--blue);
271
+ }
272
+
273
+ .deep {
274
+ background: #1667e8 !important;
275
+ }
276
+
277
+ .sky {
278
+ background: #58aef7 !important;
279
+ }
280
+
281
+ .green {
282
+ background: #18c7c0 !important;
283
+ }
284
+
285
+ .pale {
286
+ background: #aeeeff !important;
287
+ }
288
+
289
+ .orange {
290
+ background: #ff9f13 !important;
291
+ }
292
+
293
+ .pressure {
294
+ right: 60px;
295
+ }
296
+
297
+ .mini-strip {
298
+ grid-column: 1 / -1;
299
+ height: 100%;
300
+ min-height: 130px;
301
+ display: grid;
302
+ grid-template-columns: 1.1fr .65fr 1.35fr 1.45fr .7fr 1.35fr;
303
+ border: 1px solid var(--line);
304
+ border-radius: 10px;
305
+ background: #fff;
306
+ }
307
+
308
+ .mini-strip > div {
309
+ padding: 18px;
310
+ border-right: 1px solid #e4e9f0;
311
+ }
312
+
313
+ .mini-strip > div:last-child {
314
+ border-right: 0;
315
+ }
316
+
317
+ .mini-strip p {
318
+ color: #4d5868;
319
+ font-size: 14px;
320
+ }
321
+
322
+ .mini-strip strong {
323
+ display: block;
324
+ margin-top: 18px;
325
+ font-size: 25px;
326
+ font-weight: 900;
327
+ }
328
+
329
+ .blue-text {
330
+ color: var(--blue) !important;
331
+ }
332
+
333
+ .mini-strip em {
334
+ color: #14a77c;
335
+ font-style: normal;
336
+ }
337
+
338
+ .spark {
339
+ width: min(92%, 260px);
340
+ height: 84px;
341
+ margin-top: 13px;
342
+ }
343
+
344
+ @media (max-width: 1200px) {
345
+ .reliable-board {
346
+ height: auto;
347
+ }
348
+
349
+ .reliable-layout {
350
+ grid-template-columns: 1fr;
351
+ }
352
+
353
+ .metric-box {
354
+ min-height: 253px;
355
+ }
356
+
357
+ .mini-strip {
358
+ grid-template-columns: repeat(3, 1fr);
359
+ height: auto;
360
+ }
361
+
362
+ .mini-strip > div {
363
+ min-height: 72px;
364
+ }
365
+ }
366
+
367
+ @media (max-width: 720px) {
368
+ .actions {
369
+ gap: 10px;
370
+ }
371
+
372
+ .board-head {
373
+ height: auto;
374
+ gap: 12px;
375
+ flex-wrap: wrap;
376
+ margin-bottom: 12px;
377
+ }
378
+
379
+ .reliable-layout {
380
+ gap: 10px;
381
+ }
382
+
383
+ .legend-list {
384
+ right: 16px;
385
+ }
386
+
387
+ .mini-strip {
388
+ grid-template-columns: 1fr;
389
+ }
390
+ }
391
+ </style>
@@ -1,15 +1,65 @@
1
1
  <script setup lang="ts">
2
- import { onMounted, ref } from 'vue'
2
+ import { nextTick, onMounted, onUnmounted, ref } from 'vue'
3
3
  import { ArrowDown, Minus, RefreshRight, Setting } from '@element-plus/icons-vue'
4
- import { chartGradient, lineOption, useChartRegistry } from './chart'
4
+ import * as echarts from 'echarts'
5
+ import type { ECharts, EChartsOption } from 'echarts'
5
6
 
6
7
  const scaleChart = ref<HTMLElement>()
7
8
  const gapChart = ref<HTMLElement>()
8
- const { panelChart, mountCharts } = useChartRegistry()
9
+ const charts: ECharts[] = []
9
10
 
10
- onMounted(() => {
11
- mountCharts(() => {
12
- panelChart(scaleChart.value, lineOption([
11
+ function createChart(el: HTMLElement | undefined, option: EChartsOption) {
12
+ if (!el) return
13
+ const chart = echarts.init(el)
14
+ chart.setOption(option)
15
+ charts.push(chart)
16
+ }
17
+
18
+ function resizeCharts() {
19
+ charts.forEach((chart) => chart.resize())
20
+ }
21
+
22
+ function lineOption(series: echarts.SeriesOption[], yMin = 0, yMax = 200): EChartsOption {
23
+ return {
24
+ grid: { left: 56, right: 28, top: 46, bottom: 42 },
25
+ legend: {
26
+ top: 4,
27
+ right: 8,
28
+ icon: 'path://M0,4 L12,4',
29
+ itemWidth: 16,
30
+ itemHeight: 7,
31
+ textStyle: { color: '#6e7787', fontSize: 11 },
32
+ },
33
+ xAxis: {
34
+ type: 'category',
35
+ boundaryGap: false,
36
+ data: ['05-15', '05-16', '05-17', '05-18', '05-20', '05-21'],
37
+ axisTick: { show: false },
38
+ axisLine: { lineStyle: { color: '#d6dde8' } },
39
+ axisLabel: { color: '#6b7280', fontSize: 12 },
40
+ },
41
+ yAxis: {
42
+ type: 'value',
43
+ min: yMin,
44
+ max: yMax,
45
+ splitNumber: 4,
46
+ axisLabel: { color: '#6b7280', fontSize: 12 },
47
+ splitLine: { lineStyle: { color: '#e7ecf3' } },
48
+ },
49
+ series,
50
+ }
51
+ }
52
+
53
+ function chartGradient(start: string, end: string) {
54
+ return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
55
+ { offset: 0, color: start },
56
+ { offset: 1, color: end },
57
+ ])
58
+ }
59
+
60
+ onMounted(async () => {
61
+ await nextTick()
62
+ createChart(scaleChart.value, lineOption([
13
63
  {
14
64
  name: '日头寸规模',
15
65
  type: 'line',
@@ -31,7 +81,7 @@ onMounted(() => {
31
81
  },
32
82
  ]))
33
83
 
34
- panelChart(gapChart.value, lineOption([
84
+ createChart(gapChart.value, lineOption([
35
85
  {
36
86
  name: '资金缺口',
37
87
  type: 'line',
@@ -54,7 +104,13 @@ onMounted(() => {
54
104
  },
55
105
  },
56
106
  ], -100, 200))
57
- })
107
+
108
+ window.addEventListener('resize', resizeCharts)
109
+ })
110
+
111
+ onUnmounted(() => {
112
+ window.removeEventListener('resize', resizeCharts)
113
+ charts.forEach((chart) => chart.dispose())
58
114
  })
59
115
  </script>
60
116
 
@@ -92,3 +148,201 @@ onMounted(() => {
92
148
  </div>
93
149
  </article>
94
150
  </template>
151
+
152
+ <style scoped>
153
+ .warning-board {
154
+ --blue: #1267f2;
155
+ --line: #dce4ef;
156
+ min-width: 0;
157
+ height: calc(100vh - 190px);
158
+ min-height: 700px;
159
+ padding: 14px;
160
+ display: flex;
161
+ flex-direction: column;
162
+ background: rgba(255, 255, 255, .96);
163
+ border-radius: 10px;
164
+ box-shadow: 0 10px 22px rgba(34, 67, 123, .16);
165
+ }
166
+
167
+ .board-head {
168
+ height: 38px;
169
+ display: flex;
170
+ align-items: flex-start;
171
+ justify-content: space-between;
172
+ }
173
+
174
+ .board-head h2 {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 10px;
178
+ font-size: 20px;
179
+ line-height: 1.1;
180
+ font-weight: 900;
181
+ }
182
+
183
+ .board-head h2 span {
184
+ width: 13px;
185
+ height: 14px;
186
+ border-radius: 4px;
187
+ background: var(--blue);
188
+ box-shadow: inset 0 0 4px rgba(255, 255, 255, .35);
189
+ }
190
+
191
+ .actions {
192
+ display: flex;
193
+ align-items: center;
194
+ gap: 16px;
195
+ color: #6c7480;
196
+ font-size: 15px;
197
+ }
198
+
199
+ .actions button {
200
+ height: 26px;
201
+ display: flex;
202
+ align-items: center;
203
+ gap: 3px;
204
+ border: 0;
205
+ background: transparent;
206
+ color: #6c7480;
207
+ font-size: 13px;
208
+ font-weight: 600;
209
+ }
210
+
211
+ .warning-layout {
212
+ display: grid;
213
+ flex: 1;
214
+ margin-top: 8px;
215
+ gap: 12px;
216
+ grid-template-columns: 1.05fr .9fr;
217
+ grid-template-rows: minmax(0, 1fr) auto;
218
+ }
219
+
220
+ .chart-box {
221
+ min-width: 0;
222
+ position: relative;
223
+ height: 100%;
224
+ min-height: 0;
225
+ border: 1px solid var(--line);
226
+ border-radius: 10px;
227
+ background: #fff;
228
+ }
229
+
230
+ .chart-box h3 {
231
+ position: absolute;
232
+ left: 18px;
233
+ top: 18px;
234
+ z-index: 1;
235
+ font-size: 18px;
236
+ font-weight: 900;
237
+ }
238
+
239
+ .chart-box small {
240
+ position: absolute;
241
+ left: 18px;
242
+ top: 56px;
243
+ z-index: 1;
244
+ color: #232a33;
245
+ font-size: 12px;
246
+ }
247
+
248
+ .line-chart {
249
+ position: absolute;
250
+ inset: 72px 22px 22px 18px;
251
+ }
252
+
253
+ .stat-strip {
254
+ grid-column: 1 / -1;
255
+ min-height: 110px;
256
+ display: grid;
257
+ grid-template-columns: .8fr .7fr .8fr .8fr .8fr .8fr .8fr;
258
+ align-items: center;
259
+ border: 1px solid var(--line);
260
+ border-radius: 10px;
261
+ background: #fff;
262
+ }
263
+
264
+ .stat-strip > div {
265
+ min-height: 50px;
266
+ padding-left: 17px;
267
+ border-right: 1px solid #dce4ef;
268
+ }
269
+
270
+ .stat-strip > div:last-child {
271
+ border-right: 0;
272
+ }
273
+
274
+ .stat-strip p {
275
+ color: #4d5868;
276
+ font-size: 14px;
277
+ }
278
+
279
+ .stat-strip strong,
280
+ .stat-strip b {
281
+ display: block;
282
+ margin-top: 8px;
283
+ font-size: 21px;
284
+ font-weight: 900;
285
+ }
286
+
287
+ .blue-text {
288
+ color: var(--blue) !important;
289
+ }
290
+
291
+ em {
292
+ color: #10b990;
293
+ font-style: normal;
294
+ }
295
+
296
+ .tiny-bar {
297
+ display: block;
298
+ width: 64px;
299
+ height: 8px;
300
+ margin-top: 7px;
301
+ border-radius: 6px;
302
+ background: linear-gradient(90deg, var(--blue) 0 56%, #e7ebf0 56%);
303
+ }
304
+
305
+ @media (max-width: 1200px) {
306
+ .warning-board {
307
+ height: auto;
308
+ }
309
+
310
+ .warning-layout {
311
+ grid-template-columns: 1fr;
312
+ }
313
+
314
+ .chart-box {
315
+ min-height: 253px;
316
+ }
317
+
318
+ .stat-strip {
319
+ grid-template-columns: repeat(3, 1fr);
320
+ height: auto;
321
+ }
322
+
323
+ .stat-strip > div {
324
+ min-height: 72px;
325
+ }
326
+ }
327
+
328
+ @media (max-width: 720px) {
329
+ .actions {
330
+ gap: 10px;
331
+ }
332
+
333
+ .board-head {
334
+ height: auto;
335
+ gap: 12px;
336
+ flex-wrap: wrap;
337
+ margin-bottom: 12px;
338
+ }
339
+
340
+ .warning-layout {
341
+ gap: 10px;
342
+ }
343
+
344
+ .stat-strip {
345
+ grid-template-columns: 1fr;
346
+ }
347
+ }
348
+ </style>