matrix_components 2.0.500 → 2.0.501

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,1366 @@
1
+ <template>
2
+ <div class="saturation-line-view">
3
+ <span>浸润线 - 自定义Canvas演示</span>
4
+ <!-- 方案1(推荐,支持sort按照x坐标从小到大排序):fullData -->
5
+ <NsSaturationline ref="canvasRef" class="saturationline-canvas" :fullData="fullData" :isSortX="true" :config="config">
6
+ <span>无数据</span>
7
+ <template #custom-canvas>
8
+ <canvas id="saturation-line-canvas" width="800" height="400"></canvas>
9
+ </template>
10
+ </NsSaturationline>
11
+
12
+ <!-- 自定义Canvas操作区域 -->
13
+ <div class="custom-canvas-controls">
14
+ <h3>自定义Canvas功能演示</h3>
15
+ <button @click="drawCustomShapes">在自定义Canvas上绘制图形</button>
16
+ <button @click="showCoordinateInfo">显示坐标系信息</button>
17
+ <button @click="addCustomMarkers">添加自定义标记</button>
18
+ <button @click="drawCswlValListLine">绘制cswlValList线条</button>
19
+ </div>
20
+ <!-- 方案2(兼容老的调用方式) -->
21
+ <!-- <NsSaturationline ref="canvasRef" class="saturationline-canvas" :data="state.damData" :waterLevel="state.waterLevel">
22
+ <span>无数据</span>
23
+ </NsSaturationline> -->
24
+ </div>
25
+ </template>
26
+ <script setup lang="ts" name="">
27
+ import { ElMessageBox } from 'element-plus';
28
+ import { onMounted, reactive, ref, nextTick } from 'vue';
29
+
30
+ const config = reactive({
31
+ stoneYOffset: 20,
32
+ max_label_count: 100,
33
+ x_right_percent: 1.15,
34
+ y_right_percent: 1.25,
35
+ wall_width: 5,
36
+ xTrackOffset: 50,
37
+ yTrackOffset: 20,
38
+ yTrackTop: 50,
39
+ pipeLineTextYoffset: 30,
40
+ damLineColor: "#999999",
41
+ damBkColor: "#f6e7cc",
42
+ axisLineColor: "#A5BEDA",
43
+ axisTextColor: '#666666',
44
+ pipeLineColor: '#EEEEEE',
45
+ waterLevelTextColor: '#212121',
46
+ waterLevelStartColor: 'rgba(10, 123, 255, 0.7)',
47
+ waterLevelEndColor: 'rgba(10, 123, 255, 0.2)',
48
+ wallColor: '#999999',
49
+ xyLabelFontSize: 12,
50
+ pipeLineLabelFontSize: 12,
51
+ pipeLineValueFontSize: 12,
52
+ waterLabelFontSize: 12,
53
+ })
54
+
55
+ const fullData = ref({
56
+ "isDelete": 0,
57
+ "damCode": "dam_1996484649555202048",
58
+ "updateTime": "2025-12-04 17:19:29",
59
+ "sectionId": 41,
60
+ "projectCodeDesc": "象山水库",
61
+ "sjsw": null,
62
+ "ksw": 47.85,
63
+ "createBy": 1,
64
+ "pointList": [
65
+ {
66
+ "pointCode": "xiangshanup1",
67
+ "isDelete": 0,
68
+ "pointName": "UP1",
69
+ "damCode": "dam_1996484649555202048",
70
+ "updateTime": "2025-12-04 17:19:29",
71
+ "sectionId": 41,
72
+ "createBy": 1,
73
+ "createTime": "2025-12-04 16:16:41",
74
+ "updateBy": 1,
75
+ "x": "-2.5",
76
+ "y": "52.8",
77
+ "id": 77,
78
+ "time": "2025-12-04 19:37:17",
79
+ "value": 44.19,
80
+ "height": "25"
81
+
82
+ },
83
+ {
84
+ "pointCode": "xsUP2",
85
+ "isDelete": 0,
86
+ "pointName": "UP2",
87
+ "damCode": "dam_1996484649555202048",
88
+ "updateTime": "2025-12-04 17:19:29",
89
+ "sectionId": 41,
90
+ "createBy": 1,
91
+ "createTime": "2025-12-04 16:16:41",
92
+ "updateBy": 1,
93
+ "x": "2.5",
94
+ "y": "52.8",
95
+ "id": 78,
96
+ "time": "2025-12-04 19:37:17",
97
+ "value": 41.8,
98
+ "height": "25"
99
+ },
100
+ {
101
+ "pointCode": "xsup3",
102
+ "isDelete": 0,
103
+ "pointName": "UP3",
104
+ "damCode": "dam_1996484649555202048",
105
+ "updateTime": "2025-12-04 17:19:29",
106
+ "sectionId": 41,
107
+ "createBy": 1,
108
+ "createTime": "2025-12-04 16:16:41",
109
+ "updateBy": 1,
110
+ "x": "8",
111
+ "y": "49.5",
112
+ "id": 79,
113
+ "time": "2025-12-04 19:37:17",
114
+ "value": 41.14,
115
+ "height": "22"
116
+ },
117
+ ],
118
+ "cswlValList": [
119
+ {
120
+ "x": -13,
121
+ "y": 21.3413
122
+ },
123
+ {
124
+ "x": -12,
125
+ "y": 21.2529
126
+ },
127
+ {
128
+ "x": -11,
129
+ "y": 21.1582
130
+ },
131
+ {
132
+ "x": -10,
133
+ "y": 21.0537
134
+ },
135
+ {
136
+ "x": -9,
137
+ "y": 20.9615
138
+ },
139
+ {
140
+ "x": -8,
141
+ "y": 20.9049
142
+ },
143
+ {
144
+ "x": -7,
145
+ "y": 20.7928
146
+ },
147
+ {
148
+ "x": -6,
149
+ "y": 20.721
150
+ },
151
+ {
152
+ "x": -5,
153
+ "y": 20.6487
154
+ },
155
+ {
156
+ "x": -4,
157
+ "y": 20.5797
158
+ },
159
+ {
160
+ "x": -3,
161
+ "y": 20.5365
162
+ },
163
+ {
164
+ "x": -2,
165
+ "y": 20.444
166
+ },
167
+ {
168
+ "x": -1,
169
+ "y": 20.3826
170
+ },
171
+ {
172
+ "x": 0,
173
+ "y": 20.3147
174
+ },
175
+ {
176
+ "x": 1,
177
+ "y": 20.2732
178
+ },
179
+ {
180
+ "x": 2,
181
+ "y": 20.2051
182
+ },
183
+ {
184
+ "x": 3,
185
+ "y": 20.1457
186
+ },
187
+ {
188
+ "x": 4,
189
+ "y": 20.1095
190
+ },
191
+ {
192
+ "x": 5,
193
+ "y": 20.0434
194
+ },
195
+ {
196
+ "x": 6,
197
+ "y": 19.9835
198
+ },
199
+ {
200
+ "x": 7,
201
+ "y": 19.9121
202
+ },
203
+ {
204
+ "x": 8,
205
+ "y": 19.8637
206
+ },
207
+ {
208
+ "x": 9,
209
+ "y": 19.7987
210
+ },
211
+ {
212
+ "x": 10,
213
+ "y": 19.7349
214
+ },
215
+ {
216
+ "x": 11,
217
+ "y": 19.6704
218
+ },
219
+ {
220
+ "x": 12,
221
+ "y": 19.6217
222
+ },
223
+ {
224
+ "x": 13,
225
+ "y": 19.5683
226
+ },
227
+ {
228
+ "x": 14,
229
+ "y": 19.4953
230
+ },
231
+ {
232
+ "x": 15,
233
+ "y": 19.4349
234
+ },
235
+ {
236
+ "x": 16,
237
+ "y": 19.3739
238
+ },
239
+ {
240
+ "x": 17,
241
+ "y": 19.3105
242
+ },
243
+ {
244
+ "x": 18,
245
+ "y": 19.2485
246
+ },
247
+ {
248
+ "x": 19,
249
+ "y": 19.1871
250
+ },
251
+ {
252
+ "x": 20,
253
+ "y": 19.1484
254
+ },
255
+ {
256
+ "x": 21,
257
+ "y": 19.0687
258
+ },
259
+ {
260
+ "x": 22,
261
+ "y": 19.0007
262
+ },
263
+ {
264
+ "x": 23,
265
+ "y": 18.9359
266
+ },
267
+ {
268
+ "x": 24,
269
+ "y": 18.8767
270
+ },
271
+ {
272
+ "x": 25,
273
+ "y": 18.8241
274
+ },
275
+ {
276
+ "x": 26,
277
+ "y": 18.7161
278
+ },
279
+ {
280
+ "x": 27,
281
+ "y": 18.6665
282
+ },
283
+ {
284
+ "x": 28,
285
+ "y": 18.6099
286
+ },
287
+ {
288
+ "x": 29,
289
+ "y": 18.5424
290
+ },
291
+ {
292
+ "x": 30,
293
+ "y": 18.4532
294
+ },
295
+ {
296
+ "x": 31,
297
+ "y": 18.3854
298
+ },
299
+ {
300
+ "x": 32,
301
+ "y": 18.3179
302
+ },
303
+ {
304
+ "x": 33,
305
+ "y": 18.2532
306
+ },
307
+ {
308
+ "x": 34,
309
+ "y": 18.1821
310
+ },
311
+ {
312
+ "x": 35,
313
+ "y": 18.1177
314
+ },
315
+ {
316
+ "x": 36,
317
+ "y": 18.0292
318
+ },
319
+ {
320
+ "x": 37,
321
+ "y": 17.9552
322
+ },
323
+ {
324
+ "x": 38,
325
+ "y": 17.8892
326
+ },
327
+ {
328
+ "x": 39,
329
+ "y": 17.7636
330
+ },
331
+ {
332
+ "x": 40,
333
+ "y": 17.6965
334
+ },
335
+ {
336
+ "x": 41,
337
+ "y": 17.6137
338
+ },
339
+ {
340
+ "x": 42,
341
+ "y": 17.5418
342
+ },
343
+ {
344
+ "x": 43,
345
+ "y": 17.4543
346
+ },
347
+ {
348
+ "x": 44,
349
+ "y": 17.3725
350
+ },
351
+ {
352
+ "x": 45,
353
+ "y": 17.2989
354
+ },
355
+ {
356
+ "x": 46,
357
+ "y": 17.2335
358
+ },
359
+ {
360
+ "x": 47,
361
+ "y": 17.1776
362
+ },
363
+ {
364
+ "x": 48,
365
+ "y": 17.0762
366
+ },
367
+ {
368
+ "x": 49,
369
+ "y": 16.9886
370
+ },
371
+ {
372
+ "x": 50,
373
+ "y": 16.911
374
+ },
375
+ {
376
+ "x": 51,
377
+ "y": 16.8367
378
+ },
379
+ {
380
+ "x": 52,
381
+ "y": 16.7509
382
+ },
383
+ {
384
+ "x": 53,
385
+ "y": 16.6716
386
+ },
387
+ {
388
+ "x": 54,
389
+ "y": 16.5844
390
+ },
391
+ {
392
+ "x": 55,
393
+ "y": 16.489
394
+ },
395
+ {
396
+ "x": 56,
397
+ "y": 16.4105
398
+ },
399
+ {
400
+ "x": 57,
401
+ "y": 16.3294
402
+ },
403
+ {
404
+ "x": 58,
405
+ "y": 16.2448
406
+ },
407
+ {
408
+ "x": 59,
409
+ "y": 16.1585
410
+ },
411
+ {
412
+ "x": 60,
413
+ "y": 16.072
414
+ },
415
+ {
416
+ "x": 61,
417
+ "y": 15.9886
418
+ },
419
+ {
420
+ "x": 62,
421
+ "y": 15.8869
422
+ },
423
+ {
424
+ "x": 63,
425
+ "y": 15.8009
426
+ },
427
+ {
428
+ "x": 64,
429
+ "y": 15.706
430
+ },
431
+ {
432
+ "x": 65,
433
+ "y": 15.6213
434
+ },
435
+ {
436
+ "x": 66,
437
+ "y": 15.5156
438
+ },
439
+ {
440
+ "x": 67,
441
+ "y": 15.4094
442
+ },
443
+ {
444
+ "x": 68,
445
+ "y": 15.3139
446
+ },
447
+ {
448
+ "x": 69,
449
+ "y": 15.2122
450
+ },
451
+ {
452
+ "x": 70,
453
+ "y": 15.1049
454
+ },
455
+ ],
456
+ "jhsw": null,
457
+ "createTime": "2025-12-04 16:50:00",
458
+ "updateBy": 1,
459
+ "projectCode": "reservoir_1996484060796555264",
460
+ "x": "0",
461
+ "y": "10",
462
+ "id": 57,
463
+ "sectionList": [
464
+ {
465
+ "createBy": 1,
466
+ "createTime": "2025-12-04 16:50:00",
467
+ "updateBy": 1,
468
+ "isTop": false,
469
+ "isDelete": 0,
470
+ "damCode": "dam_1996484649555202048",
471
+ "x": "-14.24",
472
+ "y": "46",
473
+ "updateTime": "2025-12-04 16:55:54",
474
+ "id": 209,
475
+ "sectionId": 41
476
+ },
477
+ {
478
+ "createBy": 1,
479
+ "createTime": "2025-12-04 16:50:00",
480
+ "updateBy": 1,
481
+ "isTop": false,
482
+ "isDelete": 0,
483
+ "damCode": "dam_1996484649555202048",
484
+ "x": "-7.12",
485
+ "y": "48",
486
+ "updateTime": "2025-12-04 16:56:46",
487
+ "id": 210,
488
+ "sectionId": 41
489
+ },
490
+ {
491
+ "createBy": 1,
492
+ "createTime": "2025-12-04 16:50:00",
493
+ "updateBy": 1,
494
+ "isTop": true,
495
+ "isDelete": 0,
496
+ "damCode": "dam_1996484649555202048",
497
+ "x": "-2.5",
498
+ "y": "52.8",
499
+ "updateTime": "2025-12-04 16:56:47",
500
+ "id": 211,
501
+ "sectionId": 41
502
+ },
503
+ {
504
+ "createBy": 1,
505
+ "createTime": "2025-12-04 16:50:00",
506
+ "updateBy": 1,
507
+ "isTop": true,
508
+ "isDelete": 0,
509
+ "damCode": "dam_1996484649555202048",
510
+ "x": "2.5",
511
+ "y": "52.8",
512
+ "updateTime": "2025-12-04 16:57:18",
513
+ "id": 212,
514
+ "sectionId": 41
515
+ },
516
+ {
517
+ "createBy": 1,
518
+ "createTime": "2025-12-04 16:50:00",
519
+ "updateBy": 1,
520
+ "isTop": false,
521
+ "isDelete": 0,
522
+ "damCode": "dam_1996484649555202048",
523
+ "x": "19",
524
+ "y": "44",
525
+ "updateTime": "2025-12-04 16:57:53",
526
+ "id": 213,
527
+ "sectionId": 41
528
+ },
529
+ {
530
+ "createBy": 1,
531
+ "createTime": "2025-12-04 17:16:46",
532
+ "updateBy": 1,
533
+ "isTop": false,
534
+ "isDelete": 0,
535
+ "damCode": "dam_1996484649555202048",
536
+ "x": "22",
537
+ "y": "44",
538
+ "updateTime": "2025-12-04 16:57:51",
539
+ "id": 214,
540
+ "sectionId": 41
541
+ },
542
+ {
543
+ "createBy": 1,
544
+ "createTime": "2025-12-04 16:50:00",
545
+ "updateBy": 1,
546
+ "isTop": false,
547
+ "isDelete": 0,
548
+ "damCode": "dam_1996484649555202048",
549
+ "x": "42.85",
550
+ "y": "36",
551
+ "updateTime": "2025-12-04 16:55:54",
552
+ "id": 215,
553
+ "sectionId": 41
554
+ },
555
+ {
556
+ "createBy": 1,
557
+ "createTime": "2025-12-04 16:50:00",
558
+ "updateBy": 1,
559
+ "isTop": false,
560
+ "isDelete": 0,
561
+ "damCode": "dam_1996484649555202048",
562
+ "x": "51.45",
563
+ "y": "36",
564
+ "updateTime": "2025-12-04 16:55:54",
565
+ "id": 216,
566
+ "sectionId": 41
567
+ },
568
+ {
569
+ "createBy": 1,
570
+ "createTime": "2025-12-04 16:50:00",
571
+ "updateBy": 1,
572
+ "isTop": false,
573
+ "isDelete": 0,
574
+ "damCode": "dam_1996484649555202048",
575
+ "x": "71.2",
576
+ "y": "30",
577
+ "updateTime": "2025-12-04 16:55:54",
578
+ "id": 217,
579
+ "sectionId": 41
580
+ },
581
+ {
582
+ "createBy": 1,
583
+ "createTime": "2025-12-04 16:50:00",
584
+ "updateBy": 1,
585
+ "isTop": false,
586
+ "isDelete": 0,
587
+ "damCode": "dam_1996484649555202048",
588
+ "x": "78.67",
589
+ "y": "30",
590
+ "updateTime": "2025-12-04 16:55:54",
591
+ "id": 218,
592
+ "sectionId": 41
593
+ }
594
+ ],
595
+ "xxsw": null,
596
+ "isWall": false
597
+ })
598
+
599
+ const canvasRef = ref()
600
+
601
+ // 自定义Canvas功能
602
+ const drawCustomShapes = async () => {
603
+ await nextTick()
604
+ if (!canvasRef.value) return
605
+
606
+ // 获取组件暴露的API
607
+ const {
608
+ getCoordinateSystem,
609
+ convertToCanvasCoordinates,
610
+ getDamData,
611
+ getPipelineData
612
+ } = canvasRef.value
613
+
614
+ const coordinateSystem = getCoordinateSystem()
615
+ const damData = getDamData()
616
+ const pipelineData = getPipelineData()
617
+
618
+ console.log('坐标系信息:', coordinateSystem)
619
+ console.log('大坝数据:', damData)
620
+ console.log('测压管数据:', pipelineData)
621
+
622
+ // 获取自定义canvas元素
623
+ const canvas = document.getElementById('saturation-line-canvas')
624
+ if (!canvas) return
625
+
626
+ const ctx = canvas.getContext('2d')
627
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
628
+
629
+ // 绘制自定义图形
630
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'
631
+ ctx.fillRect(10, 10, 50, 50)
632
+
633
+ // 使用坐标转换函数在特定位置绘制标记
634
+ pipelineData.forEach(pipeline => {
635
+ const { x, y } = pipeline
636
+
637
+ // 在测压管位置绘制红色圆点
638
+ ctx.beginPath()
639
+ ctx.arc(x, y, 5, 0, 2 * Math.PI)
640
+ ctx.fillStyle = 'red'
641
+ ctx.fill()
642
+
643
+ // 添加文字标注
644
+ ctx.fillStyle = 'blue'
645
+ ctx.font = '12px Arial'
646
+ ctx.fillText(pipeline.pointName, x + 10, y - 10)
647
+ })
648
+
649
+ // 在大坝顶点位置绘制绿色标记
650
+ damData.tops.forEach((top, index) => {
651
+ const [realX, realY] = top
652
+ const canvasCoords = convertToCanvasCoordinates(realX, realY)
653
+
654
+ ctx.beginPath()
655
+ ctx.arc(canvasCoords.x, canvasCoords.y, 8, 0, 2 * Math.PI)
656
+ ctx.fillStyle = 'green'
657
+ ctx.fill()
658
+
659
+ ctx.fillStyle = 'green'
660
+ ctx.font = '12px Arial'
661
+ ctx.fillText(`顶点${index + 1}`, canvasCoords.x + 10, canvasCoords.y - 10)
662
+ })
663
+ }
664
+
665
+ const showCoordinateInfo = async () => {
666
+ await nextTick()
667
+ if (!canvasRef.value) return
668
+
669
+ const {
670
+ getCoordinateSystem,
671
+ convertToCanvasCoordinates,
672
+ convertToRealCoordinates
673
+ } = canvasRef.value
674
+
675
+ const coordinateSystem = getCoordinateSystem()
676
+
677
+ // 演示坐标转换
678
+ const realCoords = [10, 20] // 真实坐标
679
+ const canvasCoords = convertToCanvasCoordinates(realCoords[0], realCoords[1])
680
+ const backToReal = convertToRealCoordinates(canvasCoords.x, canvasCoords.y)
681
+
682
+ console.log('坐标转换演示:')
683
+ console.log('真实坐标:', realCoords)
684
+ console.log('转换为画布坐标:', canvasCoords)
685
+ console.log('转换回真实坐标:', backToReal)
686
+
687
+ ElMessageBox.alert(`坐标系信息:\n` +
688
+ `画布尺寸: ${coordinateSystem.stageSize.width}x${coordinateSystem.stageSize.height}\n` +
689
+ `X轴缩放: ${coordinateSystem.xScale.toFixed(4)}\n` +
690
+ `Y轴缩放: ${coordinateSystem.yScale.toFixed(4)}\n` +
691
+ `X轴偏移: ${coordinateSystem.xOffset}\n` +
692
+ `Y轴偏移: ${coordinateSystem.yOffset}`)
693
+ }
694
+
695
+ const addCustomMarkers = async () => {
696
+ await nextTick()
697
+ if (!canvasRef.value) return
698
+
699
+ // 获取组件暴露的API
700
+ const {
701
+ getCoordinateSystem,
702
+ convertToCanvasCoordinates,
703
+ getDamData,
704
+ getPipelineData
705
+ } = canvasRef.value
706
+
707
+ const coordinateSystem = getCoordinateSystem()
708
+ const damData = getDamData()
709
+ const pipelineData = getPipelineData()
710
+
711
+ console.log('添加自定义标记 - 坐标系:', coordinateSystem)
712
+ console.log('添加自定义标记 - 大坝数据:', damData)
713
+ console.log('添加自定义标记 - 测压管数据:', pipelineData)
714
+
715
+ const canvas = document.getElementById('saturation-line-canvas')
716
+ if (!canvas) {
717
+ console.error('未找到自定义canvas元素')
718
+ return
719
+ }
720
+
721
+ const ctx = canvas.getContext('2d')
722
+
723
+ // 清空画布
724
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
725
+
726
+ // 添加一些自定义标记,基于实际数据范围
727
+ const customPoints = [
728
+ { x: -10, y: 30, label: '自定义点1' },
729
+ { x: 0, y: 28, label: '自定义点2' },
730
+ { x: 10, y: 26, label: '自定义点3' },
731
+ { x: 20, y: 24, label: '自定义点4' },
732
+ { x: 30, y: 22, label: '自定义点5' }
733
+ ]
734
+
735
+ console.log('开始绘制自定义标记...')
736
+
737
+ customPoints.forEach((point, index) => {
738
+ try {
739
+ const canvasCoords = convertToCanvasCoordinates(point.x, point.y)
740
+ console.log(`点${index + 1}: 真实坐标(${point.x}, ${point.y}) -> 画布坐标(${canvasCoords.x}, ${canvasCoords.y})`)
741
+
742
+ // 检查坐标是否在画布范围内
743
+ if (canvasCoords.x < 0 || canvasCoords.x > canvas.width ||
744
+ canvasCoords.y < 0 || canvasCoords.y > canvas.height) {
745
+ console.warn(`点${index + 1}超出画布范围: (${canvasCoords.x}, ${canvasCoords.y})`)
746
+ return
747
+ }
748
+
749
+ // 绘制黄色三角形标记
750
+ ctx.beginPath()
751
+ ctx.moveTo(canvasCoords.x, canvasCoords.y - 8)
752
+ ctx.lineTo(canvasCoords.x - 6, canvasCoords.y + 4)
753
+ ctx.lineTo(canvasCoords.x + 6, canvasCoords.y + 4)
754
+ ctx.closePath()
755
+ ctx.fillStyle = 'rgba(255, 255, 0, 0.8)'
756
+ ctx.fill()
757
+ ctx.strokeStyle = 'orange'
758
+ ctx.lineWidth = 2
759
+ ctx.stroke()
760
+
761
+ // 添加文字
762
+ ctx.fillStyle = 'purple'
763
+ ctx.font = '12px Arial'
764
+ ctx.fillText(point.label, canvasCoords.x + 10, canvasCoords.y + 5)
765
+
766
+ console.log(`点${index + 1}绘制完成`)
767
+ } catch (error) {
768
+ console.error(`绘制点${index + 1}时出错:`, error)
769
+ }
770
+ })
771
+
772
+ console.log('自定义标记绘制完成')
773
+
774
+ // 同时在大坝顶点位置添加标记作为参考
775
+ damData.tops.forEach((top, index) => {
776
+ try {
777
+ const [realX, realY] = top
778
+ const canvasCoords = convertToCanvasCoordinates(realX, realY)
779
+
780
+ // 绘制绿色圆点标记
781
+ ctx.beginPath()
782
+ ctx.arc(canvasCoords.x, canvasCoords.y, 6, 0, 2 * Math.PI)
783
+ ctx.fillStyle = 'rgba(0, 255, 0, 0.6)'
784
+ ctx.fill()
785
+ ctx.strokeStyle = 'darkgreen'
786
+ ctx.lineWidth = 1
787
+ ctx.stroke()
788
+
789
+ // 添加文字
790
+ ctx.fillStyle = 'darkgreen'
791
+ ctx.font = '10px Arial'
792
+ ctx.fillText(`坝顶${index + 1}`, canvasCoords.x + 8, canvasCoords.y - 8)
793
+ } catch (error) {
794
+ console.error(`绘制大坝顶点${index + 1}时出错:`, error)
795
+ }
796
+ })
797
+ }
798
+
799
+ // 使用cswlValList数据绘制线条
800
+ const drawCswlValListLine = async () => {
801
+ await nextTick()
802
+ if (!canvasRef.value) return
803
+
804
+ // 获取组件暴露的API
805
+ const {
806
+ getCoordinateSystem,
807
+ convertToCanvasCoordinates
808
+ } = canvasRef.value
809
+
810
+ const coordinateSystem = getCoordinateSystem()
811
+
812
+ console.log('开始绘制cswlValList线条...')
813
+ console.log('cswlValList数据:', fullData.value.cswlValList)
814
+ console.log('坐标系信息:', coordinateSystem)
815
+
816
+ const canvas = document.getElementById('saturation-line-canvas')
817
+ if (!canvas) {
818
+ console.error('未找到自定义canvas元素')
819
+ return
820
+ }
821
+
822
+ // 关键修改:根据Konva画布的尺寸调整自定义canvas
823
+ const konvaWidth = coordinateSystem.stageSize.width
824
+ const konvaHeight = coordinateSystem.stageSize.height
825
+
826
+ // 设置自定义canvas尺寸与Konva画布一致
827
+ canvas.width = konvaWidth
828
+ canvas.height = konvaHeight
829
+
830
+ const ctx = canvas.getContext('2d')
831
+
832
+ // 清空画布
833
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
834
+
835
+ // 检查是否有cswlValList数据
836
+ if (!fullData.value.cswlValList || fullData.value.cswlValList.length === 0) {
837
+ console.warn('没有cswlValList数据可绘制')
838
+ return
839
+ }
840
+
841
+ console.log(`自定义Canvas尺寸: ${canvas.width}x${canvas.height}`)
842
+ console.log(`Konva画布尺寸: ${konvaWidth}x${konvaHeight}`)
843
+
844
+ // 开始绘制线条
845
+ ctx.beginPath()
846
+
847
+ // 设置线条样式
848
+ ctx.strokeStyle = '#ff6b6b'
849
+ ctx.lineWidth = 3
850
+ ctx.lineJoin = 'round'
851
+ ctx.lineCap = 'round'
852
+
853
+ // 绘制第一个点
854
+ const firstPoint = fullData.value.cswlValList[0]
855
+ const firstCanvasCoords = convertToCanvasCoordinates(firstPoint.x, firstPoint.y)
856
+ ctx.moveTo(firstCanvasCoords.x, firstCanvasCoords.y)
857
+
858
+ console.log(`开始点: 真实坐标(${firstPoint.x}, ${firstPoint.y}) -> 画布坐标(${firstCanvasCoords.x}, ${firstCanvasCoords.y})`)
859
+
860
+ // 绘制后续点
861
+ fullData.value.cswlValList.forEach((point, index) => {
862
+ try {
863
+ const canvasCoords = convertToCanvasCoordinates(point.x, point.y)
864
+
865
+ // 检查坐标是否在画布范围内
866
+ if (canvasCoords.x < 0 || canvasCoords.x > canvas.width ||
867
+ canvasCoords.y < 0 || canvasCoords.y > canvas.height) {
868
+ console.warn(`点${index + 1}超出画布范围: (${canvasCoords.x}, ${canvasCoords.y})`)
869
+ return
870
+ }
871
+
872
+ ctx.lineTo(canvasCoords.x, canvasCoords.y)
873
+ console.log(`点${index + 1}: 真实坐标(${point.x}, ${point.y}) -> 画布坐标(${canvasCoords.x}, ${canvasCoords.y})`)
874
+
875
+ } catch (error) {
876
+ console.error(`处理点${index + 1}时出错:`, error)
877
+ }
878
+ })
879
+
880
+ // 描边线条
881
+ ctx.stroke()
882
+
883
+ // 在线条下方添加半透明填充
884
+ ctx.beginPath()
885
+
886
+ // 绘制第一个点
887
+ const firstPointFill = fullData.value.cswlValList[0]
888
+ const firstCanvasCoordsFill = convertToCanvasCoordinates(firstPointFill.x, firstPointFill.y)
889
+ ctx.moveTo(firstCanvasCoordsFill.x, firstCanvasCoordsFill.y)
890
+
891
+ // 绘制后续点
892
+ fullData.value.cswlValList.forEach((point, index) => {
893
+ try {
894
+ const canvasCoords = convertToCanvasCoordinates(point.x, point.y)
895
+ if (canvasCoords.x >= 0 && canvasCoords.x <= canvas.width &&
896
+ canvasCoords.y >= 0 && canvasCoords.y <= canvas.height) {
897
+ ctx.lineTo(canvasCoords.x, canvasCoords.y)
898
+ }
899
+ } catch (error) {
900
+ console.error(`填充处理点${index + 1}时出错:`, error)
901
+ }
902
+ })
903
+
904
+ // 闭合路径并填充
905
+ const lastPoint = fullData.value.cswlValList[fullData.value.cswlValList.length - 1]
906
+ const lastCanvasCoords = convertToCanvasCoordinates(lastPoint.x, lastPoint.y)
907
+ ctx.lineTo(lastCanvasCoords.x, canvas.height)
908
+ ctx.lineTo(firstCanvasCoordsFill.x, canvas.height)
909
+ ctx.closePath()
910
+
911
+ // 创建渐变填充
912
+ const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height)
913
+ gradient.addColorStop(0, 'rgba(255, 107, 107, 0.3)')
914
+ gradient.addColorStop(1, 'rgba(255, 107, 107, 0.1)')
915
+ ctx.fillStyle = gradient
916
+ ctx.fill()
917
+
918
+ // 在关键点添加标记
919
+ fullData.value.cswlValList.forEach((point, index) => {
920
+ if (index % 10 === 0) { // 每10个点添加一个标记
921
+ try {
922
+ const canvasCoords = convertToCanvasCoordinates(point.x, point.y)
923
+
924
+ // 检查坐标是否在画布范围内
925
+ if (canvasCoords.x >= 0 && canvasCoords.x <= canvas.width &&
926
+ canvasCoords.y >= 0 && canvasCoords.y <= canvas.height) {
927
+
928
+ // 绘制蓝色圆点标记
929
+ ctx.beginPath()
930
+ ctx.arc(canvasCoords.x, canvasCoords.y, 4, 0, 2 * Math.PI)
931
+ ctx.fillStyle = '#4ecdc4'
932
+ ctx.fill()
933
+ ctx.strokeStyle = '#2c3e50'
934
+ ctx.lineWidth = 1
935
+ ctx.stroke()
936
+
937
+ // 添加坐标文字
938
+ ctx.fillStyle = '#2c3e50'
939
+ ctx.font = '10px Arial'
940
+ ctx.fillText(`(${point.x}, ${point.y.toFixed(1)})`, canvasCoords.x + 8, canvasCoords.y - 8)
941
+ }
942
+ } catch (error) {
943
+ console.error(`添加标记点${index + 1}时出错:`, error)
944
+ }
945
+ }
946
+ })
947
+
948
+ console.log('cswlValList线条绘制完成')
949
+ }
950
+
951
+ const state = reactive({
952
+ damData: {
953
+ // 坝体
954
+ sectionTableList: [
955
+ {
956
+ xPoint: "-44",
957
+ yPoint: "17",
958
+ isTop: false,
959
+ },
960
+ {
961
+ xPoint: "-26",
962
+ yPoint: "24",
963
+ isTop: false,
964
+ },
965
+ {
966
+ xPoint: "-16",
967
+ yPoint: "24",
968
+ isTop: false,
969
+ },
970
+ {
971
+ xPoint: "-8",
972
+ yPoint: "29",
973
+ isTop: true,
974
+ },
975
+ {
976
+ xPoint: "8",
977
+ yPoint: "29",
978
+ isTop: true,
979
+ },
980
+ {
981
+ xPoint: "22",
982
+ yPoint: "25",
983
+ isTop: false,
984
+ },
985
+ {
986
+ xPoint: "40",
987
+ yPoint: "22",
988
+ isTop: false,
989
+ },
990
+ {
991
+ xPoint: "47",
992
+ yPoint: "22",
993
+ isTop: false,
994
+ },
995
+ {
996
+ xPoint: "62",
997
+ yPoint: "17",
998
+ isTop: false,
999
+ },
1000
+ {
1001
+ xPoint: "70",
1002
+ yPoint: "17",
1003
+ isTop: false,
1004
+ },
1005
+ ],
1006
+ // 测压管
1007
+ pipelineTableList: [
1008
+ {
1009
+ xPoint: "-8",
1010
+ yPoint: "29",
1011
+ height: "15",
1012
+ pointCode: "UP1-1",
1013
+ pointName: "测试名字很长很长很长很长测试名字很长很长很长很长",
1014
+ },
1015
+ {
1016
+ xPoint: "8",
1017
+ yPoint: "29",
1018
+ height: "17",
1019
+ pointCode: "UP1-2",
1020
+ pointName: "-1-1-1--1-1----1",
1021
+ },
1022
+ {
1023
+ xPoint: "17",
1024
+ yPoint: "26.3",
1025
+ height: "15",
1026
+ pointCode: "UP1-3",
1027
+ pointName: "测试",
1028
+ },
1029
+ ],
1030
+ // y/x偏移
1031
+ isWall: "1",
1032
+ yStart: "10",
1033
+ wallXpoint: "-2",
1034
+ },
1035
+ waterLevel: {
1036
+ map: [
1037
+ {
1038
+ id: null,
1039
+ projectCode: null,
1040
+ transectName: "0+155",
1041
+ pointCode: "UP1-3",
1042
+ waterLevel: 14.8,
1043
+ date: "2025-05-20T05:00:00",
1044
+ createBy: null,
1045
+ createTime: null,
1046
+ updateBy: null,
1047
+ updateTime: null,
1048
+ isDelete: null,
1049
+ code: null,
1050
+ },
1051
+ {
1052
+ id: null,
1053
+ projectCode: null,
1054
+ transectName: "0+155",
1055
+ pointCode: "UP1-2",
1056
+ waterLevel: 16.0,
1057
+ date: "2025-05-20T05:00:00",
1058
+ createBy: null,
1059
+ createTime: null,
1060
+ updateBy: null,
1061
+ updateTime: null,
1062
+ isDelete: null,
1063
+ code: null,
1064
+ },
1065
+ {
1066
+ id: null,
1067
+ projectCode: null,
1068
+ transectName: "0+155",
1069
+ pointCode: "UP1-1",
1070
+ waterLevel: 18.3,
1071
+ date: "2025-05-20T00:00:00",
1072
+ createBy: null,
1073
+ createTime: null,
1074
+ updateBy: null,
1075
+ updateTime: null,
1076
+ isDelete: null,
1077
+ code: null,
1078
+ },
1079
+ ],
1080
+ kssw: 22,
1081
+ xxsw: 15,
1082
+ sjsw: 24,
1083
+ jhsw: 26,
1084
+ },
1085
+ });
1086
+
1087
+ onMounted(()=>{
1088
+ return
1089
+ setTimeout(()=>{
1090
+ // 方案2修改数据
1091
+ /* state.damData = {}
1092
+ state.waterLevel = {}
1093
+ return */
1094
+ // 方案1修改数据
1095
+ fullData.value = {
1096
+ "isDelete": 0,
1097
+ "damCode": "dam_1996484649555202048",
1098
+ "updateTime": "2025-12-04 17:19:29",
1099
+ "sectionId": 41,
1100
+ "projectCodeDesc": "象山水库",
1101
+ "sjsw": null,
1102
+ "ksw": 47.85,
1103
+ "createBy": 1,
1104
+ "pointList": [
1105
+ {
1106
+ "pointCode": "xsUP2",
1107
+ "isDelete": 0,
1108
+ "pointName": "UP2",
1109
+ "damCode": "dam_1996484649555202048",
1110
+ "updateTime": "2025-12-04 17:19:29",
1111
+ "sectionId": 41,
1112
+ "createBy": 1,
1113
+ "createTime": "2025-12-04 16:16:41",
1114
+ "updateBy": 1,
1115
+ "x": "2.5",
1116
+ "y": "52.8",
1117
+ "id": 78,
1118
+ "time": "2025-12-04 19:37:17",
1119
+ "value": 41.8,
1120
+ "height": "25",
1121
+ "xPoint": "2.5",
1122
+ "yPoint": "52.8"
1123
+ },
1124
+ {
1125
+ "pointCode": "xsup3",
1126
+ "isDelete": 0,
1127
+ "pointName": "UP3",
1128
+ "damCode": "dam_1996484649555202048",
1129
+ "updateTime": "2025-12-04 17:19:29",
1130
+ "sectionId": 41,
1131
+ "createBy": 1,
1132
+ "createTime": "2025-12-04 16:16:41",
1133
+ "updateBy": 1,
1134
+ "x": "8",
1135
+ "y": "49.5",
1136
+ "id": 79,
1137
+ "time": "2025-12-04 19:37:17",
1138
+ "value": 25.14,
1139
+ "height": "22",
1140
+ "xPoint": "8",
1141
+ "yPoint": "49.5"
1142
+ },
1143
+ {
1144
+ "pointCode": "xiangshanup1",
1145
+ "isDelete": 0,
1146
+ "pointName": "UP1",
1147
+ "damCode": "dam_1996484649555202048",
1148
+ "updateTime": "2025-12-04 17:19:29",
1149
+ "sectionId": 41,
1150
+ "createBy": 1,
1151
+ "createTime": "2025-12-04 16:16:41",
1152
+ "updateBy": 1,
1153
+ "x": "-2.5",
1154
+ "y": "52.8",
1155
+ "id": 77,
1156
+ "time": "2025-12-04 19:37:17",
1157
+ "value": 35.19,
1158
+ "height": "25",
1159
+ "xPoint": "-2.5",
1160
+ "yPoint": "52.8"
1161
+ }
1162
+ ],
1163
+ "jhsw": null,
1164
+ "createTime": "2025-12-04 16:50:00",
1165
+ "updateBy": 1,
1166
+ "projectCode": "reservoir_1996484060796555264",
1167
+ "x": "0",
1168
+ "y": "20",
1169
+ "id": 57,
1170
+ "sectionList": [
1171
+ {
1172
+ "createBy": 1,
1173
+ "createTime": "2025-12-04 16:50:00",
1174
+ "updateBy": 1,
1175
+ "isTop": false,
1176
+ "isDelete": 0,
1177
+ "damCode": "dam_1996484649555202048",
1178
+ "x": "-14.24",
1179
+ "y": "46",
1180
+ "updateTime": "2025-12-04 16:55:54",
1181
+ "id": 209,
1182
+ "sectionId": 41
1183
+ },
1184
+ {
1185
+ "createBy": 1,
1186
+ "createTime": "2025-12-04 16:50:00",
1187
+ "updateBy": 1,
1188
+ "isTop": false,
1189
+ "isDelete": 0,
1190
+ "damCode": "dam_1996484649555202048",
1191
+ "x": "-7.12",
1192
+ "y": "48",
1193
+ "updateTime": "2025-12-04 16:56:46",
1194
+ "id": 210,
1195
+ "sectionId": 41
1196
+ },
1197
+ {
1198
+ "createBy": 1,
1199
+ "createTime": "2025-12-04 16:50:00",
1200
+ "updateBy": 1,
1201
+ "isTop": true,
1202
+ "isDelete": 0,
1203
+ "damCode": "dam_1996484649555202048",
1204
+ "x": "-2.5",
1205
+ "y": "52.8",
1206
+ "updateTime": "2025-12-04 16:56:47",
1207
+ "id": 211,
1208
+ "sectionId": 41
1209
+ },
1210
+ {
1211
+ "createBy": 1,
1212
+ "createTime": "2025-12-04 16:50:00",
1213
+ "updateBy": 1,
1214
+ "isTop": true,
1215
+ "isDelete": 0,
1216
+ "damCode": "dam_1996484649555202048",
1217
+ "x": "2.5",
1218
+ "y": "52.8",
1219
+ "updateTime": "2025-12-04 16:57:18",
1220
+ "id": 212,
1221
+ "sectionId": 41
1222
+ },
1223
+ {
1224
+ "createBy": 1,
1225
+ "createTime": "2025-12-04 16:50:00",
1226
+ "updateBy": 1,
1227
+ "isTop": false,
1228
+ "isDelete": 0,
1229
+ "damCode": "dam_1996484649555202048",
1230
+ "x": "19",
1231
+ "y": "44",
1232
+ "updateTime": "2025-12-04 16:57:53",
1233
+ "id": 213,
1234
+ "sectionId": 41
1235
+ },
1236
+ {
1237
+ "createBy": 1,
1238
+ "createTime": "2025-12-04 17:16:46",
1239
+ "updateBy": 1,
1240
+ "isTop": false,
1241
+ "isDelete": 0,
1242
+ "damCode": "dam_1996484649555202048",
1243
+ "x": "22",
1244
+ "y": "44",
1245
+ "updateTime": "2025-12-04 16:57:51",
1246
+ "id": 214,
1247
+ "sectionId": 41
1248
+ },
1249
+ {
1250
+ "createBy": 1,
1251
+ "createTime": "2025-12-04 16:50:00",
1252
+ "updateBy": 1,
1253
+ "isTop": false,
1254
+ "isDelete": 0,
1255
+ "damCode": "dam_1996484649555202048",
1256
+ "x": "42.85",
1257
+ "y": "36",
1258
+ "updateTime": "2025-12-04 16:55:54",
1259
+ "id": 215,
1260
+ "sectionId": 41
1261
+ },
1262
+ {
1263
+ "createBy": 1,
1264
+ "createTime": "2025-12-04 16:50:00",
1265
+ "updateBy": 1,
1266
+ "isTop": false,
1267
+ "isDelete": 0,
1268
+ "damCode": "dam_1996484649555202048",
1269
+ "x": "51.45",
1270
+ "y": "36",
1271
+ "updateTime": "2025-12-04 16:55:54",
1272
+ "id": 216,
1273
+ "sectionId": 41
1274
+ },
1275
+ {
1276
+ "createBy": 1,
1277
+ "createTime": "2025-12-04 16:50:00",
1278
+ "updateBy": 1,
1279
+ "isTop": false,
1280
+ "isDelete": 0,
1281
+ "damCode": "dam_1996484649555202048",
1282
+ "x": "71.2",
1283
+ "y": "30",
1284
+ "updateTime": "2025-12-04 16:55:54",
1285
+ "id": 217,
1286
+ "sectionId": 41
1287
+ },
1288
+ {
1289
+ "createBy": 1,
1290
+ "createTime": "2025-12-04 16:50:00",
1291
+ "updateBy": 1,
1292
+ "isTop": false,
1293
+ "isDelete": 0,
1294
+ "damCode": "dam_1996484649555202048",
1295
+ "x": "78.67",
1296
+ "y": "30",
1297
+ "updateTime": "2025-12-04 16:55:54",
1298
+ "id": 218,
1299
+ "sectionId": 41
1300
+ }
1301
+ ],
1302
+ "xxsw": null,
1303
+ "isWall": false
1304
+ }
1305
+ }, 2000)
1306
+ })
1307
+
1308
+ </script>
1309
+ <style lang="scss" scoped>
1310
+ .saturation-line-view {
1311
+ width: calc(100% - 40px);
1312
+ height: calc(100% - 20px);
1313
+ padding: 20px;
1314
+ display: flex;
1315
+ flex-direction: column;
1316
+ gap: 20px;
1317
+
1318
+ .saturationline-canvas {
1319
+ flex: 1;
1320
+ height: 60%;
1321
+ border: 1px solid #ddd;
1322
+ border-radius: 4px;
1323
+ position: relative;
1324
+
1325
+ canvas {
1326
+ position: absolute;
1327
+ top: 0;
1328
+ left: 0;
1329
+ pointer-events: auto;
1330
+ z-index: 10;
1331
+ }
1332
+ }
1333
+
1334
+ .custom-canvas-controls {
1335
+ background: #f5f5f5;
1336
+ padding: 20px;
1337
+ border-radius: 8px;
1338
+ border: 1px solid #ddd;
1339
+
1340
+ h3 {
1341
+ margin: 0 0 15px 0;
1342
+ color: #333;
1343
+ }
1344
+
1345
+ button {
1346
+ margin-right: 10px;
1347
+ padding: 8px 16px;
1348
+ background: #007bff;
1349
+ color: white;
1350
+ border: none;
1351
+ border-radius: 4px;
1352
+ cursor: pointer;
1353
+ font-size: 14px;
1354
+ transition: background-color 0.3s;
1355
+
1356
+ &:hover {
1357
+ background: #0056b3;
1358
+ }
1359
+
1360
+ &:active {
1361
+ transform: translateY(1px);
1362
+ }
1363
+ }
1364
+ }
1365
+ }
1366
+ </style>