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.
- package/dist/ComponentDemo/FormDemo.vue +1 -118
- package/dist/ComponentDemo/MDDemo.vue +245 -18
- package/dist/ComponentDemo/ReadMe.vue +25 -0
- package/dist/ComponentDemo/SaturationLineDemo copy 2.vue +1516 -0
- package/dist/ComponentDemo/SaturationLineDemo copy 3.vue +1546 -0
- package/dist/ComponentDemo/SaturationLineDemo copy 4.vue +1557 -0
- package/dist/ComponentDemo/SaturationLineDemo copy.vue +1366 -0
- package/dist/ComponentDemo/SaturationLineDemo.vue +576 -4
- package/dist/matrix-components.d.ts +2 -0
- package/dist/matrix_components.css +1 -1
- package/dist/matrix_components.js +93 -18
- package/dist/matrix_components.umd.cjs +1 -1
- package/package.json +2 -1
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="saturation-line-view">
|
|
3
|
-
<span
|
|
3
|
+
<span>浸润线 - 自定义Canvas演示</span>
|
|
4
4
|
<!-- 方案1(推荐,支持sort按照x坐标从小到大排序):fullData -->
|
|
5
|
-
<NsSaturationline ref="canvasRef" class="saturationline-canvas" :fullData="fullData" :isSortX="true">
|
|
5
|
+
<NsSaturationline ref="canvasRef" class="saturationline-canvas" :fullData="fullData" :isSortX="true" :config="config">
|
|
6
6
|
<span>无数据</span>
|
|
7
|
+
<template #custom-canvas>
|
|
8
|
+
<canvas id="saturation-line-canvas" width="800" height="400"></canvas>
|
|
9
|
+
</template>
|
|
7
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>
|
|
8
21
|
<!-- 方案2(兼容老的调用方式) -->
|
|
9
22
|
<!-- <NsSaturationline ref="canvasRef" class="saturationline-canvas" :data="state.damData" :waterLevel="state.waterLevel">
|
|
10
23
|
<span>无数据</span>
|
|
@@ -12,7 +25,33 @@
|
|
|
12
25
|
</div>
|
|
13
26
|
</template>
|
|
14
27
|
<script setup lang="ts" name="">
|
|
15
|
-
import {
|
|
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
|
+
})
|
|
16
55
|
|
|
17
56
|
const fullData = ref({
|
|
18
57
|
"isDelete": 0,
|
|
@@ -558,6 +597,493 @@ const fullData = ref({
|
|
|
558
597
|
"isWall": false
|
|
559
598
|
})
|
|
560
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
|
+
// 计算角度差,确保显示最短的圆弧路径
|
|
1053
|
+
let angleDiff = endAngle - startAngle
|
|
1054
|
+
let drawStartAngle = startAngle
|
|
1055
|
+
let drawEndAngle = endAngle
|
|
1056
|
+
|
|
1057
|
+
// 如果角度差大于π,则反向绘制以显示较短的圆弧
|
|
1058
|
+
if (Math.abs(angleDiff) > Math.PI) {
|
|
1059
|
+
if (angleDiff > 0) {
|
|
1060
|
+
drawStartAngle = endAngle
|
|
1061
|
+
drawEndAngle = startAngle
|
|
1062
|
+
}
|
|
1063
|
+
} else if (angleDiff < 0) {
|
|
1064
|
+
// 确保顺时针绘制
|
|
1065
|
+
drawStartAngle = endAngle
|
|
1066
|
+
drawEndAngle = startAngle
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
console.log('绘制起始角度:', drawStartAngle * 180 / Math.PI, '(度)')
|
|
1070
|
+
console.log('绘制结束角度:', drawEndAngle * 180 / Math.PI, '(度)')
|
|
1071
|
+
|
|
1072
|
+
// 绘制起点到终点之间的圆弧(实线,突出显示)
|
|
1073
|
+
ctx.beginPath()
|
|
1074
|
+
ctx.arc(
|
|
1075
|
+
centerCanvasCoords.x,
|
|
1076
|
+
centerCanvasCoords.y,
|
|
1077
|
+
canvasRadius,
|
|
1078
|
+
drawStartAngle,
|
|
1079
|
+
drawEndAngle,
|
|
1080
|
+
false // 顺时针方向
|
|
1081
|
+
)
|
|
1082
|
+
ctx.strokeStyle = '#FF6B6B'
|
|
1083
|
+
ctx.lineWidth = 2
|
|
1084
|
+
ctx.stroke()
|
|
1085
|
+
}
|
|
1086
|
+
|
|
561
1087
|
const state = reactive({
|
|
562
1088
|
damData: {
|
|
563
1089
|
// 坝体
|
|
@@ -695,6 +1221,7 @@ const state = reactive({
|
|
|
695
1221
|
});
|
|
696
1222
|
|
|
697
1223
|
onMounted(()=>{
|
|
1224
|
+
return
|
|
698
1225
|
setTimeout(()=>{
|
|
699
1226
|
// 方案2修改数据
|
|
700
1227
|
/* state.damData = {}
|
|
@@ -922,9 +1449,54 @@ onMounted(()=>{
|
|
|
922
1449
|
padding: 20px;
|
|
923
1450
|
display: flex;
|
|
924
1451
|
flex-direction: column;
|
|
1452
|
+
gap: 20px;
|
|
1453
|
+
|
|
925
1454
|
.saturationline-canvas {
|
|
926
1455
|
flex: 1;
|
|
927
|
-
height:
|
|
1456
|
+
height: 60%;
|
|
1457
|
+
border: 1px solid #ddd;
|
|
1458
|
+
border-radius: 4px;
|
|
1459
|
+
position: relative;
|
|
1460
|
+
|
|
1461
|
+
canvas {
|
|
1462
|
+
position: absolute;
|
|
1463
|
+
top: 0;
|
|
1464
|
+
left: 0;
|
|
1465
|
+
pointer-events: auto;
|
|
1466
|
+
z-index: 10;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
.custom-canvas-controls {
|
|
1471
|
+
background: #f5f5f5;
|
|
1472
|
+
padding: 20px;
|
|
1473
|
+
border-radius: 8px;
|
|
1474
|
+
border: 1px solid #ddd;
|
|
1475
|
+
|
|
1476
|
+
h3 {
|
|
1477
|
+
margin: 0 0 15px 0;
|
|
1478
|
+
color: #333;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
button {
|
|
1482
|
+
margin-right: 10px;
|
|
1483
|
+
padding: 8px 16px;
|
|
1484
|
+
background: #007bff;
|
|
1485
|
+
color: white;
|
|
1486
|
+
border: none;
|
|
1487
|
+
border-radius: 4px;
|
|
1488
|
+
cursor: pointer;
|
|
1489
|
+
font-size: 14px;
|
|
1490
|
+
transition: background-color 0.3s;
|
|
1491
|
+
|
|
1492
|
+
&:hover {
|
|
1493
|
+
background: #0056b3;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
&:active {
|
|
1497
|
+
transform: translateY(1px);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
928
1500
|
}
|
|
929
1501
|
}
|
|
930
1502
|
</style>
|
|
@@ -96,6 +96,7 @@ declare module 'matrix_components' {
|
|
|
96
96
|
NsOffice: any
|
|
97
97
|
NsForm: any
|
|
98
98
|
NsFormTitle: any
|
|
99
|
+
NsSaturationLine: any
|
|
99
100
|
NsSaturationline: any
|
|
100
101
|
NsImage: any
|
|
101
102
|
NsImg: any
|
|
@@ -201,6 +202,7 @@ declare module 'matrix_components' {
|
|
|
201
202
|
NsOffice,
|
|
202
203
|
NsForm,
|
|
203
204
|
NsFormTitle,
|
|
205
|
+
NsSaturationLine,
|
|
204
206
|
NsSaturationline,
|
|
205
207
|
NsImage,
|
|
206
208
|
NsImg,
|