feat: Gamma主页的Peak Infomation和Nuclide Library,分析工具弹窗里的编辑斜率功能

This commit is contained in:
Xu Zhimeng 2023-09-12 19:42:36 +08:00
parent 6f9a4cbaed
commit acf0fb4706
9 changed files with 500 additions and 333 deletions

View File

@ -5,7 +5,7 @@
</div> </div>
<div class="color-picker-mask" :class="show ? 'show' : ''" @click="show = false"> <div class="color-picker-mask" :class="show ? 'show' : ''" @click="show = false">
<div class="color-picker-panel" :style="style" @click.stop> <div class="color-picker-panel" :style="style" @click.stop>
<chrome v-model="color"></chrome> <chrome v-model="color" disableAlpha></chrome>
</div> </div>
</div> </div>
</div> </div>
@ -17,7 +17,7 @@ export default {
props: { props: {
value: { value: {
type: Object, type: Object,
default: () => ({ rgba: { r: 255, g: 255, b: 255, a: 1 } }) default: () => ({ rgba: { r: 255, g: 255, b: 255 } })
} }
}, },
components: { components: {

View File

@ -30,13 +30,6 @@
@input-bg: @formInputBgColor; @input-bg: @formInputBgColor;
@input-border-color: @formInputBorderColor; @input-border-color: @formInputBorderColor;
.ant-btn:hover,
.ant-btn:active,
.ant-btn:focus {
color: #fff !important;
border-color: transparent;
}
@font-face { @font-face {
font-family: MicrogrammaD-MediExte; font-family: MicrogrammaD-MediExte;
src: url(~@/assets/fonts/MicrogrammaDMedExt.ttf); src: url(~@/assets/fonts/MicrogrammaDMedExt.ttf);

View File

@ -0,0 +1,60 @@
<template>
<custom-modal v-model="visible" :title="'Slope at ' + (index + 1)" :width="250">
<a-input-number v-model="value"></a-input-number>
<template slot="custom-footer">
<div class="footer">
<a-button type="primary" @click="handleOK">Ok</a-button>
<a-button @click="visible = false">Cancel</a-button>
</div>
</template>
</custom-modal>
</template>
<script>
export default {
data() {
return {
index: -1,
value: 0,
prevValue: 0,
allowNaN: false,
visible: false
}
},
methods: {
/**
* 打开弹窗
* @param {{ index: number; value: number; allowNaN: boolean; }} config
*/
open(config) {
this.index = config.index
this.value = config.value
this.prevValue = config.value
this.allowNaN = config.allowNaN
this.visible = true
},
handleOK() {
if (this.allowNaN || this.value) {
this.$emit('change', this.value || 0, this.index, this.prevValue)
this.visible = false
} else {
this.$message.warn('Input value invalid.')
}
}
}
}
</script>
<style lang="less" scoped>
.ant-input-number {
width: 100%;
}
.footer {
display: flex;
justify-content: center;
gap: 10px;
}
</style>

View File

@ -81,13 +81,19 @@
<a-button type="primary" @click="handleRemoveCP">(R)emove CP</a-button> <a-button type="primary" @click="handleRemoveCP">(R)emove CP</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary" @click="handleModifyCP">(M)odify CP</a-button> <a-button
type="primary"
key="modify-btn"
:class="{ 'is-modify': isModifying }"
@click="handleModifyCP"
>(M)odify CP</a-button
>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary" @click="handleEditSlope">Edit (S)lope</a-button> <a-button type="primary" @click="handleEditSlope">Edit (S)lope</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary" :disabled="isOperationStackEmpty" @click="popOperationStack">Undo</a-button> <a-button type="primary" :disabled="isOperationStackEmpty" @click="handleUndo">Undo</a-button>
</div> </div>
<div class="peak-box-item"> <div class="peak-box-item">
<a-button type="primary">Replot</a-button> <a-button type="primary">Replot</a-button>
@ -179,6 +185,10 @@
<!-- Nuclide Review 弹窗开始 --> <!-- Nuclide Review 弹窗开始 -->
<nuclide-review-modal v-model="nuclideReviewModalVisible" :sampleId="sampleId" :channel="currChannel" /> <nuclide-review-modal v-model="nuclideReviewModalVisible" :sampleId="sampleId" :channel="currChannel" />
<!-- Nuclide Review 弹窗结束 --> <!-- Nuclide Review 弹窗结束 -->
<!-- Edit Slope 弹窗 -->
<edit-slope-modal ref="editSlopeModal" @change="handleSlopeChange" />
<!-- Edit Slope 结束 -->
</custom-modal> </custom-modal>
</template> </template>
@ -191,9 +201,10 @@ import NuclideReviewModal from './components/NuclideReviewModal.vue'
import ModalMixin from '@/mixins/ModalMixin' import ModalMixin from '@/mixins/ModalMixin'
import { getAction, postAction } from '@/api/manage' import { getAction, postAction } from '@/api/manage'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { findSeriesByName, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper' import { buildLineSeries, findSeriesByName, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper'
import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin' import SampleDataMixin from '@/views/spectrumAnalysis/SampleDataMixin'
import GeneralCommentModal from './components/GeneralCommentModal.vue' import GeneralCommentModal from './components/GeneralCommentModal.vue'
import EditSlopeModal from './components/EditSlopeModal.vue'
// //
const initialOption = { const initialOption = {
@ -388,7 +399,8 @@ const thumbnailOption = {
export const Operators = { export const Operators = {
ADD: 1, // ADD: 1, //
REMOVE: 2, // REMOVE: 2, //
MODIFY: 3 // MODIFY: 3, //
SLOPE_CHANGE: 4 // slope
} }
export default { export default {
@ -399,7 +411,8 @@ export default {
PeakCommentModal, PeakCommentModal,
FitPeaksAndBaseLineModal, FitPeaksAndBaseLineModal,
NuclideReviewModal, NuclideReviewModal,
GeneralCommentModal GeneralCommentModal,
EditSlopeModal
}, },
data() { data() {
this.columns = columns this.columns = columns
@ -416,6 +429,7 @@ export default {
channelPeakChart: [], channelPeakChart: [],
energy: [], energy: [],
list: [], list: [],
BaseCtrls: {},
sampleId: -1, sampleId: -1,
peakCommentModalVisible: false, // Comment peakCommentModalVisible: false, // Comment
@ -460,6 +474,7 @@ export default {
sampleId: this.sampleId, sampleId: this.sampleId,
fileName: this.fileName fileName: this.fileName
}) })
if (success) { if (success) {
this.isLoading = false this.isLoading = false
const { const {
@ -469,7 +484,8 @@ export default {
channelCountChart, channelCountChart,
channelPeakChart, channelPeakChart,
energy, energy,
table table,
BaseCtrls
} = result } = result
console.log('%c [ ]-374', 'font-size:13px; background:pink; color:#bf2c9f;', result) console.log('%c [ ]-374', 'font-size:13px; background:pink; color:#bf2c9f;', result)
@ -479,34 +495,37 @@ export default {
this.channelCountChart = channelCountChart this.channelCountChart = channelCountChart
this.channelPeakChart = channelPeakChart this.channelPeakChart = channelPeakChart
this.energy = energy this.energy = energy
this.BaseCtrls = BaseCtrls
const series = [] const series = []
// BaseLine // BaseLine
series.push({ series.push(
...this.buildSeriesOption( buildLineSeries(
'BaseLine', 'BaseLine',
channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]), channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${channelBaseLineChart.color})` `rgb(${channelBaseLineChart.color})`,
), {
markLine: { markLine: {
silent: true, silent: true,
symbol: 'none', symbol: 'none',
label: { label: {
show: false show: false
}, },
lineStyle: { lineStyle: {
color: 'red', color: 'red',
width: 1 width: 1
}, },
data: [{ xAxis: -1 }] data: [{ xAxis: -1 }]
}, },
zlevel: 10 zlevel: 10
}) }
)
)
// Count // Count
series.push( series.push(
this.buildSeriesOption( buildLineSeries(
'CountChart', 'CountChart',
channelCountChart.pointlist.map(({ x, y }) => [x, y]), channelCountChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${channelCountChart.color})` `rgb(${channelCountChart.color})`
@ -517,7 +536,7 @@ export default {
const peakSeries = [] const peakSeries = []
channelPeakChart.forEach((item, index) => { channelPeakChart.forEach((item, index) => {
peakSeries.push( peakSeries.push(
this.buildSeriesOption( buildLineSeries(
'Peak_' + (index + 1), 'Peak_' + (index + 1),
item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
`rgb(${item.color})` `rgb(${item.color})`
@ -546,7 +565,7 @@ export default {
zlevel: 20 zlevel: 20
}) })
this.thumbnailOption.series = this.buildSeriesOption( this.thumbnailOption.series = buildLineSeries(
'BarChart', 'BarChart',
barChart.map(({ x, y }) => [x, y]), barChart.map(({ x, y }) => [x, y]),
'#fff', '#fff',
@ -565,29 +584,6 @@ export default {
} }
}, },
// series
buildSeriesOption(name, data, color, extra = {}) {
return {
name,
type: 'line',
data,
itemStyle: {
color
},
lineStyle: {
width: 1
},
symbol: 'none',
symbolSize: 1,
emphasis: {
disabled: true
},
silent: true,
animation: false,
...extra
}
},
beforeModalOpen() { beforeModalOpen() {
const { sampleId, inputFileName } = this.sampleData const { sampleId, inputFileName } = this.sampleData
this.sampleId = sampleId this.sampleId = sampleId
@ -644,6 +640,8 @@ export default {
this.selectedKeys = [selectedRow.index] this.selectedKeys = [selectedRow.index]
this.getSelPosNuclide(selectedRow) this.getSelPosNuclide(selectedRow)
this.selectedTableItem = selectedRow
} }
}, },
@ -690,7 +688,6 @@ export default {
const { success, result, message } = await getAction('/gamma/getSelPosNuclide', { const { success, result, message } = await getAction('/gamma/getSelPosNuclide', {
sampleId: this.sampleId, sampleId: this.sampleId,
channel: parseInt(row.peakCentroid), channel: parseInt(row.peakCentroid),
nuclides: row.nuclides.join(','),
fileName: this.fileName fileName: this.fileName
}) })
if (success) { if (success) {
@ -773,30 +770,32 @@ export default {
const series = [] const series = []
// BaseLine // BaseLine
series.push({ series.push(
...this.buildSeriesOption( buildLineSeries(
'BaseLine', 'BaseLine',
channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]), channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${channelBaseLineChart.color})` `rgb(${channelBaseLineChart.color})`,
), {
markLine: { markLine: {
silent: true, silent: true,
symbol: 'none', symbol: 'none',
label: { label: {
show: false show: false
}, },
lineStyle: { lineStyle: {
color: 'red', color: 'red',
width: 1 width: 1
}, },
data: [{ xAxis: -1 }] data: [{ xAxis: -1 }]
}, },
zlevel: 10 zlevel: 10
}) }
)
)
// Count // Count
series.push( series.push(
this.buildSeriesOption( buildLineSeries(
'CountChart', 'CountChart',
this.channelCountChart.pointlist.map(({ x, y }) => [x, y]), this.channelCountChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${this.channelCountChart.color})` `rgb(${this.channelCountChart.color})`
@ -807,7 +806,7 @@ export default {
const peakSeries = [] const peakSeries = []
channelPeakChart.forEach((item, index) => { channelPeakChart.forEach((item, index) => {
peakSeries.push( peakSeries.push(
this.buildSeriesOption( buildLineSeries(
'Peak_' + (index + 1), 'Peak_' + (index + 1),
item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
`rgb(${item.color})` `rgb(${item.color})`
@ -836,7 +835,7 @@ export default {
zlevel: 20 zlevel: 20
}) })
this.thumbnailOption.series = this.buildSeriesOption( this.thumbnailOption.series = buildLineSeries(
'BarChart', 'BarChart',
barChart.map(({ x, y }) => [x, y]), barChart.map(({ x, y }) => [x, y]),
'#fff', '#fff',
@ -856,30 +855,32 @@ export default {
const series = [] const series = []
// BaseLine // BaseLine
series.push({ series.push(
...this.buildSeriesOption( buildLineSeries(
'BaseLine', 'BaseLine',
this.channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]), this.channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${this.channelBaseLineChart.color})` `rgb(${this.channelBaseLineChart.color})`,
), {
markLine: { markLine: {
silent: true, silent: true,
symbol: 'none', symbol: 'none',
label: { label: {
show: false show: false
}, },
lineStyle: { lineStyle: {
color: 'red', color: 'red',
width: 1 width: 1
}, },
data: [{ xAxis: -1 }] data: [{ xAxis: -1 }]
}, },
zlevel: 10 zlevel: 10
}) }
)
)
// Count // Count
series.push( series.push(
this.buildSeriesOption( buildLineSeries(
'CountChart', 'CountChart',
this.channelCountChart.pointlist.map(({ x, y }) => [x, y]), this.channelCountChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${this.channelCountChart.color})` `rgb(${this.channelCountChart.color})`
@ -890,7 +891,7 @@ export default {
const peakSeries = [] const peakSeries = []
channelPeakChart.forEach((item, index) => { channelPeakChart.forEach((item, index) => {
peakSeries.push( peakSeries.push(
this.buildSeriesOption( buildLineSeries(
'Peak_' + (index + 1), 'Peak_' + (index + 1),
item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
`rgb(${item.color})` `rgb(${item.color})`
@ -978,30 +979,32 @@ export default {
this.channelPeakChart = channelPeakChart this.channelPeakChart = channelPeakChart
const series = [] const series = []
// BaseLine // BaseLine
series.push({ series.push(
...this.buildSeriesOption( buildLineSeries(
'BaseLine', 'BaseLine',
this.channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]), this.channelBaseLineChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${this.channelBaseLineChart.color})` `rgb(${this.channelBaseLineChart.color})`,
), {
markLine: { markLine: {
silent: true, silent: true,
symbol: 'none', symbol: 'none',
label: { label: {
show: false show: false
}, },
lineStyle: { lineStyle: {
color: 'red', color: 'red',
width: 1 width: 1
}, },
data: [{ xAxis: -1 }] data: [{ xAxis: -1 }]
}, },
zlevel: 10 zlevel: 10
}) }
)
)
// Count // Count
series.push( series.push(
this.buildSeriesOption( buildLineSeries(
'CountChart', 'CountChart',
this.channelCountChart.pointlist.map(({ x, y }) => [x, y]), this.channelCountChart.pointlist.map(({ x, y }) => [x, y]),
`rgb(${this.channelCountChart.color})` `rgb(${this.channelCountChart.color})`
@ -1012,7 +1015,7 @@ export default {
const peakSeries = [] const peakSeries = []
channelPeakChart.forEach((item, index) => { channelPeakChart.forEach((item, index) => {
peakSeries.push( peakSeries.push(
this.buildSeriesOption( buildLineSeries(
'Peak_' + (index + 1), 'Peak_' + (index + 1),
item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
`rgb(${item.color})` `rgb(${item.color})`
@ -1186,11 +1189,9 @@ export default {
// Base Line Control Point // Base Line Control Point
if (this.btnGroupType == 1) { if (this.btnGroupType == 1) {
this.btnGroupType = 2 this.btnGroupType = 2
this.clearOperationStack()
const originalCPSeries = findSeriesByName(this.option.series, 'BaseLine') const originalCPSeries = findSeriesByName(this.option.series, 'BaseLine')
const baseLineEditSeries = this.buildSeriesOption('BaseLine_Edit', cloneDeep(originalCPSeries.data), '#fff', { const baseLineEditSeries = buildLineSeries('BaseLine_Edit', cloneDeep(originalCPSeries.data), '#fff', {
zlevel: 21 zlevel: 21
}) })
@ -1203,6 +1204,7 @@ export default {
}) })
this._channelBaseCPChart = cloneDeep(this.channelBaseCPChart) this._channelBaseCPChart = cloneDeep(this.channelBaseCPChart)
this._baseCtrls = cloneDeep(this.BaseCtrls)
} }
// Peak // Peak
else { else {
@ -1214,6 +1216,9 @@ export default {
this.resetChartOpts() this.resetChartOpts()
}) })
} }
this.isModifying = false
this.clearOperationStack()
}, },
buildGraphicPoint(chart, x, y) { buildGraphicPoint(chart, x, y) {
@ -1274,6 +1279,8 @@ export default {
// 线 // 线
handleAddCP() { handleAddCP() {
this.setGraphicDraggable(false)
const xAxises = this.channelBaseCPChart.map(({ point: { x } }) => x) const xAxises = this.channelBaseCPChart.map(({ point: { x } }) => x)
const min = xAxises[0] const min = xAxises[0]
const max = xAxises[xAxises.length - 1] const max = xAxises[xAxises.length - 1]
@ -1317,6 +1324,8 @@ export default {
// //
handleRemoveCP() { handleRemoveCP() {
this.setGraphicDraggable(false)
// find nearest control-point // find nearest control-point
const chart = this.$refs.chartRef.getChartInstance() const chart = this.$refs.chartRef.getChartInstance()
const controlPointList = this.option.graphic const controlPointList = this.option.graphic
@ -1352,23 +1361,57 @@ export default {
// //
handleEditSlope() { handleEditSlope() {
// if (m_baseCtrl.XCtrl.empty()) { this.setGraphicDraggable(false)
// this.$message.warn('No control points to be edited')
// return const { xctrl, yslope } = this._baseCtrls
// } if (!xctrl.length) {
// // find nearest control-point this.$message.warn('No control points to be edited')
// let i = 1, return
// n = m_baseCtrl.XCtrl.size() }
// for (; i < n; ++i) { // find nearest control-point
// if (m_baseCtrl.XCtrl[i] >= m_curChan) { let i = 1,
// if (m_baseCtrl.XCtrl[i] - m_curChan > m_curChan - m_baseCtrl.XCtrl[i - 1]) --i n = xctrl.length
// break for (; i < n; ++i) {
// } const currXCtrl = xctrl[i]
// } const prevXCtrl = xctrl[i - 1]
// if (i == n) i = n - 1 if (currXCtrl >= this.currChannel) {
if (currXCtrl - this.currChannel > this.currChannel - prevXCtrl) {
--i
}
break
}
}
if (i == n) i = n - 1
this.$refs.editSlopeModal.open({
index: i,
value: yslope[i],
allowNaN: !(i == 0 || i == n - 1)
})
}, },
// Control Point //
handleSlopeChange(slope, index, prevSlope) {
if (slope === prevSlope) {
return
}
const { yslope } = this._baseCtrls
yslope[index] = slope
this.pushOperationStack(Operators.SLOPE_CHANGE, {
index,
slope: prevSlope
})
},
//
handleUndo() {
this.setGraphicDraggable(false)
this.popOperationStack()
},
// Baseline Control Points
handleAccept() {}, handleAccept() {},
// nuclide // nuclide
@ -1464,6 +1507,11 @@ export default {
const { point } = operand const { point } = operand
this.option.graphic.splice(index, 0, point) this.option.graphic.splice(index, 0, point)
break break
case Operators.SLOPE_CHANGE:
const { slope } = operand
const { yslope } = this._baseCtrls
yslope[index] = slope
break
} }
}, },
@ -1655,4 +1703,8 @@ export default {
width: 100%; width: 100%;
} }
} }
.is-modify {
color: #f00;
}
</style> </style>

View File

@ -156,6 +156,7 @@ export default {
.analysis-settings { .analysis-settings {
&-item { &-item {
display: flex; display: flex;
margin-top: 5px;
&:not(:first-child) { &:not(:first-child) {
margin-top: 20px; margin-top: 20px;

View File

@ -73,21 +73,21 @@ export default {
this.configList = configList this.configList = configList
return { return {
config: { config: {
spectrumLine: { rgba: { r: 255, g: 255, b: 0, a: 1 } }, spectrumLine: { rgba: { r: 255, g: 255, b: 0 } },
baseline: { rgba: { r: 0, g: 246, b: 255, a: 1 } }, baseline: { rgba: { r: 0, g: 246, b: 255 } },
lcLine: { rgba: { r: 255, g: 0, b: 0, a: 1 } }, lcLine: { rgba: { r: 255, g: 0, b: 0 } },
scacLine: { rgba: { r: 244, g: 112, b: 247, a: 1 } }, scacLine: { rgba: { r: 244, g: 112, b: 247 } },
peakLine: { rgba: { r: 255, g: 127, b: 39, a: 1 } }, peakLine: { rgba: { r: 255, g: 127, b: 39 } },
compareLine: { rgba: { r: 0, g: 255, b: 0, a: 1 } }, compareLine: { rgba: { r: 0, g: 255, b: 0 } },
spectSumLine: { rgba: { r: 0, g: 0, b: 255, a: 1 } }, spectSumLine: { rgba: { r: 0, g: 0, b: 255 } },
spectCutLine: { rgba: { r: 34, g: 90, b: 106, a: 1 } }, spectCutLine: { rgba: { r: 34, g: 90, b: 106 } },
fitBaseLine: { rgba: { r: 255, g: 255, b: 255, a: 1 } } fitBaseLine: { rgba: { r: 255, g: 255, b: 255 } }
} }
} }
}, },
methods: { methods: {
combineRGBA({ rgba: { r, g, b, a } }) { combineRGBA({ rgba: { r, g, b} }) {
return `rgba(${r}, ${g}, ${b}, ${a})` return `rgb(${r}, ${g}, ${b})`
} }
} }
} }

View File

@ -3,8 +3,8 @@
<i @click="handleClick('left')"> <i @click="handleClick('left')">
<img src="@/assets/images/spectrum/left-arrow.png" /> <img src="@/assets/images/spectrum/left-arrow.png" />
</i> </i>
<span> <span @click="handleBtnClick">
<slot></slot> Peak Information
</span> </span>
<i @click="handleClick('right')"> <i @click="handleClick('right')">
<img src="@/assets/images/spectrum/right-arrow.png" /> <img src="@/assets/images/spectrum/right-arrow.png" />
@ -17,6 +17,9 @@ export default {
methods: { methods: {
handleClick(direction) { handleClick(direction) {
this.$emit('change', direction) this.$emit('change', direction)
},
handleBtnClick() {
this.$emit('click')
} }
} }
} }
@ -25,6 +28,7 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
.btn-with-switch-icon { .btn-with-switch-icon {
display: flex; display: flex;
gap: 10px;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
border: 1px solid #0a544e; border: 1px solid #0a544e;
@ -41,9 +45,9 @@ export default {
} }
span { span {
white-space: nowrap; flex: 1;
overflow: hidden; text-align: center;
text-overflow: ellipsis; cursor: pointer;
} }
} }
</style> </style>

View File

@ -1,41 +1,17 @@
<template> <template>
<div class="nuclear-library"> <div class="nuclear-library">
<div class="nuclear-library-item" v-for="item in list" :key="item.id"> <div class="nuclear-library-item" v-for="(item, index) in list" :key="index">
{{ item.title }} {{ item }}
</div> </div>
<a-empty v-if="!list.length"></a-empty>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { props: {
return { list: {
list: [ type: Array
{
id: '1',
title: 'Ac228'
},
{
id: '2',
title: 'Ac229'
},
{
id: '3',
title: 'Ac230'
},
{
id: '4',
title: 'Eu152'
},
{
id: '5',
title: 'I132'
},
{
id: '6',
title: 'Ir192'
}
]
} }
} }
} }
@ -46,14 +22,10 @@ export default {
width: 230px; width: 230px;
max-height: 200px; max-height: 200px;
overflow: auto; overflow: auto;
padding: 20px 0;
&-item { &-item {
padding: 4px 14px; padding: 4px 14px;
// cursor: pointer;
// &:hover {
// background-color: #055565;
// }
} }
} }
</style> </style>

View File

@ -22,12 +22,10 @@
</pop-over-with-icon> </pop-over-with-icon>
<pop-over-with-icon> <pop-over-with-icon>
Nuclide Library Nuclide Library
<nuclear-library slot="content" /> <nuclear-library slot="content" :list="nuclideLibraryList" />
</pop-over-with-icon> </pop-over-with-icon>
<div class="peak-info"> <div class="peak-info">
<button-with-switch-icon @change="handlePeakInfoChange"> <button-with-switch-icon @change="handlePeakInfoChange" @click="handleTogglePeak"></button-with-switch-icon>
Peak Information
</button-with-switch-icon>
</div> </div>
</div> </div>
<!-- 二级交互栏结束 --> <!-- 二级交互栏结束 -->
@ -53,6 +51,19 @@
/> />
</div> </div>
<!-- 缩略图结束 --> <!-- 缩略图结束 -->
<!-- 自定义tooltip用于展示Peak Infomation -->
<div
v-if="peakInfomationTooltip.visible"
class="peak-infomation-tooltip"
:style="{
top: peakInfomationTooltip.top + 'px',
left: peakInfomationTooltip.left + 'px'
}"
>
<div class="peak-infomation-tooltip-content" v-html="peakInfomationTooltip.content"></div>
</div>
<!-- tooltip结束 -->
</div> </div>
</div> </div>
<!-- 主体部分结束 --> <!-- 主体部分结束 -->
@ -70,7 +81,7 @@ import NuclearLibrary from './components/SubOperators/NuclearLibrary.vue'
import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue' import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue'
import { getAction } from '@/api/manage' import { getAction } from '@/api/manage'
import Response from './response.json' import Response from './response.json'
import { getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper' import { buildLineSeries, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
// //
@ -240,7 +251,16 @@ export default {
graphAssistance: {}, graphAssistance: {},
channelPeakGroup: [], channelPeakGroup: [],
energyPeakGroup: [] energyPeakGroup: [],
nuclideLibraryList: [], // channel
peakInfomationTooltip: {
// Peak Infomation
visible: false,
content: '',
top: 0,
left: 0
}
} }
}, },
created() { created() {
@ -333,124 +353,88 @@ export default {
const series = [] const series = []
// Spectrum Line // Spectrum Line
series.push({ series.push(
name: 'Spectrum', buildLineSeries(
type: 'line', 'Spectrum',
data: shadowChannelChart.pointlist.map(({ x, y }) => [x, y]), shadowChannelChart.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${shadowChannelChart.color})`,
color: `rgb(${shadowChannelChart.color})` {
}, markLine: {
lineStyle: { silent: true,
width: 1 symbol: 'none',
}, label: {
symbol: 'none', show: false
symbolSize: 1, },
emphasis: { lineStyle: {
disabled: true color: 'red',
}, width: 1
markLine: { },
silent: true, data: [{ xAxis: -1 }]
symbol: 'none', }
label: { }
show: false )
}, )
lineStyle: {
color: 'red',
width: 1
},
data: [{ xAxis: -1 }]
},
animation: false
})
// Spectrum Line // Spectrum Line
this.thumbnailOption.series.push({ this.thumbnailOption.series.push(
name: 'Spectrum', buildLineSeries(
type: 'line', 'Spectrum',
data: shadowChannelChart.pointlist.map(({ x, y }) => [x, y]), shadowChannelChart.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${shadowChannelChart.color})`,
color: `rgb(${shadowChannelChart.color})` {
}, silent: true,
lineStyle: { markLine: {
width: 1 silent: true,
}, symbol: 'none',
symbol: 'none', label: {
symbolSize: 1, show: false
emphasis: { },
disabled: true lineStyle: {
}, type: 'solid',
silent: true, color: '#1397a3',
markLine: { width: 1
silent: true, },
symbol: 'none', data: []
label: { }
show: false }
}, )
lineStyle: { )
type: 'solid',
color: '#1397a3',
width: 1
},
data: []
}
})
// BaseLine // BaseLine
series.push({ series.push(
name: 'BaseLine', buildLineSeries(
type: 'line', 'BaseLine',
data: channelBaseLine.pointlist.map(({ x, y }) => [x, y]), channelBaseLine.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${channelBaseLine.color})`,
color: `rgb(${channelBaseLine.color})` {
}, zlevel: 2
lineStyle: { }
width: 1 )
}, )
symbol: 'none',
emphasis: {
disabled: true
},
animation: false,
zlevel: 2
})
// LcLine线 // LcLine线
series.push({ series.push(
name: 'LcLine', buildLineSeries(
type: 'line', 'LcLine',
data: channelLcLine.pointlist.map(({ x, y }) => [x, y]), channelLcLine.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${channelLcLine.color})`,
color: `rgb(${channelLcLine.color})` {
}, zlevel: 3
lineStyle: { }
width: 1 )
}, )
symbol: 'none',
emphasis: {
disabled: true
},
animation: false,
zlevel: 3
})
// Scac线 // Scac线
series.push({ series.push(
name: 'ScacLine', buildLineSeries(
type: 'line', 'ScacLine',
data: channelScacLine.pointlist.map(({ x, y }) => [x, y]), channelScacLine.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${channelScacLine.color})`,
color: `rgb(${channelScacLine.color})` {
}, zlevel: 4
lineStyle: { }
width: 1 )
}, )
symbol: 'none',
emphasis: {
disabled: true
},
animation: false,
zlevel: 4
})
// 线 // 线
series.push({ series.push({
@ -476,20 +460,16 @@ export default {
// Peak Line // Peak Line
const peakLines = [] const peakLines = []
channelPeakGroup.forEach((item, index) => { channelPeakGroup.forEach((item, index) => {
peakLines.push({ peakLines.push(
name: `Peak_${index}`, buildLineSeries(
type: 'line', `Peak_${index}`,
data: item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${item.color})`,
color: `rgb(${item.color})` {
}, zlevel: 6
lineStyle: { }
width: 1 )
}, )
symbol: 'none',
animation: false,
zlevel: 6
})
}) })
series.push(...peakLines) series.push(...peakLines)
this.option.series = series this.option.series = series
@ -640,19 +620,16 @@ export default {
const data = this.isEnergy() ? this.energyPeakGroup : this.channelPeakGroup const data = this.isEnergy() ? this.energyPeakGroup : this.channelPeakGroup
const peakLines = [] const peakLines = []
data.forEach((item, index) => { data.forEach((item, index) => {
peakLines.push({ peakLines.push(
name: `Peak_${index}`, buildLineSeries(
type: 'line', `Peak_${index}`,
data: item.pointlist.map(({ x, y }) => [x, y]), item.pointlist.map(({ x, y }) => [x, y]),
itemStyle: { `rgb(${item.color})`,
color: `rgb(${item.color})` {
}, zlevel: 6
lineStyle: { }
width: 1 )
}, )
symbol: 'none',
animation: false
})
}) })
this.option.series.push(...peakLines) this.option.series.push(...peakLines)
@ -677,12 +654,40 @@ export default {
const energy = this.isEnergy() ? xAxis.toFixed(2) : this.allEnergy.pointlist[channel - 1].x.toFixed(2) const energy = this.isEnergy() ? xAxis.toFixed(2) : this.allEnergy.pointlist[channel - 1].x.toFixed(2)
const counts = this.isEnergy() ? this.allEnergy.pointlist[channel - 1] : this.allChannel.pointlist[channel - 1] const counts = this.isEnergy() ? this.allEnergy.pointlist[channel - 1] : this.allChannel.pointlist[channel - 1]
this.option.title.text = `{a|Channel:${channel}} {a|Energy:${energy}} {a|Counts:${counts.y}} {a|Detectability:0}` this.option.title.text = `{a|Channel:${channel}} {a|Energy:${energy}} {a|Counts:${counts.y}} {a|Detectability:0}`
this.getSelPosNuclide(channel)
}
},
// Nuclide Library
async getSelPosNuclide(channel) {
try {
this.loading = true
const { sampleId, inputFileName: fileName } = this.sample
const { success, result, message } = await getAction('/gamma/getSelPosNuclide', {
sampleId,
channel,
fileName
})
if (success) {
const { identify } = result
this.nuclideLibraryList = identify
} else {
this.$message.error(message)
}
} catch (error) {
this.list = []
console.error(error)
} finally {
this.loading = false
} }
}, },
resize() { resize() {
this.$refs.chartRef.resize() this.$refs.chartRef.resize()
this.$refs.thumbnailChartRef.resize() this.$refs.thumbnailChartRef.resize()
this.closePeakInfomationTooltip()
}, },
// peak info // peak info
@ -690,6 +695,60 @@ export default {
this.moveMarkLine(direction) this.moveMarkLine(direction)
}, },
// Peak Infomation
handleTogglePeak() {
const xAxis = this.option.series[0].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)
const max = Math.max(...allX)
const min = Math.min(...allX)
return channel >= min && channel <= max
})
console.log('%c [ index ]-732', 'font-size:13px; background:pink; color:#bf2c9f;', index)
if (-1 !== index) {
this.getPeakInfo(index)
} else {
this.closePeakInfomationTooltip()
}
},
// Peak
async getPeakInfo(index) {
try {
const { inputFileName: fileName } = this.sample
const { success, result, message } = await getAction('/gamma/clickPeakInformation', {
fileName,
index
})
if (success) {
const html = result.replaceAll('\n', '<br>')
const currPeak = this.channelPeakGroup[index]
const { x, y } = currPeak.pointlist.reduce((prev, curr) => {
return prev && prev.y > curr.y ? prev : curr
})
const chart = this.$refs.chartRef.getChartInstance()
const [xPix, yPix] = chart.convertToPixel({ seriesIndex: 0 }, [x, y])
console.log('%c [ xPix, yPix ]-731', 'font-size:13px; background:pink; color:#bf2c9f;', xPix, yPix)
this.peakInfomationTooltip.content = html
this.peakInfomationTooltip.visible = true
this.peakInfomationTooltip.left = xPix
this.peakInfomationTooltip.top = yPix - 20
} else {
this.$message.error(message)
}
} catch (error) {
console.error(error)
}
},
// Peak Infomation
closePeakInfomationTooltip() {
this.peakInfomationTooltip.visible = false
},
/** /**
* 向某一个方向移动标记线 * 向某一个方向移动标记线
* @param { 'left'| 'right' } direction * @param { 'left'| 'right' } direction
@ -754,6 +813,8 @@ export default {
// //
handleBrushEnd(param) { handleBrushEnd(param) {
this.closePeakInfomationTooltip()
const chart = this.$refs.chartRef.getChartInstance() const chart = this.$refs.chartRef.getChartInstance()
const areas = param.areas[0] const areas = param.areas[0]
if (areas) { if (areas) {
@ -981,6 +1042,13 @@ export default {
return channel return channel
}, },
//
reset() {
this.selectedChannel = -1
this.nuclideLibraryList = []
this.closePeakInfomationTooltip()
},
isEnergy() { isEnergy() {
return this.graphAssistance.axisType == 'Energy' return this.graphAssistance.axisType == 'Energy'
} }
@ -988,6 +1056,7 @@ export default {
watch: { watch: {
sample: { sample: {
handler() { handler() {
this.reset()
this.getSampleDetail() this.getSampleDetail()
}, },
immediate: true immediate: true
@ -1034,3 +1103,19 @@ export default {
} }
} }
</style> </style>
<style lang="less">
.peak-infomation-tooltip {
position: absolute;
border-style: solid;
white-space: nowrap;
z-index: 9;
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: #55a9fe;
border-color: #55a9fe;
}
</style>