From 91b1fd3b81eac8ee234ca2ef7f152284f1727b89 Mon Sep 17 00:00:00 2001 From: Xu Zhimeng Date: Thu, 1 Aug 2024 17:29:22 +0800 Subject: [PATCH] =?UTF-8?q?WIP:=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E4=BC=98=E5=8C=96=E8=87=AA=E5=BB=BA?= =?UTF-8?q?=E5=8F=B0=E7=AB=99=E9=A1=B5=E9=9D=A2=E5=88=87=E6=8D=A2=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8=E6=95=88=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/CustomChart/index.vue | 14 +- src/utils/SampleStore.js | 14 +- src/views/spectrumAnalysis/beta-analysis.vue | 40 +-- .../spectrumAnalysis/beta-gamma-analysis.vue | 12 +- .../components/BetaGammaSpectrum.vue | 245 +++++++++++------- .../RoiLimits/components/RoiLimitItem.vue | 2 + src/views/spectrumAnalysis/index.vue | 14 + 7 files changed, 223 insertions(+), 118 deletions(-) diff --git a/src/components/CustomChart/index.vue b/src/components/CustomChart/index.vue index 45f4804..8986be9 100644 --- a/src/components/CustomChart/index.vue +++ b/src/components/CustomChart/index.vue @@ -1,6 +1,6 @@ @@ -26,8 +26,8 @@ export default { }, autoresize: { type: Boolean, - default: false - } + default: false, + }, }, data() { return {} @@ -72,6 +72,14 @@ export default { getZRender() { return this._chart.getZr() }, + + setOption(option, opts) { + this._chart && this._chart.setOption(option, opts) + }, + + getOption() { + return this._chart&& this._chart.getOption() + } }, watch: { option: { diff --git a/src/utils/SampleStore.js b/src/utils/SampleStore.js index a16e82c..c2cc432 100644 --- a/src/utils/SampleStore.js +++ b/src/utils/SampleStore.js @@ -29,7 +29,19 @@ const addSampleData = sampleData => { const updateSampleData = ({ inputFileName, key, data }) => { const find = sampleList.find(item => item.inputFileName == inputFileName) if (find) { - find.data[key] = data + if (key.includes('.')) { + const keys = key.split('.') + const target = keys.reduce((acc, k, index) => { + if (index == keys.length - 1) { + return acc + } + return acc[k] + }, find.data) + + target[keys[keys.length - 1]] = data + } else { + find.data[key] = data + } } } diff --git a/src/views/spectrumAnalysis/beta-analysis.vue b/src/views/spectrumAnalysis/beta-analysis.vue index dd9462c..6475d08 100644 --- a/src/views/spectrumAnalysis/beta-analysis.vue +++ b/src/views/spectrumAnalysis/beta-analysis.vue @@ -48,8 +48,6 @@ ref="betaChartRef" :betaEnergyData="betaEnergyData" :gammaEnergyData="gammaEnergyData" - :histogramDataList="histogramDataList" - :boundary="boundaryList" :isLoading.sync="isLoading" @boundaryChange="handleBoundaryChange" @open-modal="handleOpenModal" @@ -158,13 +156,11 @@ export default { isLoading: false, spectrumData: {}, // Detailed Infomation 信息 spectraType: 'sample', - histogramDataList: [], gammaEnergyData: [], betaEnergyData: [], ROILists: [], ROIAnalyzeLists: [], roiParamList: cloneDeep(InitialRoiParamList), - boundaryList: [], sampleDetail: {}, resultDisplay: [], timerStamp: Date.now(), @@ -191,8 +187,6 @@ export default { } this.ROIAnalyzeLists = [] } - await this.$nextTick() - this.$refs.betaChartRef.handleUnzoom() }, immediate: true, deep: true, @@ -209,6 +203,10 @@ export default { }, methods: { async getAnalyzeCurrentSpectrum() { + if (this.isLoading) { + return + } + try { const { inputFileName, detFileName } = this.sample const userId = store.getters.userInfo.id @@ -397,12 +395,12 @@ export default { this.ROILists = [ROIOneList, ROITwoList, ROIThreeList, ROIFourList] - this.boundaryList = [ + this.$refs.betaChartRef.setBoundaryList([ [ROIOneStart, ROIOneStop], [ROITwoStart, ROITwoStop], [ROIThreeStart, ROIThreeStop], [ROIFourStart, ROIFourStop], - ] + ]) } else { this.isLoading = false this.$message.error(message) @@ -470,7 +468,6 @@ export default { } if (val == 'detBg') this.currSpectrum = 'Det' this.roiParamList = cloneDeep(InitialRoiParamList) - this.boundaryList = [] this.ROILists = [] const { spectrumData, @@ -492,20 +489,22 @@ export default { } = currSampleDetail this.spectrumData = spectrumData - this.histogramDataList = histogramDataList - this.gammaEnergyData = gammaEnergyData - this.betaEnergyData = betaEnergyData - this.ROILists = [ROIOneList, ROITwoList, ROIThreeList, ROIFourList] - this.boundaryList = [ + const boundaryList = [ [ROIOneStart, ROIOneStop], [ROITwoStart, ROITwoStop], [ROIThreeStart, ROIThreeStop], [ROIFourStart, ROIFourStop], ] - this.roiParamList = cloneDeep(this.boundaryList) - + this.roiParamList = cloneDeep(boundaryList) + this.$nextTick(() => { + this.$refs.betaChartRef.setBoundaryList(boundaryList) + this.$refs.betaChartRef.setData(histogramDataList) + }) + this.gammaEnergyData = gammaEnergyData + this.betaEnergyData = betaEnergyData + this.ROILists = [ROIOneList, ROITwoList, ROIThreeList, ROIFourList] this.$bus.$emit('selfAnalyzeSampleTypeChange', val) }, cancelLastRequest() { @@ -533,7 +532,6 @@ export default { // 矩形框范围改变 handleBoundaryChange(evt) { const { index, start, end } = evt - this.$set(this.boundaryList, index, [start, end]) this.$set(this.roiParamList, index, [start, end]) }, @@ -605,12 +603,16 @@ export default { fileName, }) if (success) { + const { DetailedInformation } = result + this.spectrumData = DetailedInformation // 更新缓存中的DetailedInfomation数据 updateSampleData({ inputFileName: fileName, - key: 'DetailedInformation', - data: [...result.DetailedInformation], + key: `${this.spectraType}.spectrumData`, + data: DetailedInformation, }) + + console.log('%c [ ]-617', 'font-size:13px; background:pink; color:#bf2c9f;', getSampleData(fileName)) } else { throw new Error(message) } diff --git a/src/views/spectrumAnalysis/beta-gamma-analysis.vue b/src/views/spectrumAnalysis/beta-gamma-analysis.vue index 581adaf..bc2fe6b 100644 --- a/src/views/spectrumAnalysis/beta-gamma-analysis.vue +++ b/src/views/spectrumAnalysis/beta-gamma-analysis.vue @@ -320,7 +320,7 @@ export default { dbName, sampleId, analyst, - status + status, }, cancelToken ) @@ -715,6 +715,16 @@ export default { return index1 - index2 }) }, + + // 更新所有谱的DetailedInfomation + updateSpectraData(data) { + Object.entries(data).forEach(([k, v]) => { + if (['det', 'gas'].includes(k)) { + k = k + 'Bg' + } + this.sampleDetail[k].spectrumData = v + }) + }, }, watch: { sample: { diff --git a/src/views/spectrumAnalysis/components/BetaGammaSpectrum.vue b/src/views/spectrumAnalysis/components/BetaGammaSpectrum.vue index 8460d10..ce2dacb 100644 --- a/src/views/spectrumAnalysis/components/BetaGammaSpectrum.vue +++ b/src/views/spectrumAnalysis/components/BetaGammaSpectrum.vue @@ -18,14 +18,17 @@
+
+
{{ visualMapMax }}
+
+
0
+
@@ -64,13 +67,15 @@ import CustomChart from '@/components/CustomChart/index.vue' import { getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper.js' import SampleDataMixin from '../SampleDataMixin' +import { cloneDeep } from 'lodash' + const buttons = ['Gamma', 'Beta'] // Beta-Gamma 的配置 -const twoDOption = { +const TwoDOption = { grid: { top: 10, left: 60, - right: 70, + right: 10, bottom: 45, }, tooltip: { @@ -154,7 +159,7 @@ const twoDOption = { }, series: { type: 'scatterGL', - symbolSize: 4, + symbolSize: 2, data: [], itemStyle: { color: '#fff', @@ -162,26 +167,6 @@ const twoDOption = { }, brush: {}, animation: false, - visualMap: { - type: 'continuous', - min: 0, - max: 0, - itemWidth: 12, - itemHeight: 0, - dimension: 2, - seriesIndex: 0, - zlevel: 0, - orient: 'vertical', - right: 0, - bottom: 20, - textStyle: { - color: '#8EC0C8', - }, - calculable: true, - inRange: { - color: ['#ffffff', '#ff0000'], - }, - }, } const ColorList = [ @@ -203,6 +188,17 @@ const ColorList = [ }, ] +const ChartAxis = { + xAxis: { + min: 0, + max: 512, + }, + yAxis: { + min: 0, + max: 4096, + }, +} + export default { mixins: [SampleDataMixin], components: { @@ -212,10 +208,6 @@ export default { isLoading: { type: Boolean, }, - histogramDataList: { - type: Array, - default: () => [], - }, gammaEnergyData: { type: Array, default: () => [], @@ -224,99 +216,138 @@ export default { type: Array, default: () => [], }, - boundary: { - type: Array, - default: () => [], - }, - }, - watch: { - // 2D 图表 - histogramDataList: { - handler() { - this.buildScatterList() - this.setVisialMapParams() - }, - immediate: true, - }, - // 2D 图表 上的 矩形 - boundary: { - handler() { - this.$nextTick(() => { - this.reDrawRect() - }) - }, - // immediate: true, - }, }, data() { this.buttons = buttons return { - twoDOption, showROI: true, myChart: null, startChannel: null, endChannel: null, - opts: { - notMerge: false, - }, boundaryList: [], // 最终生成的框 boundaryContainerPosition: {}, isLog: true, // 当前右侧的图表是否是log currBoundaryItem: null, // 当前正在操作的方框 + + visualMapMax: 0, + + chartAxis: cloneDeep(ChartAxis), + boundary: [], } }, created() { + this.scatterList = [] + this.boundary = [] this.$bus.$on('roiLimitItemChange', this.handleLimitItemChange) }, beforeDestroy() { this.$bus.$off('roiLimitItemChange', this.handleLimitItemChange) }, mounted() { - this.opts.notMerge = true - this.$nextTick(() => { - this.opts.notMerge = false - this.twoDOption.brush = { toolbox: [] } - this.setVisualMapHeight() - }) + this.setOption(cloneDeep(TwoDOption)) }, methods: { + setData(histogramDataList) { + this.histogramDataList = histogramDataList + this.setVisialMapParams() + this.buildScatterList() + this.initChart() + }, + + setBoundaryList(boundary) { + this.boundary = boundary + }, + + setOption(option, opts) { + this.$refs.chartTwoDRef.setOption(option, opts) + }, + + initChart() { + this.chartAxis = cloneDeep(ChartAxis) + + this.setOption({ + ...this.chartAxis, + series: { + data: this.scatterList, + }, + }) + + this.reDrawRect() + }, + // 构造scatter列表 buildScatterList() { + this.$bus.$emit('roiLimitItemUnzoom') + console.time('buildScatterList') + this.scatterList = this.histogramDataList + .filter(({ c }) => c) + .map(({ b, g, c }) => this.buildScatterItem(b, g, c)) + console.timeEnd('buildScatterList') + }, + + rangeScatter() { + console.time('rangeScatter') + const { xAxis: { min: minX, max: maxX }, yAxis: { min: minY, max: maxY }, - } = this.twoDOption + } = this.chartAxis - //点大小 - this.twoDOption.series.symbolSize = 2 - this.twoDOption.series.data = this.histogramDataList - .filter(({ b, g, c }) => c && b >= minX && b <= maxX && g >= minY && g <= maxY) - .map(({ b, g, c }) => this.buildScatterItem(b, g, c)) + this.setOption({ + xAxis: { + min: minX, + max: maxX, + }, + yAxis: { + min: minY, + max: maxY, + }, + series: { + data: this.scatterList.filter(({ value: [b, g] }) => b >= minX && b <= maxX && g >= minY && g <= maxY), + }, + }) + console.timeEnd('rangeScatter') }, // 构造一个scatter 的点 buildScatterItem(xAxis, yAxis, count) { + const { r, g, b } = this.interpolateColor(1 - count / this.visualMapMax) + return { - value: [xAxis, yAxis, count], + value: [xAxis, yAxis], + itemStyle: { + color: `rgb(${r}, ${g}, ${b})`, + }, } }, setVisialMapParams() { const counts = this.histogramDataList.filter(({ c }) => c).map(({ c }) => c) if (counts.length) { - this.twoDOption.visualMap.max = counts.sort((a, b) => b - a)[0] + this.visualMapMax = counts.sort((a, b) => b - a)[0] } else { - this.twoDOption.visualMap.max = 0 + this.visualMapMax = 0 } }, + // 颜色插值算法 + interpolateColor(percentage) { + const color1 = { r: 255, g: 0, b: 0 }, + color2 = { r: 255, g: 255, b: 255 } + + 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 } + }, + // 重绘矩形框区域 reDrawRect() { const chart = this.$refs.chartTwoDRef.getChartInstance() // 得到外层容器四至范围 - const { min: xMin, max: xMax } = this.twoDOption.xAxis - const { min: yMin, max: yMax } = this.twoDOption.yAxis + const { min: xMin, max: xMax } = this.chartAxis.xAxis + const { min: yMin, max: yMax } = this.chartAxis.yAxis const [containerLeft, containerTop] = chart.convertToPixel({ seriesIndex: 0 }, [xMin, yMax]) // 拿到外层容器左上角坐标 const [containerRight, containerBottom] = chart.convertToPixel({ seriesIndex: 0 }, [xMax, yMin]) // 拿到外层容器右下角坐标 this.boundaryContainerPosition = { @@ -349,14 +380,8 @@ export default { } }, - setVisualMapHeight() { - const chartContainerRef = this.$refs.chartContainerRef - this.twoDOption.visualMap.itemHeight = chartContainerRef.offsetHeight - 40 - }, - handleChartResize() { this.reDrawRect() - this.setVisualMapHeight() }, // 弹出gamma或beta弹窗 @@ -365,11 +390,8 @@ export default { }, // 点击unzoom handleUnzoom() { - this.twoDOption.xAxis.min = 0 - this.twoDOption.xAxis.max = 512 - this.twoDOption.yAxis.min = 0 - this.twoDOption.yAxis.max = 4096 - this.buildScatterList() + this.chartAxis = cloneDeep(ChartAxis) + this.rangeScatter() this.$nextTick(() => { this.reDrawRect() @@ -380,10 +402,16 @@ export default { // 右侧四个图表范围变化 handleLimitItemChange(x1, x2) { - this.twoDOption.yAxis.min = x1 - this.twoDOption.yAxis.max = x2 + this.chartAxis.yAxis = { + min: x1, + max: x2, + } - this.buildScatterList() + this.setOption({ + yAxis: { min: x1, max: x2 }, + }) + + this.rangeScatter() this.$nextTick(() => { this.reDrawRect() @@ -436,17 +464,28 @@ export default { const rangeNumberFuncX = rangeNumber(0, 512) const rangeNumberFuncY = rangeNumber(0, 4096) - this.twoDOption.xAxis.min = rangeNumberFuncX(x1) - this.twoDOption.xAxis.max = rangeNumberFuncX(x2) - this.twoDOption.yAxis.min = rangeNumberFuncY(y1) - this.twoDOption.yAxis.max = rangeNumberFuncY(y2) - this.buildScatterList() + const xAxisMin = rangeNumberFuncX(x1), + xAxisMax = rangeNumberFuncX(x2), + yAxisMin = rangeNumberFuncY(y1), + yAxisMax = rangeNumberFuncY(y2) + this.chartAxis = { + xAxis: { + min: xAxisMin, + max: xAxisMax, + }, + yAxis: { + min: yAxisMin, + max: yAxisMax, + }, + } + + this.rangeScatter() // this.emitRangeChange([x1, x2, y1, y2]) this.$nextTick(() => { this.reDrawRect() }) - this.$bus.$emit('roiLimitItemChange', this.twoDOption.yAxis.min, this.twoDOption.yAxis.max) + this.$bus.$emit('SelfStationBetaSpectrumChange', this.chartAxis.yAxis.min, this.chartAxis.yAxis.max) } this.clearBrush(chart) @@ -579,7 +618,25 @@ export default { display: flex; .custom-chart { - width: 100%; + width: calc(100% - 45px); + } + + .bar { + width: 30px; + margin-left: 10px; + color: #ade6ee; + padding-top: 5px; + padding-bottom: 20px; + display: flex; + flex-direction: column; + align-items: center; + gap: 5px; + + &-main { + width: 14px; + flex: 1; + background: linear-gradient(to bottom, #ff0000 0, #fff 100%); + } } } } diff --git a/src/views/spectrumAnalysis/components/RoiLimits/components/RoiLimitItem.vue b/src/views/spectrumAnalysis/components/RoiLimits/components/RoiLimitItem.vue index 6a3bd47..2780ab6 100644 --- a/src/views/spectrumAnalysis/components/RoiLimits/components/RoiLimitItem.vue +++ b/src/views/spectrumAnalysis/components/RoiLimits/components/RoiLimitItem.vue @@ -177,6 +177,7 @@ export default { this.$bus.$on('changeROILimitsYAxisType', this.changeYAxisType) this.$bus.$on('roiLimitItemUnzoom', this.handleUnZoom) this.$bus.$on('roiLimitItemChange', this.handleLimitItemChange) + this.$bus.$on('SelfStationBetaSpectrumChange', this.handleLimitItemChange) }, mounted() { this.option.brush = { toolbox: [] } @@ -185,6 +186,7 @@ export default { this.$bus.$off('changeROILimitsYAxisType', this.changeYAxisType) this.$bus.$off('roiLimitItemUnzoom', this.handleUnZoom) this.$bus.$off('roiLimitItemChange', this.handleLimitItemChange) + this.$bus.$off('SelfStationBetaSpectrumChange', this.handleLimitItemChange) }, methods: { handleTooltipFormat(params) { diff --git a/src/views/spectrumAnalysis/index.vue b/src/views/spectrumAnalysis/index.vue index 272cbf0..5847a24 100644 --- a/src/views/spectrumAnalysis/index.vue +++ b/src/views/spectrumAnalysis/index.vue @@ -946,6 +946,8 @@ export default { console.error(error) } }, + + // beta-gamma的保存到DB handleSaveResultsToDB_Cuurrent() { // xeflag params_toDB if (this.params_toDB.savedAnalysisResult) { @@ -972,6 +974,18 @@ export default { this.$message.success('Save Successfully!') this.isSaving = false this.sampleInfo = res.result.sample + + this.$refs.betaGammaAnalysisRef.updateSpectraData(res.result) + Object.entries(res.result).forEach(([k, v]) => { + if (['det', 'gas'].includes(k)) { + k = k + 'Bg' + } + updateSampleData({ + inputFileName: this.sampleData.inputFileName, + key: `${k}.spectrumData`, + data: v, + }) + }) } else { this.isSaving = false this.$message.warning(`${res.message}`)