From c81923e744834f20da0788abaaa92632f3ff5e29 Mon Sep 17 00:00:00 2001
From: Xu Zhimeng <xuzhimeng@qq.com>
Date: Mon, 25 Sep 2023 19:42:31 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?=
 =?UTF-8?q?=EF=BC=8C=E8=A7=A3=E5=86=B3scatterGL=E4=B8=8D=E5=8F=97=E8=BD=B4?=
 =?UTF-8?q?=E7=BA=BF=E6=9C=80=E5=A4=A7/=E6=9C=80=E5=B0=8F=E5=80=BC?=
 =?UTF-8?q?=E6=8E=A7=E5=88=B6=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/utils/chartHelper.js                      |  10 +
 src/views/spectrumAnalysis/gamma-analysis.vue | 187 ++++++++++++++----
 2 files changed, 154 insertions(+), 43 deletions(-)

diff --git a/src/utils/chartHelper.js b/src/utils/chartHelper.js
index 6560aae..e6cb5f0 100644
--- a/src/utils/chartHelper.js
+++ b/src/utils/chartHelper.js
@@ -104,4 +104,14 @@ export function rangeNumber(min, max) {
   return num => {
     return num > max ? max : num < min ? min : num
   }
+}
+
+/**
+ * 获取图表某条轴线的最大值
+ * @param {import("echarts").ECharts} chartInstance 
+ * @param {'xAxis' | 'yAxis'} axis 
+ * @returns 
+ */
+export function getAxisMax(chartInstance, axis) {
+  return chartInstance.getModel().getComponent(axis).axis.scale._extent[1]
 }
\ No newline at end of file
diff --git a/src/views/spectrumAnalysis/gamma-analysis.vue b/src/views/spectrumAnalysis/gamma-analysis.vue
index b2a957c..dd7374b 100644
--- a/src/views/spectrumAnalysis/gamma-analysis.vue
+++ b/src/views/spectrumAnalysis/gamma-analysis.vue
@@ -106,7 +106,13 @@ import NuclideLibrary from './components/SubOperators/NuclideLibrary.vue'
 import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue'
 import { getAction, postAction } from '@/api/manage'
 import Response from './response.json'
-import { buildLineSeries, findSeriesByName, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper'
+import {
+  buildLineSeries,
+  findSeriesByName,
+  getAxisMax,
+  getXAxisAndYAxisByPosition,
+  rangeNumber,
+} from '@/utils/chartHelper'
 import { cloneDeep } from 'lodash'
 import axios from 'axios'
 import NuclideReviewModal from './components/Modals/AnalyzeInteractiveToolModal/components/NuclideReviewModal.vue'
@@ -256,6 +262,7 @@ const thumbnailOption = {
 
 const graphAssistance = {
   axisType: 'Channel',
+  spectrumType: 'Lines',
   Baseline: true,
   SCAC: true,
   Lc: true,
@@ -462,6 +469,7 @@ export default {
           shadowChannelChart.pointlist && shadowChannelChart.pointlist.map(({ x, y }) => [x, y]),
           shadowChannelChart.color,
           {
+            symbolSize: 2,
             markLine: {
               silent: true,
               symbol: 'none',
@@ -576,6 +584,7 @@ export default {
       })
       series.push(...peakLines)
 
+      // 推入Compare Line
       series.push(
         buildLineSeries('Compare', [], '#fff', {
           symbolSize: 2,
@@ -606,6 +615,8 @@ export default {
 
     // Graph Assistance 操作
     handleGraphAssistanceChange({ type, label, value }) {
+      const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum')
+      const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
       const compareLineSeries = findSeriesByName(this.option.series, 'Compare')
 
       // 类型变化
@@ -651,24 +662,35 @@ export default {
             this.redrawLineBySeriesName('Compare', this.energyCompareLine, this.channelCompareLine)
             break
           case 'Lines':
-            this.option.series[0].type = 'line'
-            this.option.series[0].symbol = 'none'
+            this.graphAssistance.spectrumType = 'Lines'
 
-            this.thumbnailOption.series[0].type = 'line'
-            this.thumbnailOption.series[0].symbol = 'none'
+            spectrumLineSeries.type = 'line'
+            spectrumLineSeries.symbol = 'none'
+
+            thumbnailSpectrumLineSeries.type = 'line'
+            thumbnailSpectrumLineSeries.symbol = 'none'
 
             compareLineSeries.type = 'line'
             compareLineSeries.symbol = 'none'
+
+            this.redrawLineBySeriesName('Spectrum', this.shadowEnergyChart, this.shadowChannelChart)
+            this.redrawLineBySeriesName('Compare', this.energyCompareLine, this.channelCompareLine)
             break
           case 'Scatter':
-            this.option.series[0].type = 'scatterGL'
-            this.option.series[0].symbol = 'circle'
+            this.graphAssistance.spectrumType = 'Scatter'
 
-            this.thumbnailOption.series[0].type = 'scatterGL'
-            this.thumbnailOption.series[0].symbol = 'circle'
+            spectrumLineSeries.type = 'scatterGL'
+            spectrumLineSeries.symbol = 'circle'
+
+            thumbnailSpectrumLineSeries.type = 'scatterGL'
+            thumbnailSpectrumLineSeries.symbol = 'circle'
 
             compareLineSeries.type = 'scatterGL'
             compareLineSeries.symbol = 'circle'
+
+            this.$nextTick(() => {
+              this.rangeScatter()
+            })
             break
         }
       }
@@ -680,9 +702,9 @@ export default {
           case 'Cursor':
             // 显示红色竖线
             if (value) {
-              this.option.series[0].markLine.lineStyle.width = 2
+              spectrumLineSeries.markLine.lineStyle.width = 2
             } else {
-              this.option.series[0].markLine.lineStyle.width = 0
+              spectrumLineSeries.markLine.lineStyle.width = 0
             }
             break
           case 'Baseline':
@@ -758,7 +780,7 @@ export default {
 
     // 重绘右上角的缩略图
     redrawThumbnailChart() {
-      const series = this.thumbnailOption.series[0]
+      const series = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
       const data = this.isEnergy() ? this.shadowEnergyChart : this.shadowChannelChart
       series.data = data.pointlist.map(({ x, y }) => [x, y])
     },
@@ -766,10 +788,11 @@ export default {
     // 点击图表,设置红线
     handleChartClick(param) {
       const { offsetX, offsetY } = param
-      const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY)
+      const point = getXAxisAndYAxisByPosition(this.getChart(), offsetX, offsetY)
       if (point) {
         const xAxis = point[0]
-        this.option.series[0].markLine.data[0].xAxis = xAxis
+        const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum')
+        spectrumLineSeries.markLine.data[0].xAxis = xAxis
 
         const channel = this.isEnergy() ? this.getChannelByEnergy(xAxis) : parseInt(xAxis.toFixed())
         const energy = this.isEnergy()
@@ -834,7 +857,8 @@ export default {
 
     // 触发Peak Infomation
     handleTogglePeak() {
-      const xAxis = this.option.series[0].markLine.data[0].xAxis
+      const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum')
+      const xAxis = spectrumLineSeries.markLine.data[0].xAxis
       const channel = this.isEnergy() ? this.getChannelByEnergy(xAxis) : parseInt(xAxis.toFixed())
       const index = this.channelPeakGroup.findIndex((peakItem) => {
         const allX = peakItem.pointlist.map((item) => item.x)
@@ -864,9 +888,7 @@ export default {
             return prev && prev.y > curr.y ? prev : curr
           })
 
-          const chart = this.$refs.chartRef.getChartInstance()
-
-          const [xPix, yPix] = chart.convertToPixel({ seriesIndex: 0 }, [x, y])
+          const [xPix, yPix] = this.getChart().convertToPixel({ seriesIndex: 0 }, [x, y])
           this.peakInfomationTooltip.content = html
           this.peakInfomationTooltip.visible = true
           this.peakInfomationTooltip.left = xPix
@@ -889,7 +911,8 @@ export default {
      * @param { 'left'| 'right' } direction
      */
     moveMarkLine(direction) {
-      const prevAxis = this.option.series[0].markLine.data[0].xAxis
+      const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum')
+      const prevAxis = spectrumLineSeries.markLine.data[0].xAxis
 
       // 获取每一段 Channel 中的最大值
       const maxXAxises = this.channelPeakGroup.map((item) => {
@@ -903,13 +926,13 @@ export default {
         // 找到第一个比prevAxis大的xAxis
         find = maxXAxises.find((xAxis) => xAxis > prevAxis)
         if (find) {
-          this.option.series[0].markLine.data[0].xAxis = find
+          spectrumLineSeries.markLine.data[0].xAxis = find
         }
       } else if (direction == 'left') {
         // 找到第一个比prevAxis小的xAxis
         find = maxXAxises.reverse().find((xAxis) => xAxis < prevAxis)
         if (find) {
-          this.option.series[0].markLine.data[0].xAxis = find
+          spectrumLineSeries.markLine.data[0].xAxis = find
         }
       }
 
@@ -920,8 +943,7 @@ export default {
 
     // 鼠标按下时开启可刷选状态
     handleMouseDown() {
-      const chart = this.$refs.chartRef.getChartInstance()
-      chart.dispatchAction({
+      this.getChart().dispatchAction({
         type: 'takeGlobalCursor',
         // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
         key: 'brush',
@@ -934,8 +956,7 @@ export default {
 
     handleMouseUp() {
       setTimeout(() => {
-        const chart = this.$refs.chartRef.getChartInstance()
-        this.clearBrush(chart)
+        this.clearBrush(this.getChart())
       }, 0)
     },
 
@@ -965,7 +986,7 @@ export default {
         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 xAxisMax = chart.getModel().getComponent('xAxis').axis.scale._extent[1]
+        const xAxisMax = getAxisMax(chart, 'xAxis')
         const yAxisMax = this.option.yAxis.max
 
         let [x1, y2, x2, y1] = [...point1, ...point2] // 根据解析出的数据确定真实的范围
@@ -992,7 +1013,7 @@ export default {
           this.setThumbnailChartRect(x1, y2, x2, y1)
         }
 
-        const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance()
+        const thumbnailChart = this.getThumbnailChart()
         const [, maxYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y1]) // 方框的上下两条边的yAxis转为pix
         const [, minYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y2])
         const rectHeightPixel = maxYPixel - minYPixel // 计算方框的左右边长(pix)
@@ -1000,13 +1021,72 @@ export default {
       }
 
       this.clearBrush(chart)
+
+      this.$nextTick(() => {
+        this.rangeScatter()
+      })
+    },
+
+    /**
+     * 因scatterGL 不受axis中max和min的控制,手动处理溢出部分
+     * @param {*} x1 xAxis min
+     * @param {*} x2 xAxis max
+     * @param {*} y1 yAxis min
+     * @param {*} y2 yAxis max
+     */
+    rangeScatter() {
+      if (!this.isScatter()) {
+        return
+      }
+
+      const {
+        xAxis: { min: x1 },
+        yAxis: { min: y1 },
+      } = this.option
+
+      const chart = this.getChart()
+      const x2 = getAxisMax(chart, 'xAxis')
+      const y2 = getAxisMax(chart, 'yAxis')
+
+      const channelSpectrumData = {
+        ...this.shadowChannelChart,
+        pointlist: this.pointlistLimit(this.shadowChannelChart.pointlist, x1, x2, y1, y2),
+      }
+      const energySpectrumData = {
+        ...this.shadowEnergyChart,
+        pointlist: this.pointlistLimit(this.shadowEnergyChart.pointlist, x1, x2, y1, y2),
+      }
+      this.redrawLineBySeriesName('Spectrum', energySpectrumData, channelSpectrumData)
+
+      const channelCompareLine = {
+        ...this.channelCompareLine,
+        pointlist: this.pointlistLimit(this.channelCompareLine.pointlist, x1, x2, y1, y2),
+      }
+      const energyCompareLine = {
+        ...this.energyCompareLine,
+        pointlist: this.pointlistLimit(this.energyCompareLine.pointlist, x1, x2, y1, y2),
+      }
+      this.redrawLineBySeriesName('Compare', energyCompareLine, channelCompareLine)
+    },
+
+    /**
+     * 筛选范围内的点
+     * @param {*} pointlist
+     * @param {*} x1
+     * @param {*} x2
+     * @param {*} y1
+     * @param {*} y2
+     */
+    pointlistLimit(pointlist, x1, x2, y1, y2) {
+      return pointlist.filter(({ x, y }) => x >= x1 && x <= x2 && y >= y1 && y <= y2)
     },
 
     // 在右上角缩略图中设置范围
     setThumbnailChartRect(x1, y2, x2, y1) {
       this.thumbnailChartRect = [x1, y2, x2, y1]
 
-      const { markLine } = this.thumbnailOption.series[0]
+      const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
+      const { markLine } = thumbnailSpectrumLineSeries
       const pointList = [
         [
           [x1, y1],
@@ -1034,7 +1114,7 @@ export default {
     // 缩略图点击
     handleThumbnailChartClick(param) {
       const { offsetX, offsetY } = param
-      const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance()
+      const thumbnailChart = this.getThumbnailChart()
 
       const point = getXAxisAndYAxisByPosition(thumbnailChart, offsetX, offsetY)
       if (point && this.thumbnailChartRect && this.thumbnailChartRect.length) {
@@ -1046,7 +1126,7 @@ export default {
 
         let [xAxis, yAxis] = point
 
-        const xAxisMax = thumbnailChart.getModel().getComponent('xAxis').axis.scale._extent[1]
+        const xAxisMax = getAxisMax(thumbnailChart, 'xAxis')
 
         const xAxisLimit = rangeNumber(1 + halfWidth, xAxisMax - halfWidth)
 
@@ -1081,14 +1161,22 @@ export default {
 
     // 重置
     handleReset() {
-      this.option.xAxis.min = 1
-      this.option.xAxis.max = 'dataMax'
-      this.option.yAxis.min = 1
-      this.option.yAxis.max = 'dataMax'
+      const spectrumLineMaxX = Math.max(...this.shadowChannelChart.pointlist.map(({ x }) => x))
+      const spectrumLineMaxY = Math.max(...this.shadowChannelChart.pointlist.map(({ y }) => y))
 
-      this.thumbnailOption.series[0].markLine.data = []
+      this.option.xAxis.min = 1
+      this.option.xAxis.max = spectrumLineMaxX
+      this.option.yAxis.min = 1
+      this.option.yAxis.max = spectrumLineMaxY
+
+      const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
+      thumbnailSpectrumLineSeries.markLine.data = []
       this.thumbnailChartRect = []
       this.closePeakInfomationTooltip()
+
+      this.$nextTick(() => {
+        this.rangeScatter()
+      })
     },
 
     // 从分析工具刷新部分数据
@@ -1120,13 +1208,12 @@ export default {
       this.energyCompareLine = energyData
       this.redrawLineBySeriesName('Compare', energyData, channelData, true, channelData.color)
 
-      if (this.option.series[0].type == 'scatterGL') {
+      if (this.isScatter()) {
         lineSeries.type = 'scatterGL'
       }
 
       this.$nextTick(() => {
-        const chart = this.$refs.chartRef.getChartInstance()
-        const yAxisMax = chart.getModel().getComponent('yAxis').axis.scale._extent[1]
+        const yAxisMax = getAxisMax(this.getChart(), 'yAxis')
         this.thumbnailOption.yAxis.max = yAxisMax
       })
     },
@@ -1231,14 +1318,16 @@ export default {
       this.option.yAxis.type = 'value'
 
       if (this.option.series.length) {
-        this.option.series[0].type = 'line'
-        this.option.series[0].symbol = 'none'
-        this.option.series[0].markLine.lineStyle.width = 2
+        const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum')
+        spectrumLineSeries.type = 'line'
+        spectrumLineSeries.symbol = 'none'
+        spectrumLineSeries.markLine.lineStyle.width = 2
       }
 
       if (this.thumbnailOption.series.length) {
-        this.thumbnailOption.series[0].type = 'line'
-        this.thumbnailOption.series[0].symbol = 'none'
+        const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
+        thumbnailSpectrumLineSeries.type = 'line'
+        thumbnailSpectrumLineSeries.symbol = 'none'
       }
       this.graphAssistance = cloneDeep(graphAssistance)
     },
@@ -1310,6 +1399,18 @@ export default {
     isEnergy() {
       return this.graphAssistance.axisType == 'Energy'
     },
+
+    isScatter() {
+      return this.graphAssistance.spectrumType == 'Scatter'
+    },
+
+    getChart() {
+      return this.$refs.chartRef.getChartInstance()
+    },
+
+    getThumbnailChart() {
+      return this.$refs.thumbnailChartRef.getChartInstance()
+    },
   },
   watch: {
     sample: {