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