feat: 完成 Beta Gamma Energy Calibration 弹窗中所有交互逻辑及接口对接,修复ResultDisplay中Concerntration背景问题,优化图表interval计算逻辑

This commit is contained in:
Xu Zhimeng 2023-07-26 19:35:36 +08:00
parent f3999c3643
commit d9c63c9bce
8 changed files with 675 additions and 209 deletions

View File

@ -17,4 +17,26 @@ export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex
return [xAxis, yAxis]
}
return null
}
/**
* 将图表导出为图片
* @param {import("echarts").ECharts} chartInstance
* @param {'png' | 'jpeg' | 'svg'} type
*/
export function exportEchartImg(chartInstance, type = 'png') {
const dataURL = chartInstance.getDataURL({
type,
pixelRatio: 2,
backgroundColor: '#022024'
});
const link = document.createElement('a')
link.style.display = 'none'
link.href = dataURL
link.setAttribute('download', 'export.png')
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
}

View File

@ -1,123 +1,168 @@
<template>
<div class="beta-detector-calibration">
<div class="content">
<div class="QCs">
<div class="beta-gamma-spectrum">
<p>Beta-Gamma Spectrum: QC</p>
<a-spin :spinning="isLoading">
<div class="content">
<div class="QCs">
<div class="beta-gamma-spectrum">
<p>Beta-Gamma Spectrum: QC</p>
<div class="content">
<div class="settings">
<div class="channel-and-width">
<span> Channel: {{ betaGammaInfo.channel }} </span>
<span>
Gamma Channel Width:
<a-input-number :min="1" v-model="gammaChannelWidth"></a-input-number>
</span>
</div>
<div class="energy">
Energy: <span>{{ betaGammaInfo.energy }}</span>
</div>
</div>
<div class="beta-gamma-chart">
<custom-chart
ref="betaGammaChartRef"
:option="betaGammaChartOption"
@zr:click="handleBetaGammaChartClick"
@zr:mousemove="handleBetaGammaChartMouseMove"
/>
<!-- 数据量太大的时候echarts会重绘故采用自定义markLine和rect的形式 -->
<div v-if="markLineVisible" class="markline" :style="{ top: markLinePosition.top + 'px' }"></div>
<div
v-if="rectVisible"
class="rect"
:style="{ top: rectPosition.top + 'px', height: rectHeight + 'px' }"
></div>
</div>
</div>
</div>
<div class="gamma-gated-beta-spectrum">
<p>Gamma-gated Beta Spectrum: QC</p>
<div class="content">
<div class="gamma-gated-chart">
<custom-chart
ref="gammaGatedChartRef"
:option="gammaGatedChartOption"
@zr:click="handleGammaGatedSpectrumChartClick"
/>
<a-button type="primary" size="small" @click="handleSnapshot($refs.gammaGatedChartRef)"
>Snapshot</a-button
>
<!-- 自定义tooltip用于点击图表后的tooltip显示 -->
<div
v-if="tooltipVisible"
class="custom-tool-tip"
:style="{
top: tooltipPosition.top + 'px',
left: tooltipPosition.left + 'px'
}"
>
<div class="channel">Channel: {{ tooltipChannel }}</div>
</div>
<!-- tooltip结束 -->
</div>
</div>
<div class="content channel-and-energy">
<a-form-model layout="inline">
<a-form-model-item label="Channel">
<a-input type="number" v-model="channelAndEnergyModel.channel"></a-input>
</a-form-model-item>
<a-form-model-item label="Energy">
<a-input type="number" v-model="channelAndEnergyModel.energy"></a-input>
</a-form-model-item>
</a-form-model>
<a-button type="primary" @click="handleAddChannelAndEnergy">Add</a-button>
</div>
<a-table
size="small"
:columns="columns"
:dataSource="list"
:pagination="false"
:class="list.length ? 'has-data' : ''"
:scroll="{ y: 99 }"
>
<template slot="operation" slot-scope="text, record, index">
<a-icon type="delete" style="color: #f00;" @click="handleDel(index)"></a-icon>
</template>
</a-table>
</div>
</div>
<div class="figure">
<p class="title">Figure of Beta Detector Calibration</p>
<div class="content">
<div class="settings">
<div class="channel-and-width">
<span> Channel: 210 </span>
<span>
Gamma Channel Width:
<a-input-number></a-input-number>
</span>
</div>
<div class="energy">Energy: <span>599.97</span></div>
</div>
<div class="beta-gamma-chart">
<custom-chart :option="betaGammaChartOption" />
<div class="figure-chart">
<custom-chart ref="figureChartRef" :option="figureChartOption" />
<a-button type="primary" size="small" @click="handleSnapshot($refs.figureChartRef)">Snapshot</a-button>
</div>
</div>
</div>
<div class="gamma-gated-beta-spectrum">
<p>Gamma-gated Beta Spectrum: QC</p>
<div class="content">
<div class="gamma-gated-chart">
<custom-chart :option="gammaGatedChartOption" />
<a-button type="primary" size="small">Snapshot</a-button>
<div class="calibration-parameter">
<p>Calibration Parameter of Beta Detector</p>
<div class="calibration-funcs">
<div class="calibration-funcs-func">
<title-over-border title="Old Calibration Function">
<p class="func">
<span>C to E : </span>
<span
>E = {{ scientificNotationStr2Fixed(c2e[0]) }} + {{ scientificNotationStr2Fixed(c2e[1]) }} *C +
{{ scientificNotationStr2Fixed(c2e[2]) }} *C <sup>2</sup>
</span>
</p>
<div class="func">
<span>E to C : </span>
<span
>C = {{ scientificNotationStr2Fixed(e2c[0]) }} + {{ scientificNotationStr2Fixed(e2c[1]) }} *E +
{{ scientificNotationStr2Fixed(e2c[2]) }} *E <sup>2</sup>
</span>
</div>
</title-over-border>
<title-over-border title="New Calibration Function">
<p class="func">
<span>C to E : </span>
<span>
E =
<a-input type="number" size="small" v-model="newCalibrationFuncModel[0]" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[1]" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[2]" /> *C <sup>2</sup>
</span>
</p>
<div class="func">
<span>E to C : </span>
<span>C = 0 + 0 *E + 0 *E <sup>2</sup> </span>
</div>
</title-over-border>
</div>
<div class="calibration-funcs-btns">
<a-button type="primary" @click="handleReset">Reset Button</a-button>
<a-button type="primary" @click="handleFitting">Fitting</a-button>
</div>
</div>
<div class="content channel-and-energy">
<a-form-model layout="inline">
<a-form-model-item label="Channel">
<a-input></a-input>
</a-form-model-item>
<a-form-model-item label="Energy">
<a-input></a-input>
</a-form-model-item>
</a-form-model>
<a-button type="primary">Add</a-button>
</div>
<a-table
size="small"
:columns="columns"
:dataSource="list"
:pagination="false"
:class="list.length ? 'has-data' : ''"
:scroll="{ y: 99 }"
></a-table>
</div>
</div>
<div class="figure">
<p class="title">Figure of Beta Detector Calibration</p>
<div class="content">
<div class="figure-chart">
<custom-chart :option="figureChartOption" />
<a-button type="primary" size="small">Snapshot</a-button>
</div>
<div class="footer">
<title-over-border title="New Calibration is Applied to">
<a-radio-group v-model="newCalibrationIsAppliedTo">
<p>
<a-radio value="1">All Spectra</a-radio>
</p>
<a-radio value="2">Current Spectrum</a-radio>
</a-radio-group>
</title-over-border>
<title-over-border title="Recalculate ROI Counts For">
<a-checkbox-group v-model="recalculateROICountsFor">
<p>
<a-checkbox value="sample">Sample Data</a-checkbox>
<a-checkbox value="gasBg">GasBg Data</a-checkbox>
</p>
<a-checkbox value="detBg">DetBg Data</a-checkbox>
<a-checkbox value="qc">QC Data</a-checkbox>
</a-checkbox-group>
</title-over-border>
<div class="footer-btns">
<a-button type="primary">Reanalyse Spectrum Using New Calibration</a-button>
<a-button type="primary" class="exit" @click="handleExit()">Exit</a-button>
</div>
</div>
<div class="calibration-parameter">
<p>Calibration Parameter of Beta Detector</p>
<div class="calibration-funcs">
<div class="calibration-funcs-func">
<title-over-border title="Old Calibration Function">
<p>
<span>C to E : </span>
<span>E = 12.0809 + 2.39764 *C + 0.00331138 *C <sup>2</sup> </span>
</p>
<div>
<span>E to C : </span>
<span>C = -2.83996 + 0.386245 *E + -9.63318e-05 *E <sup>2</sup> </span>
</div>
</title-over-border>
<title-over-border title="New Calibration Function">
<p>
<span>C to E : </span>
<span>
E =
<a-input type="number" size="small" /> + <a-input type="number" size="small" /> *C +
<a-input type="number" size="small" /> *C <sup>2</sup>
</span>
</p>
<div>
<span>E to C : </span>
<span>C = 0 + 0 *E + 0 *E <sup>2</sup> </span>
</div>
</title-over-border>
</div>
<div class="calibration-funcs-btns">
<a-button type="primary">Reset Button</a-button>
<a-button type="primary">Fitting</a-button>
</div>
</div>
</div>
</div>
<div class="footer">
<title-over-border title="New Calibration is Applied to">
<a-radio-group>
<p>
<a-radio>All Spectra</a-radio>
</p>
<a-radio>Current Spectrum</a-radio>
</a-radio-group>
</title-over-border>
<title-over-border title="Recalculate ROI Counts For">
<a-checkbox-group>
<p>
<a-checkbox>Sample Data</a-checkbox>
<a-checkbox>GasBg Data</a-checkbox>
</p>
<a-checkbox>DetBg Data</a-checkbox>
<a-checkbox>QC Data</a-checkbox>
</a-checkbox-group>
</title-over-border>
<div class="footer-btns">
<a-button type="primary">Reanalyse Spectrum Using New Calibration</a-button>
<a-button type="primary" class="exit" @click="handleExit()">Exit</a-button>
</div>
</div>
</a-spin>
</div>
</template>
@ -125,6 +170,8 @@
import CustomChart from '@/components/CustomChart/index.vue'
import TitleOverBorder from '@/views/spectrumAnalysis/components/TitleOverBorder.vue'
import { getAction } from '@/api/manage'
import { cloneDeep } from 'lodash'
import { exportEchartImg, getXAxisAndYAxisByPosition } from '@/utils/chartHelper'
const initialBetaGammaChartOption = {
grid: {
@ -133,20 +180,6 @@ const initialBetaGammaChartOption = {
right: 10,
bottom: 45
},
tooltip: {
trigger: 'item',
formatter: params => {
const [b, g, c] = params.value
return `Beta: ${b}<br>Gamma: ${g}<br>Count: ${c}`
},
axisPointer: {
animation: false,
type: 'cross',
lineStyle: {
type: 'dashed'
}
}
},
xAxis: {
name: 'Beta Channel',
nameTextStyle: {
@ -209,7 +242,7 @@ const initialBetaGammaChartOption = {
},
series: {
type: 'scatter',
symbolSize: 5,
symbolSize: 2,
data: [],
itemStyle: {
color: '#fff'
@ -223,6 +256,19 @@ const initialGammaGatedChartOption = {
right: 15,
bottom: 50
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#099D24'
}
},
formatter: params => {
const [channel] = params[0].value
return `<div class="channel">Channel: ${channel}</div>`
},
className: 'figure-chart-option-tooltip'
},
xAxis: {
min: 0,
max: 256,
@ -288,7 +334,21 @@ const initialGammaGatedChartOption = {
color: '#04ADD9'
},
symbol: 'none',
data: []
data: [],
markLine: {
symbol: 'none',
label: {
show: false
},
animation: false,
emphasis: {
disabled: true
},
lineStyle: {
color: '#f00'
},
data: []
}
}
}
@ -298,6 +358,20 @@ const initialFigureChartOption = {
right: 15,
bottom: 50
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#099D24'
}
},
formatter: params => {
const [channel, energy] = params[0].value
return `<div class="channel">Channel: ${channel}</div>
<div class="energy">Energy: ${energy.toFixed(3)}</div>`
},
className: 'figure-chart-option-tooltip'
},
xAxis: {
min: 0,
max: 256,
@ -355,7 +429,7 @@ const initialFigureChartOption = {
fontSize: 14,
color: '#5b9cba'
},
nameGap: 25
nameGap: 55
},
series: {
type: 'line',
@ -397,8 +471,10 @@ const columns = [
},
{
title: 'S',
dataIndex: 'sValue',
align: 'center'
align: 'center',
scopedSlots: {
customRender: 'operation'
}
}
]
@ -413,33 +489,43 @@ export default {
this.columns = columns
return {
betaGammaChartOption: initialBetaGammaChartOption,
gammaGatedChartOption: initialGammaGatedChartOption,
figureChartOption: initialFigureChartOption,
list: [
{
channel: 'channel',
energy: 'energy',
fwhmC: 'fwhmC',
fwhmKev: 'fwhmKev',
sValue: 'sValue'
},
{
channel: 'channel',
energy: 'energy',
fwhmC: 'fwhmC',
fwhmKev: 'fwhmKev',
sValue: 'sValue'
},
{
channel: 'channel',
energy: 'energy',
fwhmC: 'fwhmC',
fwhmKev: 'fwhmKev',
sValue: 'sValue'
}
],
isLoading: false
betaGammaChartOption: cloneDeep(initialBetaGammaChartOption),
gammaGatedChartOption: cloneDeep(initialGammaGatedChartOption),
figureChartOption: cloneDeep(initialFigureChartOption),
list: [],
isLoading: false,
gammaEnergy: [],
gammaGatedBetaSpectrum: [],
gammaChannelWidth: 5, // Gamma Channel Width
betaGammaInfo: {}, // channelenergy
markLineVisible: false,
markLinePosition: {
top: 0
},
rectVisible: false,
rectPosition: {
top: 0
},
tooltipVisible: false,
tooltipPosition: {
top: 0,
left: 0
},
channelAndEnergyModel: {},
c2e: {},
e2c: {},
newCalibrationFuncModel: [],
newCalibrationIsAppliedTo: '2',
recalculateROICountsFor: []
}
},
created() {
@ -460,6 +546,22 @@ export default {
})
console.log('%c [ res ]-462', 'font-size:13px; background:pink; color:#bf2c9f;', res)
if (res.success) {
const { CToE, EToC, betaEnergy, gammaEnergy, gammaGatedBetaSpectrum, histogramData } = res.result
this.c2e = CToE
this.e2c = EToC
this.betaGammaChartOption.series.data = histogramData.map(({ b, g, c }) => [b, g, c])
this.gammaEnergy = gammaEnergy
this.gammaGatedBetaSpectrum = gammaGatedBetaSpectrum
const gammaEnergyValue = betaEnergy.map(item => item[0])
const gammaEnergyMax = Math.ceil(Math.max(...gammaEnergyValue))
const gammaEnergyMin = Math.floor(Math.min(...gammaEnergyValue))
const gammaEnergyInterval = Math.ceil(((gammaEnergyMax - gammaEnergyMin) / 4) * 1.1)
this.figureChartOption.yAxis.max = gammaEnergyInterval * 4
this.figureChartOption.yAxis.min = gammaEnergyMin
this.figureChartOption.yAxis.interval = Math.ceil((gammaEnergyMax * 1.1) / 4)
this.figureChartOption.series.data = gammaEnergyValue.map((item, index) => [index, item])
} else {
this.$message.error(res.message)
}
@ -468,6 +570,126 @@ export default {
} finally {
this.isLoading = false
}
},
// 线
handleBetaGammaChartClick(param) {
const { offsetX, offsetY } = param
const point = getXAxisAndYAxisByPosition(this.$refs.betaGammaChartRef.getChartInstance(), offsetX, offsetY)
if (point) {
this.markLinePosition.top = offsetY
this.markLineVisible = true
// gamma-gated beta spectrum
const yAxis = parseInt(point[1].toFixed())
this.currEnergy = this.gammaEnergy[yAxis][0].toFixed(2) // Energy
this.channelAndEnergyModel = {}
const currGammaGatedBetaSpectrum = this.gammaGatedBetaSpectrum[yAxis]
const max = Math.max(...currGammaGatedBetaSpectrum)
const interval = Math.ceil((max / 4) * 1.1)
this.gammaGatedChartOption.yAxis.max = interval * 4
this.gammaGatedChartOption.yAxis.interval = interval
this.gammaGatedChartOption.series.data = currGammaGatedBetaSpectrum.map((item, index) => [index, item])
}
},
// 绿
handleBetaGammaChartMouseMove(param) {
const { offsetX, offsetY } = param
const point = getXAxisAndYAxisByPosition(this.$refs.betaGammaChartRef.getChartInstance(), offsetX, offsetY)
if (point) {
this.rectPosition.top = offsetY
this.rectVisible = true
if (this.gammaEnergy && this.gammaEnergy.length) {
// Channel Energy
const yAxis = parseInt(point[1].toFixed())
const energy = this.gammaEnergy[yAxis][0].toFixed(2)
this.betaGammaInfo = {
channel: yAxis,
energy
}
}
}
},
// Gamma Gated Beta Spectrum: QC
handleGammaGatedSpectrumChartClick(param) {
const { offsetX, offsetY } = param
const point = getXAxisAndYAxisByPosition(this.$refs.gammaGatedChartRef.getChartInstance(), offsetX, offsetY)
if (point) {
const xAxis = parseInt(point[0].toFixed())
this.gammaGatedChartOption.series.markLine.data = [{ xAxis }]
this.tooltipChannel = xAxis
this.tooltipPosition.top = offsetY
if (xAxis > 187) {
this.tooltipPosition.left = offsetX - 125
} else {
this.tooltipPosition.left = offsetX + 20
}
this.tooltipVisible = true
this.channelAndEnergyModel.channel = xAxis
this.channelAndEnergyModel.energy = this.currEnergy
}
},
// Channel Energy
handleAddChannelAndEnergy() {
const { channel, energy } = this.channelAndEnergyModel
if (!channel || !energy) {
return
}
this.list.push({
channel,
energy
})
this.channelAndEnergyModel = {}
},
//
handleDel(index) {
this.list.splice(index, 1)
},
//
handleSnapshot(chartRef) {
const chartInstance = chartRef.getChartInstance()
exportEchartImg(chartInstance)
},
// Reset Button
handleReset() {
this.newCalibrationFuncModel = []
},
// Fitting
handleFitting() {},
/**
* 返回的科学计数法的字符串处理
* @param {string} str
*/
scientificNotationStr2Fixed(str) {
if (str) {
const arr = str.split('E')
const start = arr[0]
const end = arr[1]
return `${Number(start).toPrecision(6)}${end ? 'e' + end : ''}`
}
return ''
}
},
computed: {
rectHeight() {
const { top, bottom } = initialBetaGammaChartOption.grid
const totalHeight = 427 - top - bottom
return (totalHeight / 256) * this.gammaChannelWidth
}
}
}
@ -502,6 +724,26 @@ p {
.beta-gamma-chart {
height: 427px;
position: relative;
.markline {
position: absolute;
left: 55px;
width: 442px;
height: 1px;
background-color: red;
pointer-events: none;
}
.rect {
position: absolute;
left: 55px;
width: 442px;
border: 1px solid #0f0;
background-color: rgba(0, 255, 0, 0.4);
transform: translateY(-50%);
pointer-events: none;
}
}
}
@ -526,6 +768,10 @@ p {
align-items: center;
.ant-input {
width: 120px;
}
.ant-btn {
width: 100px;
}
}
@ -595,6 +841,17 @@ p {
.ant-input {
width: 70px;
}
.func {
display: flex;
span {
&:nth-child(2) {
flex: 1;
text-align: center;
}
}
}
}
&-btns {
@ -637,4 +894,37 @@ p {
}
}
}
.custom-tool-tip {
position: absolute;
border-style: solid;
white-space: nowrap;
z-index: 99999;
box-shadow: rgba(0, 0, 0, 0.2) 1px 2px 10px;
border-width: 1px;
border-radius: 4px;
padding: 10px;
border-color: rgb(255, 255, 255);
pointer-events: none;
background-color: #00aa7f;
border-color: #00aa7f;
.channel {
color: #fff;
}
}
</style>
<style lang="less">
.figure-chart-option-tooltip {
background-color: #00aa7f !important;
border-color: #00aa7f !important;
.channel {
color: #fff;
}
.energy {
color: #00d1f0;
}
}
</style>

View File

@ -11,19 +11,31 @@
:option="gammaSpectrumChartOption"
@zr:click="handleGammaSpectrumChartClick"
/>
<a-button type="primary">Snapshot</a-button>
<a-button type="primary" @click="handleSnapshot($refs.gammaSpectrumChart)">Snapshot</a-button>
<!-- 自定义tooltip用于点击图表后的tooltip显示 -->
<div
v-if="tooltipVisible"
class="custom-tool-tip"
:style="{
top: tooltipPosition.top + 'px',
left: tooltipPosition.left + 'px'
}"
>
<div class="channel">Channel: {{ tooltipChannel }}</div>
</div>
<!-- tooltip结束 -->
</div>
</div>
<div class="content channel-and-energy">
<a-form-model layout="inline">
<a-form-model-item label="Channel">
<a-input></a-input>
<a-input v-model="channelAndEnergyModel.channel"></a-input>
</a-form-model-item>
<a-form-model-item label="Energy">
<a-input></a-input>
<a-input ref="energyInputRef" v-model="channelAndEnergyModel.energy"></a-input>
</a-form-model-item>
</a-form-model>
<a-button type="primary">Add</a-button>
<a-button type="primary" @click="handleAddChannelAndEnergy">Add</a-button>
</div>
<a-table
size="small"
@ -32,14 +44,18 @@
:pagination="false"
:class="list.length ? 'has-data' : ''"
:scroll="{ y: 99 }"
></a-table>
>
<template slot="operation" slot-scope="text, record, index">
<a-icon type="delete" style="color: #f00;" @click="handleDel(index)"></a-icon>
</template>
</a-table>
</div>
<div class="figure">
<p class="title">Figure of Gamma Detector Calibration</p>
<div class="content">
<div class="figure-chart">
<custom-chart :option="figureChartOption" />
<a-button type="primary">Snapshot</a-button>
<custom-chart ref="figureChartRef" :option="figureChartOption" />
<a-button type="primary" @click="handleSnapshot($refs.figureChartRef)">Snapshot</a-button>
</div>
</div>
</div>
@ -71,8 +87,9 @@
<span>C to E : </span>
<span>
E =
<a-input type="number" size="small" /> + <a-input type="number" size="small" /> *C +
<a-input type="number" size="small" /> *C <sup>2</sup>
<a-input type="number" size="small" v-model="newCalibrationFuncModel[0]" /> +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[1]" /> *C +
<a-input type="number" size="small" v-model="newCalibrationFuncModel[2]" /> *C <sup>2</sup>
</span>
</p>
<div class="func">
@ -82,29 +99,29 @@
</title-over-border>
</div>
<div class="calibration-funcs-btns">
<a-button type="primary">Reset Button</a-button>
<a-button type="primary">Fitting</a-button>
<a-button type="primary" @click="handleReset">Reset Button</a-button>
<a-button type="primary" @click="handleFitting">Fitting</a-button>
</div>
</div>
</div>
</div>
<div class="footer">
<title-over-border title="New Calibration is Applied to">
<a-radio-group>
<a-radio-group v-model="newCalibrationIsAppliedTo">
<p>
<a-radio>All Spectra</a-radio>
<a-radio value="1">All Spectra</a-radio>
</p>
<a-radio>Current Spectrum</a-radio>
<a-radio value="2">Current Spectrum</a-radio>
</a-radio-group>
</title-over-border>
<title-over-border title="Recalculate ROI Counts For">
<a-checkbox-group>
<a-checkbox-group v-model="recalculateROICountsFor">
<p>
<a-checkbox>Sample Data</a-checkbox>
<a-checkbox>GasBg Data</a-checkbox>
<a-checkbox value="sample">Sample Data</a-checkbox>
<a-checkbox value="gasBg">GasBg Data</a-checkbox>
</p>
<a-checkbox>DetBg Data</a-checkbox>
<a-checkbox>QC Data</a-checkbox>
<a-checkbox value="detBg">DetBg Data</a-checkbox>
<a-checkbox value="qc">QC Data</a-checkbox>
</a-checkbox-group>
</title-over-border>
<div class="footer-btns">
@ -121,7 +138,9 @@ import CustomChart from '@/components/CustomChart/index.vue'
import TitleOverBorder from '@/views/spectrumAnalysis/components/TitleOverBorder.vue'
import { getAction } from '@/api/manage'
import { graphic } from 'echarts'
import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper'
import { exportEchartImg, getXAxisAndYAxisByPosition } from '@/utils/chartHelper'
import { cloneDeep } from 'lodash'
const initialGammaSpectrumChartOption = {
grid: {
@ -219,7 +238,21 @@ const initialGammaSpectrumChartOption = {
])
},
symbol: 'none',
data: []
data: [],
markLine: {
symbol: 'none',
label: {
show: false
},
animation: false,
emphasis: {
disabled: true
},
lineStyle: {
color: '#f00'
},
data: []
}
}
}
@ -342,8 +375,10 @@ const columns = [
},
{
title: 'S',
dataIndex: 'sValue',
align: 'center'
align: 'center',
scopedSlots: {
customRender: 'operation'
}
}
]
@ -358,12 +393,26 @@ export default {
this.columns = columns
return {
gammaSpectrumChartOption: initialGammaSpectrumChartOption,
figureChartOption: initialFigureChartOption,
gammaSpectrumChartOption: cloneDeep(initialGammaSpectrumChartOption),
figureChartOption: cloneDeep(initialFigureChartOption),
list: [],
isLoading: false,
c2e: {},
e2c: {}
e2c: {},
tooltipVisible: false,
tooltipPosition: {
top: 0,
left: 0
},
tooltipChannel: '',
channelAndEnergyModel: {},
newCalibrationFuncModel: [],
newCalibrationIsAppliedTo: '2',
recalculateROICountsFor: []
}
},
created() {
@ -389,16 +438,18 @@ export default {
this.c2e = CToE
this.e2c = EToC
this.gammaSpectrumChartOption.yAxis.max = Math.ceil(max * 1.1)
const interval = Math.ceil(((max - min) / 4) * 1.1)
this.gammaSpectrumChartOption.yAxis.max = interval * 4
this.gammaSpectrumChartOption.yAxis.min = min
this.gammaSpectrumChartOption.yAxis.interval = Math.ceil((max * 1.1) / 4)
this.gammaSpectrumChartOption.yAxis.interval = interval
this.gammaSpectrumChartOption.series.data = gammaSpectrum.map(({ x, y }) => [x, y])
const gammaEnergyValue = gammaEnergy.map(item => item[0])
const gammaEnergyMax = Math.max(...gammaEnergyValue)
const gammaEnergyMin = Math.min(...gammaEnergyValue)
this.figureChartOption.yAxis.max = Math.ceil(gammaEnergyMax * 1.1)
this.figureChartOption.yAxis.min = Math.floor(gammaEnergyMin)
const gammaEnergyMax = Math.ceil(Math.max(...gammaEnergyValue))
const gammaEnergyMin = Math.floor(Math.min(...gammaEnergyValue))
const gammaEnergyInterval = Math.ceil(((gammaEnergyMax - gammaEnergyMin) / 4) * 1.1)
this.figureChartOption.yAxis.max = gammaEnergyInterval * 4
this.figureChartOption.yAxis.min = gammaEnergyMin
this.figureChartOption.yAxis.interval = Math.ceil((gammaEnergyMax * 1.1) / 4)
this.figureChartOption.series.data = gammaEnergyValue.map((item, index) => [index, item])
} else {
@ -415,10 +466,60 @@ export default {
handleGammaSpectrumChartClick(param) {
const { offsetX, offsetY } = param
const point = getXAxisAndYAxisByPosition(this.$refs.gammaSpectrumChart.getChartInstance(), offsetX, offsetY)
const xAxis = parseInt(point[0].toFixed())
console.log('%c [ xAxis ]-420', 'font-size:13px; background:pink; color:#bf2c9f;', xAxis)
if (point) {
const xAxis = parseInt(point[0].toFixed())
this.gammaSpectrumChartOption.series.markLine.data = [{ xAxis }]
this.tooltipChannel = xAxis
this.tooltipPosition.top = offsetY
if (xAxis > 225) {
this.tooltipPosition.left = offsetX - 125
} else {
this.tooltipPosition.left = offsetX + 20
}
this.tooltipVisible = true
this.channelAndEnergyModel.channel = xAxis
this.channelAndEnergyModel.energy = undefined
this.$refs.energyInputRef.focus()
}
},
//
handleSnapshot(chartRef) {
const chartInstance = chartRef.getChartInstance()
exportEchartImg(chartInstance)
},
// Channel Energy
handleAddChannelAndEnergy() {
const { channel, energy } = this.channelAndEnergyModel
if (!channel || !energy) {
return
}
this.list.push({
channel,
energy
})
this.channelAndEnergyModel = {}
},
//
handleDel(index) {
this.list.splice(index, 1)
},
// Reset Button
handleReset() {
this.newCalibrationFuncModel = []
},
// Fitting
handleFitting() {},
/**
* 返回的科学计数法的字符串处理
* @param {string} str
@ -589,6 +690,25 @@ p {
}
}
}
.custom-tool-tip {
position: absolute;
border-style: solid;
white-space: nowrap;
z-index: 99999;
box-shadow: rgba(0, 0, 0, 0.2) 1px 2px 10px;
border-width: 1px;
border-radius: 4px;
padding: 10px;
border-color: rgb(255, 255, 255);
pointer-events: none;
background-color: #00aa7f;
border-color: #00aa7f;
.channel {
color: #fff;
}
}
</style>
<style lang="less">
.figure-chart-option-tooltip {

View File

@ -1,5 +1,5 @@
<template>
<custom-modal v-model="visible" :width="1200" title="Tool of Calibration" :footer="null">
<custom-modal v-model="visible" :width="1200" title="Tool of Calibration" :footer="null" destroy-on-close>
<a-tabs :animated="false">
<a-tab-pane tab="Gamma Detector Calibration" key="1">
<gamma-detector-calibration @exit="visible = false" :sampleId="sampleId" />

View File

@ -124,6 +124,9 @@ export default {
}
}
},
created() {
this.getStationAndDetectorList(this.queryParam.menuTypes)
},
methods: {
loadData(arg) {
const params = this.getQueryParams() //

View File

@ -4,15 +4,13 @@
<template slot="flag">
<a-checkbox></a-checkbox>
</template>
<template slot="concentration" slot-scope="text">
<div class="concentration color-box">
<template slot="concentration" slot-scope="text, record">
<div class="concentration color-box" :class="record.className">
{{ text }}
</div>
</template>
<template slot="uncertainty" slot-scope="text">
<div class="uncertainty color-box">
+/-{{ text }}
</div>
<div class="uncertainty color-box">+/-{{ text }}</div>
</template>
<template slot="mdc" slot-scope="text">
<div class="mdc color-box">
@ -27,15 +25,13 @@
<template slot="flag">
<a-checkbox></a-checkbox>
</template>
<template slot="concentration" slot-scope="text">
<div class="concentration color-box error">
<template slot="concentration" slot-scope="text, record">
<div class="concentration color-box" :class="record.className">
{{ text }}
</div>
</template>
<template slot="uncertainty" slot-scope="text">
<div class="uncertainty color-box">
+/-{{ text }}
</div>
<div class="uncertainty color-box">+/-{{ text }}</div>
</template>
<template slot="mdc" slot-scope="text">
<div class="mdc color-box">
@ -114,8 +110,19 @@ export default {
watch: {
data: {
handler(val) {
this.source1 = val.slice(0, 2)
this.source2 = val.slice(2, 4)
if (val && Array.isArray(val)) {
val.forEach(item => {
if (item.conc < 0) {
item.className = 'error'
} else if (item.conc > 0 && item.conc < item.mdc) {
item.className = 'warning'
} else {
item.className = 'success'
}
})
this.source1 = val.slice(0, 2)
this.source2 = val.slice(2, 4)
}
},
immediate: true
}
@ -188,7 +195,15 @@ export default {
background-color: #ad8815;
&.error {
background-color: #c11414;
background-color: red;
}
&.warning {
background-color: #ffcc30;
}
&.success {
background-color: #0f0;
}
}

View File

@ -260,9 +260,10 @@ export default {
handler(newVal) {
this.option.series.data = newVal.map(({ x, y }) => [x, y])
const max = Math.max(...newVal.map(item => item.y)) * 1.1
this.option.yAxis.interval = Math.ceil(max / 4)
this.option.yAxis.max = this.option.yAxis.interval * 4
const max = Math.max(...newVal.map(item => item.y))
const interval = Math.ceil((max / 4) * 1.1)
this.option.yAxis.interval = interval
this.option.yAxis.max = interval * 4
},
immediate: true
}

View File

@ -143,7 +143,10 @@
<!-- Beta-Gamma 的Comments 结束 -->
<!-- Beta-Gamma 的Energy Calibration开始 -->
<beta-gamma-energy-calibration-modal v-model="betaGammaEnergyCalibrationModalVisible" :sampleId="this.sampleData.sampleId" />
<beta-gamma-energy-calibration-modal
v-model="betaGammaEnergyCalibrationModalVisible"
:sampleId="this.sampleData.sampleId"
/>
<!-- Beta-Gamma 的Energy Calibration结束 -->
<!-- Beta-Gamma Spectrum 弹窗 -->
@ -158,7 +161,7 @@
<!-- Beta-Gamma Sample Infomation 弹窗 结束 -->
<!-- Beta-Gamma QC Result 弹窗 -->
<beta-gamma-qc-results-modal v-model="betaGammaQCResultsModalVisible" :sampleId="this.sampleData.sampleId"/>
<beta-gamma-qc-results-modal v-model="betaGammaQCResultsModalVisible" :sampleId="this.sampleData.sampleId" />
<!-- Beta-Gamma QC Result 弹窗 结束 -->
<!-- Beta-Gamma RLR 弹窗 -->
@ -311,9 +314,14 @@ export default {
}
},
methods: {
// -
/**
* 从数据库加载-选择完成
* @param {any[]} sampleList
*/
handleLoadSampleFromDB(sampleList) {
this.sampleList = sampleList
const ids = this.sampleList.map(item => item.sampleId) // Sampleid
const willAddList = sampleList.filter(item => !ids.includes(item.sampleId))
this.sampleList = this.sampleList.concat(willAddList)
},
//
@ -330,6 +338,7 @@ export default {
//
handleCleanAll() {
this.sampleList = []
this.analysisType = undefined
this.sampleData = {}
},
@ -403,6 +412,7 @@ export default {
}
},
computed: {
//
operations() {
return [
{
@ -452,6 +462,9 @@ export default {
change: spectra => {
if (spectra) {
this.loadSelectedSample(spectra)
} else {
this.analysisType = undefined
this.sampleData = {}
}
}
}
@ -630,11 +643,13 @@ export default {
{
type: 'a-menu-item',
title: 'View Comments',
show: this.isBetaGamma || this.isGamma,
handler: this.handleViewComments
},
{
type: 'a-menu-item',
title: 'Add Comments',
show: this.isBetaGamma || this.isGamma,
handler: this.handleAddComments
}
]