feat: 实现2D图表鼠标移动时右侧四个图表跟着动,实现2D图表右侧的控制颜色按钮,实现右侧四个图表的鼠标移动时显示竖线功能
This commit is contained in:
		
							parent
							
								
									e1a2e89c2b
								
							
						
					
					
						commit
						22fa4c54b2
					
				|  | @ -20,10 +20,27 @@ export default { | |||
|   mounted() { | ||||
|     this.chart = echarts.init(this.$refs.containerRef) | ||||
|     this.chart.setOption(this.option) | ||||
|     this.initEventListener() | ||||
|   }, | ||||
|   methods: { | ||||
|     initEventListener() { | ||||
|       const zr = this.getZRender() | ||||
|       zr.on('mousemove', (params) => { | ||||
|         this.$emit('zr:mousemove', params) | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     resize() { | ||||
|       this.chart && this.chart.resize() | ||||
|     }, | ||||
| 
 | ||||
|     // 获取echart实例 | ||||
|     getChartInstance() { | ||||
|       return this.chart | ||||
|     }, | ||||
| 
 | ||||
|     getZRender() { | ||||
|       return this.chart.getZr() | ||||
|     } | ||||
|   }, | ||||
|   watch : { | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/utils/chartHelper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/utils/chartHelper.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| /** | ||||
|  * 根据位置获取这个点在图表的哪个轴线上 | ||||
|  * @param offsetX | ||||
|  * @param offsetY | ||||
|  */ | ||||
| export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex = 0) { | ||||
|     const pointInPixel = [offsetX, offsetY] | ||||
|     if ( | ||||
|         chart.containPixel( | ||||
|             { | ||||
|                 seriesIndex: 0 | ||||
|             }, | ||||
|             pointInPixel | ||||
|         ) | ||||
|     ) { | ||||
|         const [xAxis, yAxis] = chart.convertFromPixel({ seriesIndex }, pointInPixel) | ||||
|         return [xAxis, yAxis] | ||||
|     } | ||||
|     return null | ||||
| } | ||||
|  | @ -5,7 +5,7 @@ | |||
|         <template slot="title"> | ||||
|           Beta-Gamma Spectrum: Sample | ||||
|         </template> | ||||
|         <beta-gamma-spectrum-chart ref="scatterChartRef" /> | ||||
|         <beta-gamma-spectrum-chart ref="betaGammaChartRef" :data="twoDData" @positionChange="handlePositionChange" /> | ||||
|       </beta-gamma-chart-container> | ||||
|     </div> | ||||
|     <div class="beta-and-gamma-spectrum"> | ||||
|  | @ -64,6 +64,9 @@ import BetaGammaChartContainer from './components/BetaGammaChartContainer.vue' | |||
| import BetaGammaSpectrumChart from './components/BetaGammaSpectrumChart.vue' | ||||
| import ResultDisplay from './components/ResultDisplay.vue' | ||||
| import SpectrumLineChart from './components/SpectrumLineChart.vue' | ||||
| 
 | ||||
| import twoDData from './data.json' | ||||
| 
 | ||||
| export default { | ||||
|   components: { BetaGammaChartContainer, SpectrumLineChart, ResultDisplay, BetaGammaSpectrumChart }, | ||||
|   data() { | ||||
|  | @ -97,16 +100,36 @@ export default { | |||
|           uncertainty: '+/-0.01988', | ||||
|           mdc: '0.03464' | ||||
|         } | ||||
|       ] | ||||
|       ], | ||||
|       twoDData: {} | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.getData() | ||||
|   }, | ||||
|   methods: { | ||||
|     resize() { | ||||
|       this.$refs.scatterChartRef && this.$refs.scatterChartRef.resize() | ||||
|       this.$refs.betaGammaChartRef && this.$refs.betaGammaChartRef.resize() | ||||
|       this.$refs.lineChart1Ref && this.$refs.lineChart1Ref.resize() | ||||
|       this.$refs.lineChart2Ref && this.$refs.lineChart2Ref.resize() | ||||
|       this.$refs.lineChart3Ref && this.$refs.lineChart3Ref.resize() | ||||
|       this.$refs.lineChart4Ref && this.$refs.lineChart4Ref.resize() | ||||
|     }, | ||||
| 
 | ||||
|     async getData() { | ||||
|       await 0 | ||||
|       this.twoDData = twoDData | ||||
|     }, | ||||
| 
 | ||||
|     // 鼠标在左侧2d图表上移动时 | ||||
|     handlePositionChange([xAxis, yAxis]) { | ||||
|       // Gamma Spectrum,根据bata-gamma的gamma channel的值(y轴)进行定位 | ||||
|       this.$refs.lineChart1Ref.setLinePosition(yAxis) | ||||
|       this.$refs.lineChart2Ref.setLinePosition(yAxis) | ||||
| 
 | ||||
|       // Beta Spectrum,根据bata-gamma的bata channel的值(x轴)进行定位 | ||||
|       this.$refs.lineChart3Ref.setLinePosition(xAxis) | ||||
|       this.$refs.lineChart4Ref.setLinePosition(xAxis) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -6,15 +6,18 @@ | |||
|         :key="item" | ||||
|         :class="active == index ? 'active' : ''" | ||||
|         @click="handleChange(index)" | ||||
|         >{{ item }}</span | ||||
|       > | ||||
|         {{ item }} | ||||
|       </span> | ||||
|       <span @click="handleUnzoom">Unzoom</span> | ||||
|     </div> | ||||
|     <div class="beta-gamma-spectrum-chart-main"> | ||||
|       <!-- 2D 图表 --> | ||||
|       <div class="_2d-chart" v-if="active == 0"> | ||||
|         <custom-chart ref="chartRef" :option="twoDOption" /> | ||||
|         <custom-chart ref="chartRef" :option="twoDOption" @zr:mousemove="handleMouseMove" /> | ||||
|         <div class="bar"> | ||||
|           <div>256</div> | ||||
|           <color-palette v-model="currCount" :maxValue="4" /> | ||||
|           <div>{{ currCount + 1 }}</div> | ||||
|           <div class="bar-main"></div> | ||||
|           <div>0</div> | ||||
|         </div> | ||||
|  | @ -34,7 +37,10 @@ | |||
| <script> | ||||
| import CustomChart from '@/components/CustomChart/index.vue' | ||||
| import Custom3DChart from '@/components/Custom3DChart/index.vue' | ||||
| const buttons = ['2D', '3D Surface', '3D Scatter', 'Unzoom'] | ||||
| import ColorPalette from './ColorPalette.vue' | ||||
| import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js' | ||||
| 
 | ||||
| const buttons = ['2D', '3D Surface', '3D Scatter'] | ||||
| 
 | ||||
| // 2D 配置 | ||||
| const twoDOption = { | ||||
|  | @ -45,8 +51,11 @@ const twoDOption = { | |||
|     bottom: 45 | ||||
|   }, | ||||
|   tooltip: { | ||||
|     trigger: 'axis', | ||||
|     showContent: false, | ||||
|     trigger: 'item', | ||||
|     formatter: params => { | ||||
|       const [b, g, c] = params.value | ||||
|       return `Beta: ${b}<br>Gamma: ${g}<br>Count: ${c}` | ||||
|     }, | ||||
|     axisPointer: { | ||||
|       animation: false, | ||||
|       type: 'cross', | ||||
|  | @ -105,21 +114,16 @@ const twoDOption = { | |||
|     max: 256, | ||||
|     interval: 64 | ||||
|   }, | ||||
|   series: [ | ||||
|     { | ||||
|       xAxisIndex: 0, | ||||
|       yAxisIndex: 0, | ||||
|       type: 'scatter', | ||||
|       symbolSize: 2.5, | ||||
|       itemStyle: { | ||||
|         color: '#fff' | ||||
|       }, | ||||
|       data: new Array(1256).fill(0).map(() => [parseInt(Math.random() * 256), parseInt(Math.random() * 256)]) | ||||
|     }, | ||||
|     { | ||||
|       type: 'line' | ||||
|   series: { | ||||
|     xAxisIndex: 0, | ||||
|     yAxisIndex: 0, | ||||
|     type: 'scatter', | ||||
|     symbolSize: 5, | ||||
|     data: [], | ||||
|     itemStyle: { | ||||
|       color: '#fff' | ||||
|     } | ||||
|   ] | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| //3D Surface 配置 | ||||
|  | @ -255,28 +259,93 @@ const threeDScatterOption = { | |||
| } | ||||
| 
 | ||||
| export default { | ||||
|   props: { | ||||
|     data: { | ||||
|       type: Object, | ||||
|       default: () => ({}) | ||||
|     } | ||||
|   }, | ||||
|   components: { | ||||
|     CustomChart, | ||||
|     Custom3DChart | ||||
|     Custom3DChart, | ||||
|     ColorPalette | ||||
|   }, | ||||
|   data() { | ||||
|     this.buttons = buttons | ||||
|     return { | ||||
|       active: 1, | ||||
|       active: 0, | ||||
| 
 | ||||
|       maxCount: 15, // count的最大值 | ||||
|       currCount: 15, | ||||
| 
 | ||||
|       twoDOption, | ||||
|       threeDSurfaceOption, | ||||
|       threeDScatterOption | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   methods: { | ||||
|     // 点击改变Beta-Gamma Spectrum: Sample图表类型 | ||||
|     handleChange(index) { | ||||
|       this.active = index | ||||
|     }, | ||||
| 
 | ||||
|     // 点击unzoom | ||||
|     handleUnzoom() { | ||||
|       console.log('%c [ handleUnzoom ]-309', 'font-size:13px; background:pink; color:#bf2c9f;') | ||||
|     }, | ||||
| 
 | ||||
|     resize() { | ||||
|       this.$refs.chartRef && this.$refs.chartRef.resize() | ||||
|       this.$refs._3dSurfaceRef && this.$refs._3dSurfaceRef.resize() | ||||
|       this.$refs._3dScannerRef && this.$refs._3dScannerRef.resize() | ||||
|     }, | ||||
| 
 | ||||
|     handleMouseMove(param) { | ||||
|       const { offsetX, offsetY } = param | ||||
|       const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY) | ||||
|       this.$emit('positionChange', point ? [point[0].toFixed(), point[1].toFixed()] : [null, null]) | ||||
|     }, | ||||
| 
 | ||||
|     // 颜色插值 | ||||
|     interpolateColor(color1, color2, percentage) { | ||||
|       const r = color1.r + (color2.r - color1.r) * percentage | ||||
|       const g = color1.g + (color2.g - color1.g) * percentage | ||||
|       const b = color1.b + (color2.b - color1.b) * percentage | ||||
|       return { r, g, b } | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     data: { | ||||
|       handler(newVal) { | ||||
|         const data = [] | ||||
|         Object.entries(newVal).forEach(([_, v]) => { | ||||
|           v.forEach(({ b, g, c }) => { | ||||
|             data.push({ | ||||
|               value: [b, g, c] | ||||
|             }) | ||||
|           }) | ||||
|         }) | ||||
|         this.twoDOption.series.data = data | ||||
|       }, | ||||
|       immediate: true | ||||
|     }, | ||||
| 
 | ||||
|     currCount: { | ||||
|       handler(val) { | ||||
|         if (val <= this.maxCount) { | ||||
|           const { r, g, b } = this.interpolateColor( | ||||
|             { r: 255, g: 0, b: 0 }, | ||||
|             { r: 255, g: 255, b: 255 }, | ||||
|             val / this.maxCount | ||||
|           ) | ||||
| 
 | ||||
|           this.twoDOption.series.itemStyle.color = `rgb(${r}, ${g}, ${b})` | ||||
|         } else { | ||||
|           this.twoDOption.series.itemStyle.color = '#fff' | ||||
|         } | ||||
|       }, | ||||
|       immediate: true | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -338,7 +407,7 @@ export default { | |||
|         &-main { | ||||
|           display: inline-block; | ||||
|           width: 14px; | ||||
|           height: calc(100% - 42px); | ||||
|           height: calc(100% - 70px); | ||||
|           background: linear-gradient(to bottom, #ff0000 0, #fff 100%); | ||||
|         } | ||||
|       } | ||||
|  |  | |||
							
								
								
									
										132
									
								
								src/views/spectrumAnalysis/components/ColorPalette.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/views/spectrumAnalysis/components/ColorPalette.vue
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,132 @@ | |||
| <template> | ||||
|   <div | ||||
|     ref="containerElemRef" | ||||
|     class="color-palette" | ||||
|     :style="{ width: circleWidth + 'px', height: circleWidth + 'px' }" | ||||
|     @click="handleClick" | ||||
|   > | ||||
|     <span | ||||
|       ref="dotElemRef" | ||||
|       class="dot" | ||||
|       :style="{ | ||||
|         width: dotWidth + 'px', | ||||
|         height: dotWidth + 'px', | ||||
|         left: this.dotPosition.x, | ||||
|         top: this.dotPosition.y | ||||
|       }" | ||||
|     ></span> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Number, | ||||
|       default: 1 | ||||
|     }, | ||||
|     maxValue: { | ||||
|       type: Number, | ||||
|       default: 0 | ||||
|     }, | ||||
|     circleWidth: { | ||||
|       type: Number, | ||||
|       default: 26 | ||||
|     }, | ||||
|     dotWidth: { | ||||
|       type: Number, | ||||
|       default: 5 | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       dotPosition: { | ||||
|         x: 0, | ||||
|         y: 0 | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     handleClick({ offsetX, offsetY }) { | ||||
|       const { degree, radian } = this.getDegree([offsetX, offsetY]) | ||||
|       for (let index = 0; index < this.range; index++) { | ||||
|         if (degree >= this.perDegree * index && degree < this.perDegree * (index + 1)) { | ||||
|           this.$emit('input', index) | ||||
|           break | ||||
|         } | ||||
|       } | ||||
|       this.setDotPosition(radian) | ||||
|     }, | ||||
| 
 | ||||
|     setDotPosition(radian) { | ||||
|       const circleRadius = this.circleWidth / 2 // 半径 | ||||
|       const dotRadius = circleRadius - this.dotWidth // 绘制圆点时的半径 | ||||
| 
 | ||||
|       this.dotPosition = { | ||||
|         x: circleRadius - dotRadius * Math.sin(radian) - this.dotWidth / 2 + 'px', | ||||
|         y: circleRadius + dotRadius * Math.cos(radian) - this.dotWidth / 2 + 'px' | ||||
|       } | ||||
|     }, | ||||
|     // 工具方法 | ||||
| 
 | ||||
|     /** | ||||
|      * 根据圆心和某个点,计算从圆心到该点的角度 | ||||
|      */ | ||||
|     getDegree(point) { | ||||
|       // 计算两个点在 x 轴上的差值和在 y 轴上的差值 | ||||
|       const circleRadius = this.circleWidth / 2 // 半径 | ||||
| 
 | ||||
|       const [pointX, pointY] = point | ||||
|       const deltaX = circleRadius - pointX | ||||
|       const deltaY = pointY - circleRadius | ||||
|       // 使用反正切函数计算角度(弧度) | ||||
|       const radian = Math.atan2(deltaX, deltaY) | ||||
|       let degree = radian * (180 / Math.PI) | ||||
|       if (degree < 0) { | ||||
|         degree = 360 + degree | ||||
|       } | ||||
|       return { | ||||
|         radian, | ||||
|         degree | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   watch: { | ||||
|     value: { | ||||
|       handler(newVal) { | ||||
|         const degree = newVal * this.perDegree | ||||
|         const radian = (degree * Math.PI) / 180 // 角度转弧度 | ||||
| 
 | ||||
|         this.setDotPosition(radian) | ||||
|       }, | ||||
|       immediate: true | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     range() { | ||||
|       return this.maxValue > 50 ? this.maxValue : 50 | ||||
|     }, | ||||
| 
 | ||||
|     perDegree() { | ||||
|       return 360 / this.range | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .color-palette { | ||||
|   border-radius: 50%; | ||||
|   background-color: #ff5858; | ||||
|   margin: 0 auto; | ||||
|   position: relative; | ||||
| 
 | ||||
|   .dot { | ||||
|     position: absolute; | ||||
|     pointer-events: none; | ||||
|     border-radius: 50%; | ||||
|     background-color: #f00; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										128
									
								
								src/views/spectrumAnalysis/components/LoadFromFileModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/views/spectrumAnalysis/components/LoadFromFileModal.vue
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,128 @@ | |||
| <template> | ||||
|   <a-modal v-model="visible" :width="1400" title="Load Data From File"> | ||||
|     <a-table :data-source="list" :columns="columns" :pagination="false"> | ||||
|       <template slot="sampleData"> | ||||
|         <a-input type="file" @change="handleFileChange($event, 'sampleData')"></a-input> | ||||
|       </template> | ||||
|       <template slot="gasBkData"> | ||||
|         <a-input type="file" @change="handleFileChange($event, 'gasBkData')"></a-input> | ||||
|       </template> | ||||
|       <template slot="detBkData"> | ||||
|         <a-input type="file" @change="handleFileChange($event, 'detBkData')"></a-input> | ||||
|       </template> | ||||
|       <template slot="qcData"> | ||||
|         <a-input type="file" @change="handleFileChange($event, 'qcData')"></a-input> | ||||
|       </template> | ||||
|       <template slot="status" slot-scope="text"> | ||||
|         <span class="status"></span> | ||||
|       </template> | ||||
|     </a-table> | ||||
| 
 | ||||
|     <!-- 底部按钮 --> | ||||
|     <template slot="footer"> | ||||
|       <a-space> | ||||
|         <a-button type="primary" @click="handleReset">Reset</a-button> | ||||
|         <a-button type="primary" @click="handleLoad">Load</a-button> | ||||
|         <a-button type="primary" @click="handleCancel">Cancel</a-button> | ||||
|       </a-space> | ||||
|     </template> | ||||
|     <!-- 底部按钮结束 --> | ||||
|   </a-modal> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| const columns = [ | ||||
|   { | ||||
|     title: 'SampleData', | ||||
|     dataIndex: 'sampleData', | ||||
|     scopedSlots: { | ||||
|       customRender: 'sampleData' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     title: 'GasBkData', | ||||
|     dataIndex: 'gasBkData', | ||||
|     scopedSlots: { | ||||
|       customRender: 'gasBkData' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     title: 'DetBkData', | ||||
|     dataIndex: 'detBkData', | ||||
|     scopedSlots: { | ||||
|       customRender: 'detBkData' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     title: 'QCData', | ||||
|     dataIndex: 'qcData', | ||||
|     scopedSlots: { | ||||
|       customRender: 'qcData' | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     title: 'Status', | ||||
|     align: 'center', | ||||
|     scopedSlots: { | ||||
|       customRender: 'status' | ||||
|     } | ||||
|   } | ||||
| ] | ||||
| 
 | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     this.columns = columns | ||||
|     return { | ||||
|       list: this.getInitialList() | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getInitialList() { | ||||
|       return new Array(10).fill(0).map(() => ({ | ||||
|         sampleData: '', | ||||
|         gasBkData: '', | ||||
|         detBkData: '', | ||||
|         qcData: '' | ||||
|       })) | ||||
|     }, | ||||
| 
 | ||||
|     handleFileChange(fileInfo, key) { | ||||
|       console.log('%c [ fileInfo, key ]-86', 'font-size:13px; background:pink; color:#bf2c9f;', fileInfo, key) | ||||
|     }, | ||||
| 
 | ||||
|     handleReset() { | ||||
|       this.list = this.getInitialList() | ||||
|     }, | ||||
| 
 | ||||
|     handleLoad() {}, | ||||
| 
 | ||||
|     handleCancel() {} | ||||
|   }, | ||||
|   computed: { | ||||
|     visible: { | ||||
|       get() { | ||||
|         return this.value | ||||
|       }, | ||||
|       set(val) { | ||||
|         this.$emit('input', val) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .status { | ||||
|   display: inline-block; | ||||
|   width: 25px; | ||||
|   height: 25px; | ||||
|   border-radius: 50%; | ||||
| 
 | ||||
|   background-color: #00e170; | ||||
| } | ||||
| </style> | ||||
|  | @ -1,76 +0,0 @@ | |||
| <template> | ||||
|   <a-modal v-model="visible" title="Select File" :footer="null"> | ||||
|     <a-table :data-source="list" :columns="columns" :loading="loading" :pagination="false"> | ||||
|       <template slot="operator" slot-scope="record"> | ||||
|         <a-icon type="check" style="cursor: pointer;" @click="handleSelect(record)"></a-icon> | ||||
|       </template> | ||||
|     </a-table> | ||||
|   </a-modal> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| const columns = [ | ||||
|   { | ||||
|     title: 'File Name', | ||||
|     dataIndex: 'fileName', | ||||
|     ellipsis: true | ||||
|   }, | ||||
|   { | ||||
|     title: 'Action', | ||||
|     width: 80, | ||||
|     align: 'center', | ||||
|     scopedSlots: { | ||||
|       customRender: 'operator' | ||||
|     } | ||||
|   } | ||||
| ] | ||||
| export default { | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     this.columns = columns | ||||
|     return { | ||||
|       loading: false, | ||||
|       list: [] | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     async getList() { | ||||
|       try { | ||||
|         this.loading = true | ||||
|         const res = await '' | ||||
|         console.log('%c [ res ]-13', 'font-size:13px; background:pink; color:#bf2c9f;', res) | ||||
|         this.loading = false | ||||
|         this.list = [{ fileName: '文件1' }, { fileName: '文件2' }] | ||||
|       } catch (error) { | ||||
|         console.error(error) | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     // 选中 | ||||
|     handleSelect(fileInfo) { | ||||
|         console.log('%c [  ]-56', 'font-size:13px; background:pink; color:#bf2c9f;', fileInfo) | ||||
|         this.$emit('select', fileInfo) | ||||
|         this.visible = false | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     visible: { | ||||
|       get() { | ||||
|         if (this.value) { | ||||
|           this.getList() | ||||
|         } | ||||
|         return this.value | ||||
|       }, | ||||
|       set(val) { | ||||
|         this.$emit('input', val) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style></style> | ||||
|  | @ -1,156 +0,0 @@ | |||
| <template> | ||||
|   <a-modal v-model="visible" :width="1400" title="Load Data From File"> | ||||
|     <a-table :data-source="list" :columns="columns" :pagination="false"> | ||||
|       <template slot="status" slot-scope="text"> | ||||
|         <span class="status"></span> | ||||
|       </template> | ||||
|     </a-table> | ||||
| 
 | ||||
|     <!-- 底部按钮 --> | ||||
|     <template slot="footer"> | ||||
|       <a-space> | ||||
|         <a-button type="primary" @click="handleReset">Reset</a-button> | ||||
|         <a-button type="primary" @click="handleLoad">Load</a-button> | ||||
|         <a-button type="primary" @click="handleCancel">Cancel</a-button> | ||||
|       </a-space> | ||||
|     </template> | ||||
|     <!-- 底部按钮结束 --> | ||||
| 
 | ||||
|     <ftp-file-modal v-model="ftpFileModalVisible" @select="handleSelect" /> | ||||
|   </a-modal> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import FtpFileModal from './FtpFileModal.vue' | ||||
| export default { | ||||
|   components: { FtpFileModal }, | ||||
|   props: { | ||||
|     value: { | ||||
|       type: Boolean | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       list: this.getInitialList(), | ||||
|       ftpFileModalVisible: false | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getInitialList() { | ||||
|       return new Array(10).fill(0).map(() => ({ | ||||
|         sampleData: '', | ||||
|         gasBkData: '', | ||||
|         detBkData: '', | ||||
|         qcData: '' | ||||
|       })) | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * 从ftp中选择文件 | ||||
|      * @param rowData 选中的行的数据 | ||||
|      * @param { string } dataKey 选中的数据的那一列的key | ||||
|      */ | ||||
|     selectFileFromFtp(rowData, dataKey) { | ||||
|       this.currRowData = rowData | ||||
|       this.currDataKey = dataKey | ||||
|       this.ftpFileModalVisible = true | ||||
|     }, | ||||
| 
 | ||||
|     handleSelect(fileInfo) { | ||||
|       this.currRowData[this.currDataKey] = fileInfo.fileName | ||||
|     }, | ||||
| 
 | ||||
|     handleReset() { | ||||
|       this.list = this.getInitialList() | ||||
|     }, | ||||
| 
 | ||||
|     handleLoad() {}, | ||||
| 
 | ||||
|     handleCancel() {} | ||||
|   }, | ||||
|   computed: { | ||||
|     visible: { | ||||
|       get() { | ||||
|         return this.value | ||||
|       }, | ||||
|       set(val) { | ||||
|         this.$emit('input', val) | ||||
|       } | ||||
|     }, | ||||
|     columns() { | ||||
|       return [ | ||||
|         { | ||||
|           title: 'SampleData', | ||||
|           dataIndex: 'sampleData', | ||||
|           customCell: record => { | ||||
|             return { | ||||
|               on: { | ||||
|                 click: () => { | ||||
|                   this.selectFileFromFtp(record, 'sampleData') | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           title: 'GasBkData', | ||||
|           dataIndex: 'gasBkData', | ||||
|           customCell: record => { | ||||
|             return { | ||||
|               on: { | ||||
|                 click: () => { | ||||
|                   this.selectFileFromFtp(record, 'gasBkData') | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           title: 'DetBkData', | ||||
|           dataIndex: 'detBkData', | ||||
|           customCell: record => { | ||||
|             return { | ||||
|               on: { | ||||
|                 click: () => { | ||||
|                   this.selectFileFromFtp(record, 'detBkData') | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           title: 'QCData', | ||||
|           dataIndex: 'qcData', | ||||
|           customCell: record => { | ||||
|             return { | ||||
|               on: { | ||||
|                 click: () => { | ||||
|                   this.selectFileFromFtp(record, 'qcData') | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           title: 'Status', | ||||
|           align: 'center', | ||||
|           scopedSlots: { | ||||
|             customRender: 'status' | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .status { | ||||
|   display: inline-block; | ||||
|   width: 25px; | ||||
|   height: 25px; | ||||
|   border-radius: 50%; | ||||
| 
 | ||||
|   background-color: #00e170; | ||||
| } | ||||
| </style> | ||||
|  | @ -1,13 +1,20 @@ | |||
| <template> | ||||
|   <div class="spectrum-line-chart"> | ||||
|     <div class="title">{{ title + ' Count'}}</div> | ||||
|     <custom-chart class="spectrum-line-chart-main" ref="chartRef" :option="option" style="height: 100%"></custom-chart> | ||||
|     <div class="title">{{ title + ' Count' }}</div> | ||||
|     <custom-chart | ||||
|       class="spectrum-line-chart-main" | ||||
|       ref="chartRef" | ||||
|       :option="option" | ||||
|       style="height: 100%" | ||||
|       @zr:mousemove="handleMouseMove" | ||||
|     ></custom-chart> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import CustomChart from '@/components/CustomChart/index.vue' | ||||
| import { cloneDeep } from 'lodash' | ||||
| import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js' | ||||
| 
 | ||||
| const initialOption = { | ||||
|   grid: { | ||||
|  | @ -88,7 +95,23 @@ const initialOption = { | |||
|     symbol: 'none', | ||||
|     data: new Array(256) | ||||
|       .fill(0) | ||||
|       .map((_, index) => [index, (Math.random() < 0.05 ? parseInt(Math.random() * 19644) : parseInt(Math.random() * 800))]) | ||||
|       .map((_, index) => [ | ||||
|         index, | ||||
|         Math.random() < 0.05 ? parseInt(Math.random() * 19644) : parseInt(Math.random() * 800) | ||||
|       ]), | ||||
|     markLine: { | ||||
|       symbol: 'none', | ||||
|       animation: false, | ||||
|       label: { | ||||
|         show: false | ||||
|       }, | ||||
|       lineStyle: { | ||||
|         type: 'solid', | ||||
|         color: 'yellow' | ||||
|       }, | ||||
|       silent: true, | ||||
|       data: [] | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -118,6 +141,23 @@ export default { | |||
|   methods: { | ||||
|     resize() { | ||||
|       this.$refs.chartRef && this.$refs.chartRef.resize() | ||||
|     }, | ||||
| 
 | ||||
|     // 设置辅助线位置 | ||||
|     setLinePosition(xAxis) { | ||||
|       setTimeout(() => { | ||||
|         if (xAxis) { | ||||
|           this.option.series.markLine.data = [{ xAxis }] | ||||
|         } else { | ||||
|           this.option.series.markLine.data = [] | ||||
|         } | ||||
|       }, 0) | ||||
|     }, | ||||
| 
 | ||||
|     handleMouseMove(param) { | ||||
|       const { offsetX, offsetY } = param | ||||
|       const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY) | ||||
|       this.setLinePosition(point ? point[0].toFixed() : null) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										4195
									
								
								src/views/spectrumAnalysis/data.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4195
									
								
								src/views/spectrumAnalysis/data.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -92,7 +92,7 @@ import BetaGammaAnalysis from './beta-gamma-analysis.vue' | |||
| import Spectra from './components/SubOperators/Spectra.vue' | ||||
| import SpectraListInMenu from './components/SpectraListInMenu.vue' | ||||
| import LoadFromDbModal from './components/LoadFromDBModal.vue' | ||||
| import LoadFromFileModal from './components/LoadFromFileModal/Index.vue' | ||||
| import LoadFromFileModal from './components/LoadFromFileModal.vue' | ||||
| 
 | ||||
| // 分析类型 | ||||
| const ANALYZE_TYPE = { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user