feat: 增加各图表之间的联动
This commit is contained in:
		
							parent
							
								
									6c02e52e23
								
							
						
					
					
						commit
						0482aebb12
					
				|  | @ -3,6 +3,10 @@ | |||
| </template> | ||||
| <script> | ||||
| import * as echarts from 'echarts' | ||||
| 
 | ||||
| const events = ['brushEnd'] | ||||
| const zrEvents = ['mousemove', 'mousedown', 'mouseup'] | ||||
| 
 | ||||
| export default { | ||||
|   props: { | ||||
|     option: { | ||||
|  | @ -18,43 +22,51 @@ export default { | |||
|     return {} | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.chart = echarts.init(this.$refs.containerRef) | ||||
|     this.chart.setOption(this.option) | ||||
|     this._chart = echarts.init(this.$refs.containerRef) | ||||
|     this._chart.setOption(this.option) | ||||
|     this.initEventListener() | ||||
|   }, | ||||
|   methods: { | ||||
|     initEventListener() { | ||||
|       events.forEach(eventName => { | ||||
|         this._chart.on(eventName, (params) => { | ||||
|           this.$emit(eventName, params) | ||||
|         }) | ||||
|       }) | ||||
| 
 | ||||
|       const zr = this.getZRender() | ||||
|       zr.on('mousemove', (params) => { | ||||
|         this.$emit('zr:mousemove', params) | ||||
|       zrEvents.forEach(eventName => { | ||||
|         zr.on(eventName, params => { | ||||
|           this.$emit(`zr:${eventName}`, params) | ||||
|         }) | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     resize() { | ||||
|       this.chart && this.chart.resize() | ||||
|       this._chart && this._chart.resize() | ||||
|     }, | ||||
| 
 | ||||
|     // 获取echart实例 | ||||
|     getChartInstance() { | ||||
|       return this.chart | ||||
|       return this._chart | ||||
|     }, | ||||
| 
 | ||||
|     getZRender() { | ||||
|       return this.chart.getZr() | ||||
|       return this._chart.getZr() | ||||
|     } | ||||
|   }, | ||||
|   watch : { | ||||
|   watch: { | ||||
|     option: { | ||||
|       handler() { | ||||
|         if(this.chart) { | ||||
|           this.chart.setOption(this.option) | ||||
|         if (this._chart) { | ||||
|           this._chart.setOption(this.option) | ||||
|         } | ||||
|       }, | ||||
|       deep: true | ||||
|     }, | ||||
|     height() { | ||||
|       this.$nextTick(() => { | ||||
|         this.chart && this.chart.resize() | ||||
|         this._chart && this._chart.resize() | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
|  |  | |||
|  | @ -5,7 +5,12 @@ | |||
|         <template slot="title"> | ||||
|           Beta-Gamma Spectrum: Sample | ||||
|         </template> | ||||
|         <beta-gamma-spectrum-chart ref="betaGammaChartRef" :data="twoDData" @positionChange="handlePositionChange" /> | ||||
|         <beta-gamma-spectrum-chart | ||||
|           ref="betaGammaChartRef" | ||||
|           :data="twoDData" | ||||
|           @positionChange="handlePositionChange" | ||||
|           @rangeChange="handleRangeChange" | ||||
|         /> | ||||
|       </beta-gamma-chart-container> | ||||
|     </div> | ||||
|     <div class="beta-and-gamma-spectrum"> | ||||
|  | @ -16,7 +21,7 @@ | |||
|               <template slot="title"> | ||||
|                 Gamma Spectrum: Original | ||||
|               </template> | ||||
|               <spectrum-line-chart ref="lineChart1Ref" /> | ||||
|               <spectrum-line-chart ref="lineChart1Ref" @rangeChange="handleLineChartRangeChange($event, 'y')" /> | ||||
|             </beta-gamma-chart-container> | ||||
|           </div> | ||||
|           <div class="gamma-spectrum-item"> | ||||
|  | @ -24,7 +29,7 @@ | |||
|               <template slot="title"> | ||||
|                 Gamma Spectrum: Projected | ||||
|               </template> | ||||
|               <spectrum-line-chart ref="lineChart2Ref" /> | ||||
|               <spectrum-line-chart ref="lineChart2Ref" @rangeChange="handleLineChartRangeChange($event, 'y')" /> | ||||
|             </beta-gamma-chart-container> | ||||
|           </div> | ||||
|         </div> | ||||
|  | @ -34,7 +39,12 @@ | |||
|               <template slot="title"> | ||||
|                 Beta Spectrum: Original | ||||
|               </template> | ||||
|               <spectrum-line-chart ref="lineChart3Ref" title="Beta" color="#00ff1e" /> | ||||
|               <spectrum-line-chart | ||||
|                 ref="lineChart3Ref" | ||||
|                 title="Beta" | ||||
|                 color="#00ff1e" | ||||
|                 @rangeChange="handleLineChartRangeChange($event, 'x')" | ||||
|               /> | ||||
|             </beta-gamma-chart-container> | ||||
|           </div> | ||||
|           <div class="gamma-spectrum-item"> | ||||
|  | @ -42,7 +52,12 @@ | |||
|               <template slot="title"> | ||||
|                 Beta Spectrum: Projected | ||||
|               </template> | ||||
|               <spectrum-line-chart ref="lineChart4Ref" title="Beta" color="#00ff1e" /> | ||||
|               <spectrum-line-chart | ||||
|                 ref="lineChart4Ref" | ||||
|                 title="Beta" | ||||
|                 color="#00ff1e" | ||||
|                 @rangeChange="handleLineChartRangeChange($event, 'x')" | ||||
|               /> | ||||
|             </beta-gamma-chart-container> | ||||
|           </div> | ||||
|         </div> | ||||
|  | @ -142,6 +157,34 @@ export default { | |||
|       // Beta Spectrum,根据bata-gamma的bata channel的值(x轴)进行定位 | ||||
|       this.$refs.lineChart3Ref.setLinePosition(xAxis) | ||||
|       this.$refs.lineChart4Ref.setLinePosition(xAxis) | ||||
|     }, | ||||
| 
 | ||||
|     // 鼠标在左侧2d图表上刷选时 | ||||
|     handleRangeChange([x1, x2, y1, y2]) { | ||||
|       this.$refs.lineChart1Ref.setRange(y1, y2) | ||||
|       this.$refs.lineChart2Ref.setRange(y1, y2) | ||||
| 
 | ||||
|       this.$refs.lineChart3Ref.setRange(x1, x2) | ||||
|       this.$refs.lineChart4Ref.setRange(x1, x2) | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * 右侧折线图表刷选时 | ||||
|      * @param {number[]} range 范围 | ||||
|      * @param {'x'|'y'} type 类型 | ||||
|      **/ | ||||
| 
 | ||||
|     handleLineChartRangeChange([x1, x2], type) { | ||||
|       if (type == 'y') { | ||||
|         // 如果是gamma channel变化 | ||||
|         this.$refs.lineChart1Ref.setRange(x1, x2) | ||||
|         this.$refs.lineChart2Ref.setRange(x1, x2) | ||||
|       } else if (type == 'x') { | ||||
|         this.$refs.lineChart3Ref.setRange(x1, x2) | ||||
|         this.$refs.lineChart4Ref.setRange(x1, x2) | ||||
|       } | ||||
| 
 | ||||
|       this.$refs.betaGammaChartRef.setRange(x1, x2, type) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -13,8 +13,14 @@ | |||
|     </div> | ||||
|     <div class="beta-gamma-spectrum-chart-main"> | ||||
|       <!-- 2D 图表 --> | ||||
|       <div class="_2d-chart" v-if="active == 0"> | ||||
|         <custom-chart ref="chartRef" :option="twoDOption" @zr:mousemove="handleMouseMove" /> | ||||
|       <div class="_2d-chart" v-show="active == 0"> | ||||
|         <custom-chart | ||||
|           ref="chartRef" | ||||
|           :option="twoDOption" | ||||
|           @zr:mousemove="handleMouseMove" | ||||
|           @zr:mousedown="handleMouseDown" | ||||
|           @brushEnd="handleBrushEnd" | ||||
|         /> | ||||
|         <div class="bar"> | ||||
|           <color-palette v-model="currCount" :maxValue="4" /> | ||||
|           <div>{{ currCount + 1 }}</div> | ||||
|  | @ -123,7 +129,8 @@ const twoDOption = { | |||
|     itemStyle: { | ||||
|       color: '#fff' | ||||
|     } | ||||
|   } | ||||
|   }, | ||||
|   brush: {} | ||||
| } | ||||
| 
 | ||||
| //3D Surface 配置 | ||||
|  | @ -284,6 +291,10 @@ export default { | |||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   mounted() { | ||||
|     this.twoDOption.brush = { toolbox: [] } | ||||
|   }, | ||||
| 
 | ||||
|   methods: { | ||||
|     // 点击改变Beta-Gamma Spectrum: Sample图表类型 | ||||
|     handleChange(index) { | ||||
|  | @ -292,7 +303,12 @@ export default { | |||
| 
 | ||||
|     // 点击unzoom | ||||
|     handleUnzoom() { | ||||
|       console.log('%c [ handleUnzoom ]-309', 'font-size:13px; background:pink; color:#bf2c9f;') | ||||
|       this.twoDOption.xAxis.min = 0 | ||||
|       this.twoDOption.xAxis.max = 256 | ||||
|       this.twoDOption.yAxis.min = 0 | ||||
|       this.twoDOption.yAxis.max = 256 | ||||
| 
 | ||||
|       this.emitRangeChange([0, 256, 0, 256]) | ||||
|     }, | ||||
| 
 | ||||
|     resize() { | ||||
|  | @ -301,12 +317,81 @@ export default { | |||
|       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]) | ||||
|     }, | ||||
| 
 | ||||
|     // 鼠标按下时开启可刷选状态 | ||||
|     handleMouseDown() { | ||||
|       const chart = this.$refs.chartRef.getChartInstance() | ||||
|       chart.dispatchAction({ | ||||
|         type: 'takeGlobalCursor', | ||||
|         // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。 | ||||
|         key: 'brush', | ||||
|         brushOption: { | ||||
|           // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。 | ||||
|           brushType: 'rect' | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     // 刷选完毕时 | ||||
|     handleBrushEnd(param) { | ||||
|       const chart = this.$refs.chartRef.getChartInstance() | ||||
|       const areas = param.areas[0] | ||||
|       if (areas) { | ||||
|         const range = areas.range | ||||
|         const [[minX, maxX], [minY, maxY]] = range | ||||
| 
 | ||||
|         const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map(num => parseInt(num.toFixed())) | ||||
|         const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map(num => parseInt(num.toFixed())) | ||||
| 
 | ||||
|         const [x1, y2, x2, y1] = [...point1, ...point2] // 根据解析出的数据确定真实的范围 | ||||
| 
 | ||||
|         this.twoDOption.xAxis.min = x1 | ||||
|         this.twoDOption.xAxis.max = x2 | ||||
|         this.twoDOption.yAxis.min = y1 | ||||
|         this.twoDOption.yAxis.max = y2 | ||||
| 
 | ||||
|         this.emitRangeChange([x1, x2, y1, y2]) | ||||
|       } | ||||
| 
 | ||||
|       // 清理刷选的范围 | ||||
|       chart.dispatchAction({ | ||||
|         type: 'brush', | ||||
|         areas: [] | ||||
|       }) | ||||
| 
 | ||||
|       // 改为不可刷选状态 | ||||
|       chart.dispatchAction({ | ||||
|         type: 'takeGlobalCursor' | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     // 通知上层范围改变 | ||||
|     emitRangeChange(range) { | ||||
|       this.$emit('rangeChange', range) | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * 设置范围 | ||||
|      * @param {number} x1 | ||||
|      * @param {number} x2 | ||||
|      * @param {'x' | 'y'} type 要改变哪条轴 | ||||
|      */ | ||||
|     setRange(x1, x2, type) { | ||||
|       if (type == 'x') { | ||||
|         this.twoDOption.xAxis.min = x1 | ||||
|         this.twoDOption.xAxis.max = x2 | ||||
|       } else if (type == 'y') { | ||||
|         this.twoDOption.yAxis.min = x1 | ||||
|         this.twoDOption.yAxis.max = x2 | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     // 颜色插值 | ||||
|     interpolateColor(color1, color2, percentage) { | ||||
|       const r = color1.r + (color2.r - color1.r) * percentage | ||||
|  |  | |||
|  | @ -1,13 +1,25 @@ | |||
| <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%" | ||||
|       @zr:mousemove="handleMouseMove" | ||||
|     ></custom-chart> | ||||
|     <div class="calculation"> | ||||
|       <span>Channel: 136</span> | ||||
|       <span>Count: 1475</span> | ||||
|       <span class="error">Energy: 381.409</span> | ||||
|     </div> | ||||
|     <div class="chart-container"> | ||||
|       <div class="left-title">{{ title + ' Count' }}</div> | ||||
|       <custom-chart | ||||
|         class="spectrum-line-chart-main" | ||||
|         ref="chartRef" | ||||
|         :option="option" | ||||
|         style="height: 100%" | ||||
|         @zr:mousemove="handleMouseMove" | ||||
|         @zr:mousedown="handleMouseDown" | ||||
|         @brushEnd="handleBrushEnd" | ||||
|       ></custom-chart> | ||||
|     </div> | ||||
|     <div class="bottom-title"> | ||||
|       {{ title + ' Channel' }} | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
|  | @ -18,26 +30,9 @@ import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js' | |||
| 
 | ||||
| const initialOption = { | ||||
|   grid: { | ||||
|     top: 25, | ||||
|     right: 12, | ||||
|     bottom: 40 | ||||
|   }, | ||||
|   title: { | ||||
|     text: '', | ||||
|     left: 'right', | ||||
|     top: 0, | ||||
|     textStyle: { | ||||
|       color: '#ade6ee', | ||||
|       fontSize: 12, | ||||
|       rich: { | ||||
|         a: { | ||||
|           padding: [0, 27, 0, 0] | ||||
|         }, | ||||
|         b: { | ||||
|           color: '#ff5656' | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     top: 10, | ||||
|     right: 15, | ||||
|     bottom: 20 | ||||
|   }, | ||||
|   xAxis: { | ||||
|     min: 0, | ||||
|  | @ -83,6 +78,9 @@ const initialOption = { | |||
|         color: 'rgba(119, 181, 213, .2)' | ||||
|       } | ||||
|     }, | ||||
|     axisTick: { | ||||
|       show: false | ||||
|     }, | ||||
|     axisLabel: { | ||||
|       color: '#ade6ee' | ||||
|     } | ||||
|  | @ -112,7 +110,8 @@ const initialOption = { | |||
|       silent: true, | ||||
|       data: [] | ||||
|     } | ||||
|   } | ||||
|   }, | ||||
|   brush: {} | ||||
| } | ||||
| 
 | ||||
| export default { | ||||
|  | @ -131,13 +130,15 @@ export default { | |||
|   }, | ||||
|   data() { | ||||
|     const option = cloneDeep(initialOption) | ||||
|     option.title.text = `{a|Channel: 136}{a|Count: 1475}{b|Energy:  381.409}` | ||||
|     option.series.itemStyle.color = this.color | ||||
|     option.xAxis.name = this.title + ' Channel' | ||||
|     return { | ||||
|       option | ||||
|     } | ||||
|   }, | ||||
|   mounted() { | ||||
|     this.option.brush = { toolbox: [] } | ||||
|   }, | ||||
|   methods: { | ||||
|     resize() { | ||||
|       this.$refs.chartRef && this.$refs.chartRef.resize() | ||||
|  | @ -154,10 +155,66 @@ export default { | |||
|       }, 0) | ||||
|     }, | ||||
| 
 | ||||
|     // 设置范围 | ||||
|     setRange(min, max) { | ||||
|       this.option.xAxis.min = min | ||||
|       this.option.xAxis.max = max | ||||
|     }, | ||||
| 
 | ||||
|     // 鼠标在图表上移动时 | ||||
|     handleMouseMove(param) { | ||||
|       const { offsetX, offsetY } = param | ||||
|       const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY) | ||||
|       this.setLinePosition(point ? point[0].toFixed() : null) | ||||
|     }, | ||||
| 
 | ||||
|     // 鼠标按下时开启可刷选状态 | ||||
|     handleMouseDown() { | ||||
|       const chart = this.$refs.chartRef.getChartInstance() | ||||
|       chart.dispatchAction({ | ||||
|         type: 'takeGlobalCursor', | ||||
|         // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。 | ||||
|         key: 'brush', | ||||
|         brushOption: { | ||||
|           // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。 | ||||
|           brushType: 'lineX' | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     // 刷选完毕时 | ||||
|     handleBrushEnd(param) { | ||||
|       const chart = this.$refs.chartRef.getChartInstance() | ||||
| 
 | ||||
|       const areas = param.areas[0] | ||||
|       if (areas) { | ||||
|         const range = areas.range | ||||
|         const [minX, maxX] = range | ||||
| 
 | ||||
|         const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, 0]) | ||||
|         const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, 0]) | ||||
| 
 | ||||
|         const [x1, x2] = [parseInt(point1[0].toFixed()), parseInt(point2[0].toFixed())] // 根据解析出的数据确定真实的范围 | ||||
|         this.option.xAxis.min = x1 | ||||
|         this.option.xAxis.max = x2 | ||||
| 
 | ||||
|         this.emitRangeChange([x1, x2]) | ||||
|       } | ||||
| 
 | ||||
|       // 清理刷选的范围 | ||||
|       chart.dispatchAction({ | ||||
|         type: 'brush', | ||||
|         areas: [] | ||||
|       }) | ||||
| 
 | ||||
|       // 改为不可刷选状态 | ||||
|       chart.dispatchAction({ | ||||
|         type: 'takeGlobalCursor' | ||||
|       }) | ||||
|     }, | ||||
| 
 | ||||
|     emitRangeChange(range) { | ||||
|       this.$emit('rangeChange', range) | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -165,23 +222,54 @@ export default { | |||
| 
 | ||||
| <style lang="less" scoped> | ||||
| .spectrum-line-chart { | ||||
|   display: flex; | ||||
|   height: 100%; | ||||
| 
 | ||||
|   .title { | ||||
|     writing-mode: vertical-rl; | ||||
|     color: #5b9cba; | ||||
|     font-size: 16px; | ||||
|     transform: rotate(180deg); | ||||
|     text-align: center; | ||||
|     user-select: none; | ||||
|     white-space: nowrap; | ||||
|     overflow: hidden; | ||||
|     text-overflow: ellipsis; | ||||
|   .calculation { | ||||
|     line-height: 10px; | ||||
|     text-align: right; | ||||
|     font-size: 14px; | ||||
| 
 | ||||
|     .error { | ||||
|       color: #ff5656; | ||||
|     } | ||||
| 
 | ||||
|     span { | ||||
|       color: #ade6ee; | ||||
| 
 | ||||
|       &:not(:last-child) { | ||||
|         margin-right: 27px; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   &-main { | ||||
|     flex: 1; | ||||
|   .chart-container { | ||||
|     display: flex; | ||||
|     margin-top: 7px; | ||||
|     margin-bottom: 8px; | ||||
|     height: calc(100% - 35px); | ||||
| 
 | ||||
|     .left-title { | ||||
|       writing-mode: vertical-rl; | ||||
|       color: #5b9cba; | ||||
|       font-size: 14px; | ||||
|       transform: rotate(180deg); | ||||
|       text-align: center; | ||||
|       user-select: none; | ||||
|       white-space: nowrap; | ||||
|       overflow: hidden; | ||||
|       text-overflow: ellipsis; | ||||
|     } | ||||
| 
 | ||||
|     .spectrum-line-chart-main { | ||||
|       flex: 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .bottom-title { | ||||
|     line-height: 10px; | ||||
|     font-size: 14px; | ||||
|     color: #5b9cba; | ||||
|     text-align: center; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user