From 67757b84e7dda84cb8b4ca3018a37aa467968e55 Mon Sep 17 00:00:00 2001 From: Xu Zhimeng Date: Thu, 26 Oct 2023 11:39:06 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AF=B9gamma?= =?UTF-8?q?=E5=9B=BE=E8=A1=A8=E7=BC=A9=E6=94=BE=E7=9A=84=E9=94=AE=E7=9B=98?= =?UTF-8?q?=E5=BF=AB=E6=8D=B7=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/spectrumAnalysis/gamma-analysis.vue | 184 +++++++++++++++++- src/views/spectrumAnalysis/settings.js | 30 ++- 2 files changed, 195 insertions(+), 19 deletions(-) diff --git a/src/views/spectrumAnalysis/gamma-analysis.vue b/src/views/spectrumAnalysis/gamma-analysis.vue index d7b0d48..ae5c81e 100644 --- a/src/views/spectrumAnalysis/gamma-analysis.vue +++ b/src/views/spectrumAnalysis/gamma-analysis.vue @@ -235,6 +235,8 @@ export default { this.$bus.$on('colorChange', this.handleColorChange) this.$bus.$on('gammaRefresh', this.handleRefresh) this.$bus.$on('accept', this.handleAccept) + + document.addEventListener('keydown', this.handleKeyboardEvent) }, destroyed() { this.cancelLastRequest() @@ -242,12 +244,170 @@ export default { this.$bus.$off('colorChange', this.handleColorChange) this.$bus.$off('gammaRefresh', this.handleRefresh) this.$bus.$off('accept', this.handleAccept) + + document.removeEventListener('keydown', this.handleKeyboardEvent) }, mounted() { this.option.brush = { toolbox: [] } this.initWebSocket() }, methods: { + // 键盘事件 + handleKeyboardEvent(event) { + this.changeRectByKeyBoard(event.key) + }, + + /** + * 键盘事件处理 + * @param {*} key + * @description 1、xAxis采用按axis值增/减量的方式实现 + * 2、而因为yAxis在type=log下分布不平均,无法用按axis值增/减量的方式实现平均的增大或缩小 + * 所以采用像素增/减量的方式。 + * 具体实现则为,因为右上角缩略图表是不改变轴最大值最小值的,也就是它的每个axis像素数不会 + * 随着图表值域的缩小而变大,所以将其视作标准参照物,将主图表现在的axis值转为像素值,增/减 + * 去每步像素值得到新的像素值,然后再转化为axis值去设置主图表范围,和设置右上角缩略图表的 + * 框的范围 + */ + changeRectByKeyBoard(key) { + if (!['=', '-', 'ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft'].includes(key)) { + return + } + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + const markLineData = spectrumLineSeries.markLine.data[0] + const markLineXAxis = markLineData.xAxis + + const thumbnailChart = this.getThumbnailChart() + // 通过thumbnail chart获取最小值和最大值 + const maxX = getAxisMax(thumbnailChart, 'xAxis') + const maxY = getAxisMax(thumbnailChart, 'yAxis') + const xStep = Math.ceil(maxX / 100) // x 轴每次走的axis数 + const yStep = 5 // y 轴在缩略图表每次走的像素数 + + // 如果遇到dataMax,设为最大值真实值 + let { min: currMinX, max: currMaxX } = this.option.xAxis + if (currMaxX == 'dataMax') { + currMaxX = maxX + } + let { min: currMinY, max: currMaxY } = this.option.yAxis + if (currMaxY == 'dataMax') { + currMaxY = maxY + } + + const { pixX: currMinXPix } = this.convertToPixel(thumbnailChart, currMinX, currMinY) + const { pixY: currMinYPix } = this.convertToPixel(thumbnailChart, currMinX, currMinY) + const { pixY: currMaxYPix } = this.convertToPixel(thumbnailChart, currMinX, currMaxY) + + const { pixY: minYPixel } = this.convertToPixel(thumbnailChart, currMinX, 1) + const { pixY: maxYPixel } = this.convertToPixel(thumbnailChart, currMinX, maxY) + + let nextMinX, nextMaxX, nextMinYPix, nextMaxYPix + + switch (key) { + case '=': // 在x轴扩大范围 + nextMinX = currMinX - xStep + nextMaxX = currMaxX + xStep + if (nextMinX < 1) { + nextMinX = 1 + } + if (nextMaxX > maxX) { + nextMaxX = maxX + } + this.setRectRange(nextMinX, nextMaxX, currMinY, currMaxY) + break + case '-': // 在x轴缩小范围 + if (currMaxX - currMinX > 2 * xStep) { + nextMinX = currMinX + xStep + nextMaxX = currMaxX - xStep + + this.setRectRange(nextMinX, nextMaxX, currMinY, currMaxY) + } + break + case 'ArrowUp': // 在y轴扩大范围 + nextMinYPix = currMinYPix + yStep + nextMaxYPix = currMaxYPix - yStep + + if (nextMinYPix > minYPixel) { + nextMinYPix = minYPixel + } + + if (nextMaxYPix < maxYPixel) { + nextMaxYPix = maxYPixel + } + + const nextMinY = getXAxisAndYAxisByPosition(thumbnailChart, currMinXPix, nextMinYPix)[1] + const nextMaxY = getXAxisAndYAxisByPosition(thumbnailChart, currMinXPix, nextMaxYPix)[1] + + this.setRectRange(currMinX, currMaxX, nextMinY, nextMaxY) + break + case 'ArrowDown': // 在y轴缩小范围 + if (currMinYPix - currMaxYPix > 2 * yStep) { + nextMinYPix = currMinYPix - yStep + nextMaxYPix = currMaxYPix + yStep + + const nextMinY = getXAxisAndYAxisByPosition(thumbnailChart, currMinXPix, nextMinYPix)[1] + const nextMaxY = getXAxisAndYAxisByPosition(thumbnailChart, currMinXPix, nextMaxYPix)[1] + + this.setRectRange(currMinX, currMaxX, nextMinY, nextMaxY) + } + break + case 'ArrowRight': + if (markLineXAxis == maxX) { + return + } + const nextAxis = markLineXAxis == -1 ? 1 : markLineXAxis + 1 + markLineData.xAxis = nextAxis + const { channel: nextChannel, energy: nextEnergy, counts: nextCounts } = this.getEnergyAndCountsByXAxis(nextAxis) + this.setChartBottomTitle(nextChannel, nextEnergy, nextCounts) + + this.getSelPosNuclide(nextChannel) + break + case 'ArrowLeft': + if (markLineXAxis <= 1) { + return + } + markLineData.xAxis = markLineXAxis - 1 + const { + channel: prevChannel, + energy: prevEnergy, + counts: prevCounts, + } = this.getEnergyAndCountsByXAxis(markLineXAxis - 1) + this.setChartBottomTitle(prevChannel, prevEnergy, prevCounts) + + this.getSelPosNuclide(prevChannel) + break + } + }, + + // 图表转化像素值 + convertToPixel(chart, xAxis, yAxis) { + const [pixX, pixY] = chart.convertToPixel({ seriesIndex: 0 }, [xAxis, yAxis]) + return { + pixX, + pixY, + } + }, + + // 设置范围 + setRectRange(minX, maxX, minY, maxY) { + this.option.xAxis.min = minX + this.option.xAxis.max = maxX + this.option.yAxis.min = minY + this.option.yAxis.max = maxY + if (this.isEnergy()) { + const channel1 = this.getChannelByEnergy(minX) + const channel2 = this.getChannelByEnergy(maxX) + this.setThumbnailChartRect(channel1, maxY, channel2, minY) + } else { + this.setThumbnailChartRect(minX, maxY, maxX, minY) + } + + const thumbnailChart = this.getThumbnailChart() + const [, maxYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, minY]) // 方框的上下两条边的yAxis转为pix + const [, minYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, maxY]) + const rectHeightPixel = maxYPixel - minYPixel // 计算方框的左右边长(pix) + this.halfHeightPixel = rectHeightPixel / 2 + }, + initWebSocket: function () { console.log('qweqwerq') // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https @@ -434,7 +594,12 @@ export default { this.resetThumbnailChartDataMax() // 设置 Spectrum Line - this.redrawLineBySeriesName('Spectrum', shadowEnergyChart, shadowChannelChart, true, shadowChannelChart.color) + this.setSeriesData( + this.option.series, + 'Spectrum', + this.transformPointListData(shadowChannelChart.pointlist), + shadowChannelChart.color + ) // 设置 BaseLine this.setSeriesData( @@ -691,7 +856,7 @@ export default { if (point) { const xAxis = point[0] const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') - spectrumLineSeries.markLine.data[0].xAxis = xAxis + spectrumLineSeries.markLine.data[0].xAxis = parseInt(xAxis.toFixed()) const { channel, energy, counts } = this.getEnergyAndCountsByXAxis(xAxis) this.setChartBottomTitle(channel, energy, counts) @@ -702,7 +867,9 @@ export default { // 设置图表底部的标题 setChartBottomTitle(channel, energy, counts) { - this.option.title.text = `{a|Channel:${channel}} {a|Energy:${energy}} {a|Counts:${counts}} {a|Detectability:0}` + this.option.title.text = `{a|Channel:${channel}} {a|Energy:${ + energy || 0 + }} {a|Counts:${counts || 0}} {a|Detectability:0}` }, // 根据xAixs值找channel、energy和counts @@ -1058,14 +1225,11 @@ export default { const point = getXAxisAndYAxisByPosition(thumbnailChart, offsetX, offsetY) if (point && this.thumbnailChartRect && this.thumbnailChartRect.length) { const [x1, y2, x2, y1] = this.thumbnailChartRect - const halfWidth = Math.ceil((x2 - x1) / 2) + const halfWidth = (x2 - x1) / 2 // 缩略图最大值转为pix - const [, maxYAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [ - 0, - getAxisMax(thumbnailChart, 'yAxis'), - ]) - const [, minYAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, 1]) + const { pixY: maxYAxisPixel } = this.convertToPixel(thumbnailChart, 0, getAxisMax(thumbnailChart, 'yAxis')) + const { pixY: minYAxisPixel } = this.convertToPixel(thumbnailChart, 0, 1) let [xAxis, yAxis] = point @@ -1078,7 +1242,7 @@ export default { xAxis = xAxisLimit(xAxis) - let [, yAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, yAxis]) + let { pixY: yAxisPixel } = this.convertToPixel(thumbnailChart, 0, yAxis) yAxisPixel = yAxisLimit(yAxisPixel) const minYAxis = thumbnailChart.convertFromPixel({ seriesIndex: 0 }, [0, yAxisPixel + halfHeightPixel])[1] // 再把y轴最小值从pix转为yAxis diff --git a/src/views/spectrumAnalysis/settings.js b/src/views/spectrumAnalysis/settings.js index b039cf6..b9e3a5c 100644 --- a/src/views/spectrumAnalysis/settings.js +++ b/src/views/spectrumAnalysis/settings.js @@ -1,5 +1,12 @@ -import { buildLineSeries } from "@/utils/chartHelper" -import { baseLineCtrlPoint, baseLineSeries, compareLineSeries, lcLineSeries, scacLineSeries, spectrumSeries } from "./seriesBuilder" +import { buildLineSeries } from '@/utils/chartHelper' +import { + baseLineCtrlPoint, + baseLineSeries, + compareLineSeries, + lcLineSeries, + scacLineSeries, + spectrumSeries +} from './seriesBuilder' export const GammaOptions = { option: { @@ -36,6 +43,7 @@ export const GammaOptions = { className: 'figure-chart-option-tooltip' }, xAxis: { + type: 'value', name: 'Channel', nameTextStyle: { color: '#8FD4F8', @@ -105,13 +113,13 @@ export const GammaOptions = { // 缩略图配置 thumbnailOption: { grid: { - top: 0, + top: 5, left: 5, right: 5, - bottom: 0 + bottom: 5 }, xAxis: { - type: 'category', + type: 'value', axisLine: { show: false }, @@ -121,6 +129,9 @@ export const GammaOptions = { axisLabel: { show: false }, + axisTick: { + show: false + }, min: 1, max: 'dataMax' }, @@ -135,6 +146,9 @@ export const GammaOptions = { axisLabel: { show: false }, + axisTick: { + show: false + }, min: 1, max: 'dataMax' }, @@ -159,8 +173,6 @@ export const GammaOptions = { } } -console.log('%c [ ]-162', 'font-size:13px; background:pink; color:#bf2c9f;', GammaOptions.option) - export const graphAssistance = { chartYAxisType: 'Log10', Cursor: true, @@ -168,5 +180,5 @@ export const graphAssistance = { Lc: true, axisType: 'Channel', spectrumType: 'Lines', - SCAC: true, -} \ No newline at end of file + SCAC: true +} From fc7c62b504252e42ff7d700cfc5cb1f04331f16b Mon Sep 17 00:00:00 2001 From: Xu Zhimeng Date: Thu, 26 Oct 2023 13:51:51 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DBeta=E7=82=B9?= =?UTF-8?q?=E5=87=BBQC=20Flags=E5=BC=B9=E7=AA=97=E4=B8=ADDetectorList=20?= =?UTF-8?q?=E4=B8=BAundefined=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8Cgamma?= =?UTF-8?q?=E5=8F=8C=E5=87=BB=E5=9B=BE=E8=A1=A8=E6=94=B9=E4=B8=BA=E6=98=BE?= =?UTF-8?q?=E7=A4=BApeak=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticsParamerHistoryModalForQCFlags.vue | 14 +++++++------- src/views/spectrumAnalysis/gamma-analysis.vue | 7 +------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/views/spectrumAnalysis/components/Modals/BetaGammaModals/StatisticsParamerHistoryModalForQCFlags.vue b/src/views/spectrumAnalysis/components/Modals/BetaGammaModals/StatisticsParamerHistoryModalForQCFlags.vue index 19724c2..281c48b 100644 --- a/src/views/spectrumAnalysis/components/Modals/BetaGammaModals/StatisticsParamerHistoryModalForQCFlags.vue +++ b/src/views/spectrumAnalysis/components/Modals/BetaGammaModals/StatisticsParamerHistoryModalForQCFlags.vue @@ -204,20 +204,20 @@ export default { // 设置左上角台站和探测器列表 setStationAndDetector({ detectorList, stationName, stationId }) { this.queryParams.stationName = stationName - this.detectorList = detectorList.map((item) => ({ - label: item, - value: item, + this.detectorList = detectorList.map(({ detectorCode }) => ({ + label: detectorCode, + value: detectorCode, })) - this.queryParams.detectorName = detectorList[0] + this.queryParams.detectorName = detectorList[0].detectorCode this.queryParams.stationId = stationId }, // 重置左上角查询信息 handleReset() { this.queryParams.stationName = this.initialMDC.stationName - this.detectorList = this.initialMDC.detectorList.map((item) => ({ - label: item, - value: item, + this.detectorList = this.initialMDC.detectorList.map(({ detectorCode }) => ({ + label: detectorCode, + value: detectorCode, })) }, diff --git a/src/views/spectrumAnalysis/gamma-analysis.vue b/src/views/spectrumAnalysis/gamma-analysis.vue index ae5c81e..c711308 100644 --- a/src/views/spectrumAnalysis/gamma-analysis.vue +++ b/src/views/spectrumAnalysis/gamma-analysis.vue @@ -48,7 +48,7 @@ :option="option" :opts="opts" @zr:click="handleChartClick" - @zr:dblclick="handleChartDblClick" + @zr:dblclick="handleTogglePeak" @zr:mousedown="handleMouseDown" @zr:mouseup="handleMouseUp" @brushEnd="handleBrushEnd" @@ -891,11 +891,6 @@ export default { } }, - // 双击还原 - handleChartDblClick() { - this.handleResetChart() - }, - // 获取 Nuclide Library 数据 async getSelPosNuclide(channel) { this.currChannel = channel From df457a3e4f18f5a7fb62934140f3b773baf1e091 Mon Sep 17 00:00:00 2001 From: Xu Zhimeng Date: Thu, 26 Oct 2023 14:45:59 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=BA=95=E9=83=A8?= =?UTF-8?q?significance=E4=B8=8D=E5=8F=98=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/views/spectrumAnalysis/gamma-analysis.vue | 57 +++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/views/spectrumAnalysis/gamma-analysis.vue b/src/views/spectrumAnalysis/gamma-analysis.vue index c711308..241df67 100644 --- a/src/views/spectrumAnalysis/gamma-analysis.vue +++ b/src/views/spectrumAnalysis/gamma-analysis.vue @@ -198,6 +198,7 @@ export default { all: null, baseLineCP: [], }, + peakList: [], // Peak 列表(非点位) nuclideLibraryList: [], // 当前鼠标点击选中的channel peakInfomationTooltip: { @@ -356,7 +357,11 @@ export default { } const nextAxis = markLineXAxis == -1 ? 1 : markLineXAxis + 1 markLineData.xAxis = nextAxis - const { channel: nextChannel, energy: nextEnergy, counts: nextCounts } = this.getEnergyAndCountsByXAxis(nextAxis) + const { + channel: nextChannel, + energy: nextEnergy, + counts: nextCounts, + } = this.getEnergyAndCountsByXAxis(nextAxis) this.setChartBottomTitle(nextChannel, nextEnergy, nextCounts) this.getSelPosNuclide(nextChannel) @@ -545,6 +550,7 @@ export default { shapeChannelData, shapeEnergyData, + peak, } = result if (flag && (flag == 'dab' || flag == 'file')) { this.bAnalyed = result.bAnalyed @@ -556,6 +562,10 @@ export default { this.detailedInfomation = DetailedInformation this.qcFlags = QCFlag + if(peak) { + this.peakList = peak + } + const channelPeakGroup = this.getLineData(allData, 'Peak', 'channel', true) const energyPeakGroup = this.getLineData(allData, 'Peak', 'energy', true) @@ -867,9 +877,48 @@ export default { // 设置图表底部的标题 setChartBottomTitle(channel, energy, counts) { - this.option.title.text = `{a|Channel:${channel}} {a|Energy:${ - energy || 0 - }} {a|Counts:${counts || 0}} {a|Detectability:0}` + const { index, find } = this.findNearPeak(channel) + + this.option.title.text = `{a|Channel:${channel}} {a|Energy:${energy || '0.00'}} {a|Counts:${ + counts || '0.0' + }} {a|Significance:${find ? this.peakList[index].significance.toFixed(2) : '0.00'}}` + }, + + // 查找最近的峰(C++相关) + findNearPeak(channel) { + let t_bFind = false, + i = 0, + peakNum = this.peakList.length + for (; i < peakNum; ++i) { + const peak = this.peakList[i] + if (channel >= peak.left && channel <= peak.right) { + // 如果 channel 在峰的左右边界内 + if (peak.multiIndex > 0 && channel > peak.peakCentroid) { + // 如果是重峰,且 channel 在重峰的第一个峰的中心道右侧 + let j = i + let temp = channel - peak.peakCentroid + while (++j < peakNum && this.peakList[j].multiIndex == peak.multiIndex) { + if (Math.abs(this.peakList[j].peakCentroid - channel) < temp) { + // 找出重峰中峰中心道离 channel 最近的峰 + temp = Math.abs(this.peakList[j].peakCentroid - channel) + i = j + } + } + } + // channel 在索引(i)对应的峰内 + t_bFind = true + break + } else if (peak.left > channel) { + // channel 不在任何峰内,找离它最近的峰 + if (i > 0 && channel - this.peakList[i - 1].peakCentroid < peak.peakCentroid - channel) i -= 1 + break + } + } + if (i >= peakNum) i -= 1 + return { + index: i, + find: t_bFind, + } }, // 根据xAixs值找channel、energy和counts