Merge branch 'feature-particulate-renpy' of http://git.hivekion.com:3000/xiaoguangbin/AnalysisSystemForRadionuclide_vue into feature-particulate-renpy
This commit is contained in:
commit
0678934296
|
@ -24,6 +24,7 @@
|
|||
"dayjs": "^1.8.0",
|
||||
"dom-align": "1.12.0",
|
||||
"echarts": "^5.4.2",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"enquire.js": "^2.1.6",
|
||||
"file-saver": "^2.0.5",
|
||||
"js-cookie": "^2.2.0",
|
||||
|
|
BIN
src/assets/images/spectrum/comparation.png
Normal file
BIN
src/assets/images/spectrum/comparation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/spectrum/download.png
Normal file
BIN
src/assets/images/spectrum/download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/images/spectrum/left-arrow.png
Normal file
BIN
src/assets/images/spectrum/left-arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/spectrum/right-arrow.png
Normal file
BIN
src/assets/images/spectrum/right-arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/spectrum/search-hover.png
Normal file
BIN
src/assets/images/spectrum/search-hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/images/spectrum/search.png
Normal file
BIN
src/assets/images/spectrum/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
51
src/components/Custom3DChart/index.vue
Normal file
51
src/components/Custom3DChart/index.vue
Normal file
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div class="custom-chart" ref="containerRef" :style="{ height: height + 'px' }"></div>
|
||||
</template>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import 'echarts-gl'
|
||||
export default {
|
||||
props: {
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
mounted() {
|
||||
this.chart = echarts.init(this.$refs.containerRef)
|
||||
this.chart.setOption(this.option)
|
||||
},
|
||||
methods: {
|
||||
resize() {
|
||||
this.chart && this.chart.resize()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
option: {
|
||||
handler() {
|
||||
if (this.chart) {
|
||||
this.chart.setOption(this.option)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
height() {
|
||||
this.$nextTick(() => {
|
||||
this.chart && this.chart.resize()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-chart {
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
|
@ -3,6 +3,10 @@
|
|||
</template>
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
const events = ['brushEnd']
|
||||
const zrEvents = ['mousemove', 'mousedown', 'mouseup']
|
||||
|
||||
export default {
|
||||
props: {
|
||||
option: {
|
||||
|
@ -18,27 +22,51 @@ export default {
|
|||
return {}
|
||||
},
|
||||
mounted() {
|
||||
this.chart = echarts.init(this.$refs.containerRef)
|
||||
this.chart.setOption(this.option)
|
||||
this._chart = echarts.init(this.$refs.containerRef)
|
||||
this._chart.setOption(this.option)
|
||||
this.initEventListener()
|
||||
},
|
||||
methods: {
|
||||
initEventListener() {
|
||||
events.forEach(eventName => {
|
||||
this._chart.on(eventName, (params) => {
|
||||
this.$emit(eventName, params)
|
||||
})
|
||||
})
|
||||
|
||||
const zr = this.getZRender()
|
||||
zrEvents.forEach(eventName => {
|
||||
zr.on(eventName, params => {
|
||||
this.$emit(`zr:${eventName}`, params)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
resize() {
|
||||
this.chart && this.chart.resize()
|
||||
this._chart && this._chart.resize()
|
||||
},
|
||||
|
||||
// 获取echart实例
|
||||
getChartInstance() {
|
||||
return this._chart
|
||||
},
|
||||
|
||||
getZRender() {
|
||||
return this._chart.getZr()
|
||||
}
|
||||
},
|
||||
watch : {
|
||||
watch: {
|
||||
option: {
|
||||
handler() {
|
||||
if(this.chart) {
|
||||
this.chart.clear()
|
||||
this.chart.setOption(this.option)
|
||||
if (this._chart) {
|
||||
this._chart.setOption(this.option)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
height() {
|
||||
this.$nextTick(() => {
|
||||
this.chart && this.chart.resize()
|
||||
this._chart && this._chart.resize()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +74,6 @@ export default {
|
|||
</script>
|
||||
<style lang="less" scoped>
|
||||
.custom-chart {
|
||||
height: 100%;
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<template>
|
||||
<a-modal
|
||||
:class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')"
|
||||
v-bind="_attrs"
|
||||
v-model="visible"
|
||||
:footer="null"
|
||||
>
|
||||
<a-modal :class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')" v-bind="_attrs" v-model="visible">
|
||||
<img slot="closeIcon" src="@/assets/images/global/close.png" />
|
||||
<div slot="title">
|
||||
<div class="custom-modal-title">
|
||||
|
@ -16,10 +11,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
<a-space v-if="showFooter" class="operators" :size="20">
|
||||
<a-button type="success" @click="onSave" :loading="confirmLoading">Save</a-button>
|
||||
<a-button type="warn" @click="onCancel">Cancel</a-button>
|
||||
</a-space>
|
||||
<template slot="footer">
|
||||
<slot name="custom-footer"></slot>
|
||||
<a-space v-if="!hasCustomFooter" class="operators" :size="20">
|
||||
<a-button type="success" @click="onSave" :loading="confirmLoading">Save</a-button>
|
||||
<a-button type="warn" @click="onCancel">Cancel</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -34,10 +32,6 @@ export default {
|
|||
title: {
|
||||
type: String
|
||||
},
|
||||
showFooter: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
enableFullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
@ -92,6 +86,11 @@ export default {
|
|||
attrs['width'] = '100%'
|
||||
}
|
||||
return attrs
|
||||
},
|
||||
|
||||
// 是否有自定义的footer
|
||||
hasCustomFooter() {
|
||||
return !!this.$slots['custom-footer']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,16 @@ export default {
|
|||
methods: {
|
||||
onMenuSelect({ key }) {
|
||||
const childPath = this.getChildrenPath(this.menuItems.find(menu => menu.name === key))
|
||||
this.$router.push(childPath)
|
||||
if (key == "abnormal-alarm" || key == "istatistics") {
|
||||
const selectedKeys = window.sessionStorage.getItem('currMenu')
|
||||
if (selectedKeys) {
|
||||
this.$router.push(selectedKeys)
|
||||
} else {
|
||||
this.$router.push(childPath)
|
||||
}
|
||||
} else {
|
||||
this.$router.push(childPath)
|
||||
}
|
||||
},
|
||||
getChildrenPath(menuItem) {
|
||||
if (menuItem.children) {
|
||||
|
|
17
src/mixins/ModalMixin.js
Normal file
17
src/mixins/ModalMixin.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,8 +18,15 @@
|
|||
|
||||
@modal-footer-border-color-split: @formInputBorderColor;
|
||||
|
||||
@disabled-color: rgba(255, 255, 255, .25);
|
||||
@background-color-base: darken(@primary-color, 20);
|
||||
@border-color-base: darken(@primary-color, 20);
|
||||
|
||||
@text-color: #fff;
|
||||
|
||||
.ant-btn:hover,
|
||||
.ant-btn:active {
|
||||
.ant-btn:active,
|
||||
.ant-btn:focus {
|
||||
color: #fff !important;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
@ -61,6 +68,8 @@ body {
|
|||
.ant-table {
|
||||
color: #ade6ee;
|
||||
font-size: 16px;
|
||||
border: 1px solid rgba(65,111,127, .5);
|
||||
|
||||
&-thead {
|
||||
> tr {
|
||||
th {
|
||||
|
@ -299,6 +308,41 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
// 时间选择器
|
||||
@time-picker-selected-bg: @primary-color;
|
||||
@item-hover-bg: @primary-color;
|
||||
.ant-time-picker {
|
||||
&-input {
|
||||
background: @modalBg;
|
||||
border-radius: 0;
|
||||
&::placeholder {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&-clear,
|
||||
&-clock-icon {
|
||||
background-color: @modalBg !important;
|
||||
color: #01B6E3 !important;
|
||||
}
|
||||
|
||||
&-panel {
|
||||
&-input {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
&-inner {
|
||||
background-color: @modalBg;
|
||||
border: 1px solid @formInputBorderColor;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&-select li:focus {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框样式
|
||||
.ant-input {
|
||||
background-color: @formInputBgColor !important;
|
||||
|
@ -679,6 +723,16 @@ input[type='number']::-webkit-outer-spin-button {
|
|||
background-color: #b98326 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&-grey {
|
||||
// 自定义warn样式
|
||||
background-color: #406979 !important;
|
||||
color: #fff !important;
|
||||
border-color: #406979 !important;
|
||||
&:hover {
|
||||
background-color: #406979 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 空状态
|
||||
|
@ -869,6 +923,7 @@ input[type='number']::-webkit-outer-spin-button {
|
|||
&-arrow {
|
||||
border-left-color: #03353f !important;
|
||||
border-top-color: #03353f !important;
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
src/utils/chartHelper.js
Normal file
20
src/utils/chartHelper.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* 根据位置获取这个点在图表的哪个轴线上
|
||||
* @param offsetX
|
||||
* @param offsetY
|
||||
*/
|
||||
export function getXAxisAndYAxisByPosition(chart, offsetX, offsetY, seriesIndex = 0) {
|
||||
const pointInPixel = [offsetX, offsetY]
|
||||
if (
|
||||
chart.containPixel(
|
||||
{
|
||||
seriesIndex: 0
|
||||
},
|
||||
pointInPixel
|
||||
)
|
||||
) {
|
||||
const [xAxis, yAxis] = chart.convertFromPixel({ seriesIndex }, pointInPixel)
|
||||
return [xAxis, yAxis]
|
||||
}
|
||||
return null
|
||||
}
|
|
@ -55,7 +55,7 @@
|
|||
</custom-table>
|
||||
</div>
|
||||
<!-- 日志列表结束 -->
|
||||
<custom-modal title="Log" :width="950" v-model="visible" :show-footer="false">
|
||||
<custom-modal title="Log" :width="950" v-model="visible" :footer="null">
|
||||
<a-spin class="log-detail" :spinning="isGettingDetail">
|
||||
<div v-for="(logItem, index) in logInfo" :key="index">
|
||||
{{ logItem }}
|
||||
|
|
315
src/views/spectrumAnalysis/beta-gamma-analysis.vue
Normal file
315
src/views/spectrumAnalysis/beta-gamma-analysis.vue
Normal file
|
@ -0,0 +1,315 @@
|
|||
<template>
|
||||
<div class="beta-gamma-analysis">
|
||||
<!-- 二级交互栏 -->
|
||||
<div class="spectrum-analysis-sub-operators">
|
||||
<pop-over-with-icon placement="bottomLeft">
|
||||
Detailed-Information
|
||||
<detailed-infomation slot="content" />
|
||||
</pop-over-with-icon>
|
||||
<pop-over-with-icon placement="bottomLeft">
|
||||
QC Flags
|
||||
<qc-flags slot="content" :data="{ collectionTime: '123' }" />
|
||||
</pop-over-with-icon>
|
||||
<pop-over-with-icon placement="bottomLeft" style="width: 159px" v-model="spectraVisible">
|
||||
Spectra
|
||||
<spectra slot="content" v-model="spectraType" @input="spectraVisible = false" />
|
||||
</pop-over-with-icon>
|
||||
</div>
|
||||
<!-- 二级交互栏结束 -->
|
||||
<!-- 主体部分 -->
|
||||
<div class="beta-gamma-analysis-main">
|
||||
<!-- 左侧图表 -->
|
||||
<div class="beta-gamma-spectrum-sample">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Beta-Gamma Spectrum: Sample
|
||||
</template>
|
||||
<beta-gamma-spectrum-chart
|
||||
ref="betaGammaChartRef"
|
||||
:data="histogramDataList"
|
||||
@positionChange="handlePositionChange"
|
||||
@rangeChange="handleRangeChange"
|
||||
/>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
<!-- 左侧图表结束 -->
|
||||
|
||||
<!-- 右侧 -->
|
||||
<div class="beta-and-gamma-spectrum">
|
||||
<!-- 四个图表开始 -->
|
||||
<div class="spectrum-charts">
|
||||
<div class="gamma-spectrum">
|
||||
<div class="gamma-spectrum-item">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Gamma Spectrum: Original
|
||||
</template>
|
||||
<spectrum-line-chart
|
||||
ref="lineChart1Ref"
|
||||
:data="gammaOriginalData"
|
||||
@rangeChange="handleLineChartRangeChange($event, 'y')"
|
||||
/>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
<div class="gamma-spectrum-item">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Gamma Spectrum: Projected
|
||||
</template>
|
||||
<spectrum-line-chart
|
||||
ref="lineChart2Ref"
|
||||
:data="betaProjectedData"
|
||||
@rangeChange="handleLineChartRangeChange($event, 'y')"
|
||||
/>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gamma-spectrum">
|
||||
<div class="gamma-spectrum-item">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Beta Spectrum: Original
|
||||
</template>
|
||||
<spectrum-line-chart
|
||||
ref="lineChart3Ref"
|
||||
:data="betaOriginalData"
|
||||
title="Beta"
|
||||
color="#00ff1e"
|
||||
@rangeChange="handleLineChartRangeChange($event, 'x')"
|
||||
/>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
<div class="gamma-spectrum-item">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Beta Spectrum: Projected
|
||||
</template>
|
||||
<spectrum-line-chart
|
||||
ref="lineChart4Ref"
|
||||
:data="gammaProjectedData"
|
||||
title="Beta"
|
||||
color="#00ff1e"
|
||||
@rangeChange="handleLineChartRangeChange($event, 'x')"
|
||||
/>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 四个图表结束 -->
|
||||
|
||||
<!-- 结果显示开始 -->
|
||||
<div class="result-display">
|
||||
<beta-gamma-chart-container>
|
||||
<template slot="title">
|
||||
Result display
|
||||
</template>
|
||||
<result-display :data="resultDisplay"></result-display>
|
||||
</beta-gamma-chart-container>
|
||||
</div>
|
||||
<!-- 结果显示结束 -->
|
||||
</div>
|
||||
<!-- 右侧结束 -->
|
||||
|
||||
<!-- Comparison Modal 开始 -->
|
||||
<comparison-modal v-model="comparisonModalVisible" />
|
||||
<!-- Comparison Modal 结束 -->
|
||||
</div>
|
||||
<!-- 主体部分结束 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BetaGammaChartContainer from './components/BetaGammaChartContainer.vue'
|
||||
import BetaGammaSpectrumChart from './components/BetaGammaSpectrumChart.vue'
|
||||
import ComparisonModal from './components/Modals/ComparisonModal.vue'
|
||||
import ResultDisplay from './components/ResultDisplay.vue'
|
||||
import SpectrumLineChart from './components/SpectrumLineChart.vue'
|
||||
import DetailedInfomation from './components/SubOperators/DetailedInfomation.vue'
|
||||
import PopOverWithIcon from './components/SubOperators/PopOverWithIcon.vue'
|
||||
import QcFlags from './components/SubOperators/QcFlags.vue'
|
||||
import Spectra from './components/SubOperators/Spectra.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BetaGammaChartContainer,
|
||||
SpectrumLineChart,
|
||||
ResultDisplay,
|
||||
BetaGammaSpectrumChart,
|
||||
ComparisonModal,
|
||||
DetailedInfomation,
|
||||
|
||||
PopOverWithIcon,
|
||||
QcFlags,
|
||||
Spectra
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
spectraVisible: false,
|
||||
spectraType: 'Sample Data',
|
||||
|
||||
resultDisplay: [
|
||||
{
|
||||
id: 1,
|
||||
isotope: 'Xe131m',
|
||||
concentration: '0.03464',
|
||||
uncertainty: '+/-0.01988',
|
||||
mdc: '0.03464'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
isotope: 'Xe131m',
|
||||
concentration: '0.03464',
|
||||
uncertainty: '+/-0.01988',
|
||||
mdc: '0.03464'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
isotope: 'Xe131m',
|
||||
concentration: '0.03464',
|
||||
uncertainty: '+/-0.01988',
|
||||
mdc: '0.03464'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
isotope: 'Xe131m',
|
||||
concentration: '0.03464',
|
||||
uncertainty: '+/-0.01988',
|
||||
mdc: '0.03464'
|
||||
}
|
||||
],
|
||||
histogramDataList: [],
|
||||
|
||||
gammaOriginalData: [],
|
||||
betaOriginalData: [],
|
||||
betaProjectedData: [],
|
||||
gammaProjectedData: [],
|
||||
|
||||
comparisonModalVisible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resize() {
|
||||
this.$refs.betaGammaChartRef && this.$refs.betaGammaChartRef.resize()
|
||||
this.$refs.lineChart1Ref && this.$refs.lineChart1Ref.resize()
|
||||
this.$refs.lineChart2Ref && this.$refs.lineChart2Ref.resize()
|
||||
this.$refs.lineChart3Ref && this.$refs.lineChart3Ref.resize()
|
||||
this.$refs.lineChart4Ref && this.$refs.lineChart4Ref.resize()
|
||||
},
|
||||
|
||||
// 鼠标在左侧2d图表上移动时
|
||||
handlePositionChange([xAxis, yAxis]) {
|
||||
// Gamma Spectrum,根据bata-gamma的gamma channel的值(y轴)进行定位
|
||||
this.$refs.lineChart1Ref.setLinePosition(yAxis)
|
||||
this.$refs.lineChart2Ref.setLinePosition(yAxis)
|
||||
|
||||
// Beta Spectrum,根据bata-gamma的bata channel的值(x轴)进行定位
|
||||
this.$refs.lineChart3Ref.setLinePosition(xAxis)
|
||||
this.$refs.lineChart4Ref.setLinePosition(xAxis)
|
||||
},
|
||||
|
||||
// 鼠标在左侧2d图表上刷选时
|
||||
handleRangeChange([x1, x2, y1, y2]) {
|
||||
this.$refs.lineChart1Ref.setRange(y1, y2)
|
||||
this.$refs.lineChart2Ref.setRange(y1, y2)
|
||||
|
||||
this.$refs.lineChart3Ref.setRange(x1, x2)
|
||||
this.$refs.lineChart4Ref.setRange(x1, x2)
|
||||
},
|
||||
|
||||
/**
|
||||
* 右侧折线图表刷选时
|
||||
* @param {number[]} range 范围
|
||||
* @param {'x'|'y'} type 类型
|
||||
**/
|
||||
|
||||
handleLineChartRangeChange([x1, x2], type) {
|
||||
if (type == 'y') {
|
||||
// 如果是gamma channel变化
|
||||
this.$refs.lineChart1Ref.setRange(x1, x2)
|
||||
this.$refs.lineChart2Ref.setRange(x1, x2)
|
||||
} else if (type == 'x') {
|
||||
this.$refs.lineChart3Ref.setRange(x1, x2)
|
||||
this.$refs.lineChart4Ref.setRange(x1, x2)
|
||||
}
|
||||
|
||||
this.$refs.betaGammaChartRef.setRange(x1, x2, type)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newVal) {
|
||||
const {
|
||||
betaOriginalData,
|
||||
betaProjectedData,
|
||||
gammaOriginalData,
|
||||
gammaProjectedData,
|
||||
histogramDataList, // 左侧 Beta-Gamma Spectrum: Sample 图表
|
||||
spectrumData
|
||||
} = newVal
|
||||
|
||||
|
||||
console.log('%c [ spectrumData ]-246', 'font-size:13px; background:pink; color:#bf2c9f;', spectrumData)
|
||||
|
||||
this.histogramDataList = histogramDataList
|
||||
|
||||
this.gammaOriginalData = gammaOriginalData
|
||||
this.betaOriginalData = betaOriginalData
|
||||
|
||||
this.betaProjectedData = betaProjectedData
|
||||
this.gammaProjectedData = gammaProjectedData
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.beta-gamma-analysis {
|
||||
height: 100%;
|
||||
|
||||
&-main {
|
||||
height: calc(100% - 51px);
|
||||
display: flex;
|
||||
overflow: auto hidden;
|
||||
}
|
||||
|
||||
.beta-gamma-spectrum-sample {
|
||||
width: calc(100% - 1078px);
|
||||
}
|
||||
|
||||
.beta-and-gamma-spectrum {
|
||||
width: 1048px;
|
||||
margin-left: 30px;
|
||||
flex-direction: column;
|
||||
|
||||
.spectrum-charts {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - 208px);
|
||||
|
||||
.gamma-spectrum {
|
||||
display: flex;
|
||||
height: 50%;
|
||||
|
||||
&-item {
|
||||
flex: 509px;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-display {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,98 @@
|
|||
<template>
|
||||
<div class="betagamma-chart">
|
||||
<div class="betagamma-chart-title">
|
||||
<div class="title">
|
||||
<slot name="title"> </slot>
|
||||
</div>
|
||||
<div class="square">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="betagamma-chart-content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.betagamma-chart {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
&-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-right: 20px;
|
||||
height: 45px;
|
||||
border-top: 1px solid rgba(12, 235, 201, 0.3);
|
||||
border-bottom: 4px solid rgba(12, 235, 201, 0.2);
|
||||
|
||||
.title {
|
||||
padding: 0 20px;
|
||||
line-height: 40px;
|
||||
background-color: rgba(12, 235, 201, 0.05);
|
||||
color: #0cebc9;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
font-family: MicrogrammaD-MediExte;
|
||||
letter-spacing: 1px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.square {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
span {
|
||||
background-color: rgba(12, 235, 201, 0.2);
|
||||
vertical-align: middle;
|
||||
&:first-child {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
margin-right: 9px;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
margin-right: 23px;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
&:nth-child(6) {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
height: calc(100% - 45px);
|
||||
overflow: hidden;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
506
src/views/spectrumAnalysis/components/BetaGammaSpectrumChart.vue
Normal file
506
src/views/spectrumAnalysis/components/BetaGammaSpectrumChart.vue
Normal file
|
@ -0,0 +1,506 @@
|
|||
<template>
|
||||
<div class="beta-gamma-spectrum-chart">
|
||||
<div class="beta-gamma-spectrum-chart-operators">
|
||||
<span
|
||||
v-for="(item, index) in buttons"
|
||||
:key="item"
|
||||
:class="active == index ? 'active' : ''"
|
||||
@click="handleChange(index)"
|
||||
>
|
||||
{{ item }}
|
||||
</span>
|
||||
<span @click="handleUnzoom">Unzoom</span>
|
||||
</div>
|
||||
<div class="beta-gamma-spectrum-chart-main">
|
||||
<!-- 2D 图表 -->
|
||||
<div class="_2d-chart" v-show="active == 0">
|
||||
<custom-chart
|
||||
ref="chartRef"
|
||||
:option="twoDOption"
|
||||
@zr:mousemove="handleMouseMove"
|
||||
@zr:mousedown="handleMouseDown"
|
||||
@zr:mouseup="handleMouseUp"
|
||||
@brushEnd="handleBrushEnd"
|
||||
/>
|
||||
<div class="bar">
|
||||
<color-palette v-model="currCount" :maxValue="4" />
|
||||
<div>{{ currCount + 1 }}</div>
|
||||
<div class="bar-main"></div>
|
||||
<div>0</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 2D图表结束 -->
|
||||
|
||||
<!-- 3D Surface开始 -->
|
||||
<Custom3DChart v-if="active == 1" key="1" ref="_3dSurfaceRef" :option="threeDSurfaceOption" />
|
||||
<!-- 3D Surface结束 -->
|
||||
<!-- 3D Scatter -->
|
||||
<Custom3DChart v-if="active == 2" key="2" ref="_3dScannerRef" :option="threeDScatterOption" />
|
||||
<!-- 3D Scatter结束 -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
import Custom3DChart from '@/components/Custom3DChart/index.vue'
|
||||
import ColorPalette from './ColorPalette.vue'
|
||||
import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js'
|
||||
|
||||
const buttons = ['2D', '3D Surface', '3D Scatter']
|
||||
|
||||
// 2D 配置
|
||||
const twoDOption = {
|
||||
grid: {
|
||||
top: 15,
|
||||
left: 55,
|
||||
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: {
|
||||
color: '#5b9cba',
|
||||
fontSize: 16
|
||||
},
|
||||
nameLocation: 'center',
|
||||
nameGap: 30,
|
||||
axisLabel: {
|
||||
color: '#ade6ee',
|
||||
fontSize: 12
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(119, 181, 213, .3)'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
yAxis: {
|
||||
name: 'Gamma Channel',
|
||||
nameTextStyle: {
|
||||
color: '#5b9cba',
|
||||
fontSize: 16
|
||||
},
|
||||
nameLocation: 'center',
|
||||
nameGap: 35,
|
||||
axisLabel: {
|
||||
color: '#ade6ee',
|
||||
fontSize: 12
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(119, 181, 213, .3)'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
series: {
|
||||
xAxisIndex: 0,
|
||||
yAxisIndex: 0,
|
||||
type: 'scatter',
|
||||
symbolSize: 5,
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
brush: {}
|
||||
}
|
||||
|
||||
//3D Surface 配置
|
||||
|
||||
const threeDSurfaceOption = {
|
||||
visualMap: {
|
||||
show: false,
|
||||
dimension: 2,
|
||||
min: 0,
|
||||
max: 0,
|
||||
inRange: ['#47C134', '#f00']
|
||||
},
|
||||
grid3D: {
|
||||
axisLabel: {
|
||||
color: '#C4E5A6'
|
||||
},
|
||||
axisPointer: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
name: 'Beta Channel',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
yAxis3D: {
|
||||
name: 'Gamma Channel',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
zAxis3D: {
|
||||
name: 'Count',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
max: 0
|
||||
},
|
||||
series: {
|
||||
type: 'surface',
|
||||
data: []
|
||||
}
|
||||
}
|
||||
|
||||
// 3D Scatter 配置
|
||||
const threeDScatterOption = {
|
||||
grid3D: {
|
||||
axisLabel: {
|
||||
color: '#C4E5A6'
|
||||
},
|
||||
axisPointer: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
name: 'Beta Channel',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
yAxis3D: {
|
||||
name: 'Gamma Channel',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64
|
||||
},
|
||||
zAxis3D: {
|
||||
name: 'Count',
|
||||
nameTextStyle: {
|
||||
color: '#C4E5A6',
|
||||
fontSize: 14
|
||||
},
|
||||
max: 6
|
||||
},
|
||||
series: {
|
||||
type: 'scatter3D',
|
||||
symbolSize: 2.5,
|
||||
itemStyle: {
|
||||
color: '#a2d092'
|
||||
},
|
||||
data: new Array(512)
|
||||
.fill(0)
|
||||
.map(() => [parseInt(Math.random() * 256), parseInt(Math.random() * 256), 4.5 + Math.random() * 0.1])
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CustomChart,
|
||||
Custom3DChart,
|
||||
ColorPalette
|
||||
},
|
||||
data() {
|
||||
this.buttons = buttons
|
||||
return {
|
||||
active: 0,
|
||||
|
||||
maxCount: 15, // count的最大值
|
||||
currCount: 15,
|
||||
|
||||
twoDOption,
|
||||
threeDSurfaceOption,
|
||||
threeDScatterOption
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.twoDOption.brush = { toolbox: [] }
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 点击改变Beta-Gamma Spectrum: Sample图表类型
|
||||
handleChange(index) {
|
||||
this.active = index
|
||||
},
|
||||
|
||||
// 点击unzoom
|
||||
handleUnzoom() {
|
||||
this.twoDOption.xAxis.min = 0
|
||||
this.twoDOption.xAxis.max = 256
|
||||
this.twoDOption.yAxis.min = 0
|
||||
this.twoDOption.yAxis.max = 256
|
||||
|
||||
this.emitRangeChange([0, 256, 0, 256])
|
||||
},
|
||||
|
||||
resize() {
|
||||
this.$refs.chartRef && this.$refs.chartRef.resize()
|
||||
this.$refs._3dSurfaceRef && this.$refs._3dSurfaceRef.resize()
|
||||
this.$refs._3dScannerRef && this.$refs._3dScannerRef.resize()
|
||||
},
|
||||
|
||||
// 鼠标在图表上移动时
|
||||
handleMouseMove(param) {
|
||||
const { offsetX, offsetY } = param
|
||||
const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY)
|
||||
this.$emit('positionChange', point ? [point[0].toFixed(), point[1].toFixed()] : [null, null])
|
||||
},
|
||||
|
||||
// 鼠标按下时开启可刷选状态
|
||||
handleMouseDown() {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor',
|
||||
// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
|
||||
key: 'brush',
|
||||
brushOption: {
|
||||
// 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
|
||||
brushType: 'rect'
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleMouseUp() {
|
||||
setTimeout(() => {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
// 清理刷选的范围
|
||||
chart.dispatchAction({
|
||||
type: 'brush',
|
||||
areas: []
|
||||
})
|
||||
|
||||
// 改为不可刷选状态
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor'
|
||||
})
|
||||
}, 0)
|
||||
},
|
||||
|
||||
// 刷选完毕时
|
||||
handleBrushEnd(param) {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
const areas = param.areas[0]
|
||||
if (areas) {
|
||||
const range = areas.range
|
||||
const [[minX, maxX], [minY, maxY]] = range
|
||||
|
||||
const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, minY]).map(num => parseInt(num.toFixed()))
|
||||
const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, maxY]).map(num => parseInt(num.toFixed()))
|
||||
|
||||
const [x1, y2, x2, y1] = [...point1, ...point2] // 根据解析出的数据确定真实的范围
|
||||
|
||||
this.twoDOption.xAxis.min = x1
|
||||
this.twoDOption.xAxis.max = x2
|
||||
this.twoDOption.yAxis.min = y1
|
||||
this.twoDOption.yAxis.max = y2
|
||||
|
||||
this.emitRangeChange([x1, x2, y1, y2])
|
||||
}
|
||||
|
||||
// 清理刷选的范围
|
||||
chart.dispatchAction({
|
||||
type: 'brush',
|
||||
areas: []
|
||||
})
|
||||
|
||||
// 改为不可刷选状态
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor'
|
||||
})
|
||||
},
|
||||
|
||||
// 通知上层范围改变
|
||||
emitRangeChange(range) {
|
||||
this.$emit('rangeChange', range)
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置范围
|
||||
* @param {number} x1
|
||||
* @param {number} x2
|
||||
* @param {'x' | 'y'} type 要改变哪条轴
|
||||
*/
|
||||
setRange(x1, x2, type) {
|
||||
if (type == 'x') {
|
||||
this.twoDOption.xAxis.min = x1
|
||||
this.twoDOption.xAxis.max = x2
|
||||
} else if (type == 'y') {
|
||||
this.twoDOption.yAxis.min = x1
|
||||
this.twoDOption.yAxis.max = x2
|
||||
}
|
||||
},
|
||||
|
||||
// 颜色插值
|
||||
interpolateColor(color1, color2, percentage) {
|
||||
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 }
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newVal) {
|
||||
this.twoDOption.series.data = newVal.filter(item => item.c).map(item => [item.b, item.g, item.c]) // 设置2D Scatter数据
|
||||
|
||||
const treeDSurfaceZMax = Math.max(...newVal.map(item => item.c))
|
||||
this.threeDSurfaceOption.zAxis3D.max = Math.ceil(treeDSurfaceZMax * 1.2)
|
||||
this.threeDSurfaceOption.series.data = newVal.map(item => [item.b, item.g, item.c]) // 设置3D surface数据
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
|
||||
currCount: {
|
||||
handler(val) {
|
||||
if (val <= this.maxCount) {
|
||||
const { r, g, b } = this.interpolateColor(
|
||||
{ r: 255, g: 0, b: 0 },
|
||||
{ r: 255, g: 255, b: 255 },
|
||||
val / this.maxCount
|
||||
)
|
||||
|
||||
this.twoDOption.series.itemStyle.color = `rgb(${r}, ${g}, ${b})`
|
||||
} else {
|
||||
this.twoDOption.series.itemStyle.color = '#fff'
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.beta-gamma-spectrum-chart {
|
||||
height: 100%;
|
||||
|
||||
&-operators {
|
||||
text-align: right;
|
||||
overflow: auto;
|
||||
height: 26px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 9px;
|
||||
|
||||
.ant-space-item:first-child {
|
||||
span {
|
||||
width: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
line-height: 26px;
|
||||
width: 100px;
|
||||
background-color: #406979;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.active {
|
||||
background-color: #1397a3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-main {
|
||||
height: calc(100% - 40px);
|
||||
margin-top: 15px;
|
||||
|
||||
._2d-chart {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
||||
.custom-chart {
|
||||
width: calc(100% - 45px);
|
||||
}
|
||||
|
||||
.bar {
|
||||
width: 30px;
|
||||
margin-left: 15px;
|
||||
height: 100%;
|
||||
color: #ade6ee;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 38px;
|
||||
text-align: center;
|
||||
|
||||
&-main {
|
||||
display: inline-block;
|
||||
width: 14px;
|
||||
height: calc(100% - 70px);
|
||||
background: linear-gradient(to bottom, #ff0000 0, #fff 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
163
src/views/spectrumAnalysis/components/ColorPalette.vue
Normal file
163
src/views/spectrumAnalysis/components/ColorPalette.vue
Normal file
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<div
|
||||
ref="containerElemRef"
|
||||
class="color-palette"
|
||||
:style="{ width: circleWidth + 'px', height: circleWidth + 'px' }"
|
||||
@click="handleClick"
|
||||
@mousedown="handleMouseDown"
|
||||
@mousemove="handleMouseMove"
|
||||
@mouseup="handleMouseUp"
|
||||
@mouseout="handleMouseOut"
|
||||
>
|
||||
<span
|
||||
ref="dotElemRef"
|
||||
class="dot"
|
||||
:style="{
|
||||
width: dotWidth + 'px',
|
||||
height: dotWidth + 'px',
|
||||
left: this.dotPosition.x,
|
||||
top: this.dotPosition.y
|
||||
}"
|
||||
></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
maxValue: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
circleWidth: {
|
||||
type: Number,
|
||||
default: 26
|
||||
},
|
||||
dotWidth: {
|
||||
type: Number,
|
||||
default: 5
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dotPosition: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
isMouseDown: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick({ offsetX, offsetY }) {
|
||||
this.setPositionByMouseEvent(offsetX, offsetY)
|
||||
},
|
||||
|
||||
// 鼠标按下
|
||||
handleMouseDown({ offsetX, offsetY }) {
|
||||
this.setPositionByMouseEvent(offsetX, offsetY)
|
||||
this.isMouseDown = true
|
||||
},
|
||||
|
||||
handleMouseMove({ offsetX, offsetY }) {
|
||||
if (this.isMouseDown) {
|
||||
this.setPositionByMouseEvent(offsetX, offsetY)
|
||||
}
|
||||
},
|
||||
|
||||
// 鼠标抬起
|
||||
handleMouseUp() {
|
||||
this.isMouseDown = false
|
||||
},
|
||||
|
||||
// 鼠标移开
|
||||
handleMouseOut() {
|
||||
this.isMouseDown = false
|
||||
},
|
||||
|
||||
setPositionByMouseEvent(offsetX, offsetY) {
|
||||
const { degree, radian } = this.getDegree([offsetX, offsetY])
|
||||
for (let index = 0; index < this.range; index++) {
|
||||
if (degree >= this.perDegree * index && degree < this.perDegree * (index + 1)) {
|
||||
this.$emit('input', index)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.setDotPosition(radian)
|
||||
},
|
||||
|
||||
setDotPosition(radian) {
|
||||
const circleRadius = this.circleWidth / 2 // 半径
|
||||
const dotRadius = circleRadius - this.dotWidth // 绘制圆点时的半径
|
||||
|
||||
this.dotPosition = {
|
||||
x: circleRadius - dotRadius * Math.sin(radian) - this.dotWidth / 2 + 'px',
|
||||
y: circleRadius + dotRadius * Math.cos(radian) - this.dotWidth / 2 + 'px'
|
||||
}
|
||||
},
|
||||
// 工具方法
|
||||
|
||||
/**
|
||||
* 根据圆心和某个点,计算从圆心到该点的角度
|
||||
*/
|
||||
getDegree(point) {
|
||||
// 计算两个点在 x 轴上的差值和在 y 轴上的差值
|
||||
const circleRadius = this.circleWidth / 2 // 半径
|
||||
|
||||
const [pointX, pointY] = point
|
||||
const deltaX = circleRadius - pointX
|
||||
const deltaY = pointY - circleRadius
|
||||
// 使用反正切函数计算角度(弧度)
|
||||
const radian = Math.atan2(deltaX, deltaY)
|
||||
let degree = radian * (180 / Math.PI)
|
||||
if (degree < 0) {
|
||||
degree = 360 + degree
|
||||
}
|
||||
return {
|
||||
radian,
|
||||
degree
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
value: {
|
||||
handler(newVal) {
|
||||
const degree = newVal * this.perDegree
|
||||
const radian = (degree * Math.PI) / 180 // 角度转弧度
|
||||
|
||||
this.setDotPosition(radian)
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
range() {
|
||||
return this.maxValue > 50 ? this.maxValue : 50
|
||||
},
|
||||
|
||||
perDegree() {
|
||||
return 360 / this.range
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.color-palette {
|
||||
border-radius: 50%;
|
||||
background-color: #ff5858;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border-radius: 50%;
|
||||
background-color: #f00;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :title="type + ' Comment'" :okHandler="handleOk">
|
||||
<a-textarea :rows="10" v-model="content"></a-textarea>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
},
|
||||
type: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
content: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async handleOk() {
|
||||
if (!this.content) {
|
||||
this.$message.warn('Please Input Comment')
|
||||
throw new Error('Content Is Empty')
|
||||
}
|
||||
|
||||
console.log('%c [ ]-29', 'font-size:13px; background:pink; color:#bf2c9f;', this.type, this.content)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
if (this.value) {
|
||||
this.content = ''
|
||||
}
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -0,0 +1,162 @@
|
|||
<template>
|
||||
<custom-modal centered v-model="visible" :width="1200" title="Fit Peaks and Baseline">
|
||||
<custom-table :columns="columns" :list="list">
|
||||
<template v-for="(slot, index) in slots" :slot="slot.slotName" slot-scope="{ record }">
|
||||
<a-checkbox v-if="slot.isCheckbox" :key="index" v-model="record[slot.dataIndex]">
|
||||
Fixed
|
||||
</a-checkbox>
|
||||
<a-input v-else :key="index" v-model="record[slot.dataIndex]"></a-input>
|
||||
</template>
|
||||
</custom-table>
|
||||
<div slot="custom-footer">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handlePeaks">Peaks</a-button>
|
||||
<a-button>Cancel</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const columns = [
|
||||
{
|
||||
title: 'Peak',
|
||||
dataIndex: 'peak',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'Peak'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Nuclide',
|
||||
dataIndex: 'nuclide',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'Nuclide'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Energy',
|
||||
dataIndex: 'energy',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'Energy'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'NetArea',
|
||||
dataIndex: 'netAreaInput',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'NetAreaInput'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'FWHM',
|
||||
dataIndex: 'fwhmInput',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'FWHMInput'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Step',
|
||||
dataIndex: 'Step',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'Step'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'BWGamma',
|
||||
dataIndex: 'bwGamma',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'BWGamma'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'NetArea',
|
||||
dataIndex: 'netAreaCheckbox',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'NetAreaCheckbox'
|
||||
},
|
||||
isCheckbox: true
|
||||
},
|
||||
{
|
||||
title: 'Centroid',
|
||||
dataIndex: 'centroid',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'Centroid'
|
||||
},
|
||||
isCheckbox: true
|
||||
},
|
||||
{
|
||||
title: 'FWHM',
|
||||
dataIndex: 'fwhmCheckbox',
|
||||
width: 100,
|
||||
scopedSlots: {
|
||||
customRender: 'FWHMCheckbox'
|
||||
},
|
||||
isCheckbox: true
|
||||
}
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
peak: 'peak',
|
||||
nuclide: 'nuclide',
|
||||
energy: 'energy',
|
||||
netAreaInput: 'netAreaInput',
|
||||
fwhmInput: 'fwhmInput',
|
||||
Step: 'Step',
|
||||
bwGamma: 'bwGamma',
|
||||
netAreaCheckbox: false,
|
||||
centroid: false,
|
||||
fwhmCheckbox: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlePeaks() {
|
||||
console.log('%c [ ]-134', 'font-size:13px; background:pink; color:#bf2c9f;', this.list)
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
if (this.value) {
|
||||
this.content = ''
|
||||
}
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
},
|
||||
slots() {
|
||||
return columns.map(column => {
|
||||
return {
|
||||
isCheckbox: column.isCheckbox,
|
||||
dataIndex: column.dataIndex,
|
||||
slotName: column.scopedSlots.customRender
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
|
@ -0,0 +1,128 @@
|
|||
<template>
|
||||
<custom-chart :option="option" />
|
||||
</template>
|
||||
<script>
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
const initialOption = {
|
||||
grid: {
|
||||
top: 40,
|
||||
bottom: 50,
|
||||
right: 30
|
||||
},
|
||||
title: {
|
||||
text: 'Energy',
|
||||
textStyle: {
|
||||
color: '#8FD4F8',
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal'
|
||||
},
|
||||
right: 10,
|
||||
bottom: 5
|
||||
},
|
||||
xAxis: {
|
||||
min: 620.68,
|
||||
max: 629.16,
|
||||
splitNumber: 3,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
min: 417,
|
||||
max: 327,
|
||||
interval: 90,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
name: 'Counts',
|
||||
nameTextStyle: {
|
||||
color: '#8FD4F8',
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
data: [
|
||||
[620.68, 410],
|
||||
[621.98, 390],
|
||||
[622.12, 337],
|
||||
[623.53, 400],
|
||||
[624.37, 410],
|
||||
[625.37, 410],
|
||||
[626.37, 410],
|
||||
[627.37, 410],
|
||||
[628.37, 410]
|
||||
],
|
||||
itemStyle: {
|
||||
color: '#8BB93C'
|
||||
},
|
||||
symbol: 'none',
|
||||
markLine: {
|
||||
data: [
|
||||
{
|
||||
xAxis: 625.14,
|
||||
label: {
|
||||
formatter: '{c} keV',
|
||||
color: '#f00',
|
||||
fontWeight: 'bold',
|
||||
fontSize: 14
|
||||
}
|
||||
}
|
||||
],
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
color: '#f00'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: [
|
||||
[620.68, 367],
|
||||
[622, 367],
|
||||
[623, 367],
|
||||
[624, 367],
|
||||
[625, 367],
|
||||
[626, 367],
|
||||
[627, 367],
|
||||
[628, 367],
|
||||
[629, 367]
|
||||
],
|
||||
itemStyle: {
|
||||
color: '#8FD4F8'
|
||||
},
|
||||
symbol: 'none'
|
||||
}
|
||||
]
|
||||
}
|
||||
export default {
|
||||
components: {
|
||||
CustomChart
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
option: initialOption
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,564 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="1200" title="Nuclide Review" :footer="null">
|
||||
<div class="nuclide-review-search">
|
||||
<span @click="handleNuclideChange('prev')"><</span>
|
||||
<a-form-model layout="inline">
|
||||
<a-form-model-item label="Energy">
|
||||
<a-input-number></a-input-number>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="Tolerance">
|
||||
<a-input-number></a-input-number>
|
||||
</a-form-model-item>
|
||||
<a-button type="primary">Search</a-button>
|
||||
</a-form-model>
|
||||
<span @click="handleNuclideChange('next')">></span>
|
||||
</div>
|
||||
|
||||
<!-- 以下是表格部分 -->
|
||||
<div class="nuclide-review-table">
|
||||
<div class="nuclide-review-table-nuclide">
|
||||
<div class="nuclide-review-table-nuclide-header">Nuclide</div>
|
||||
<div class="nuclide-review-table-nuclide-content">
|
||||
<div
|
||||
class="nuclide-review-table-nuclide-item"
|
||||
:class="currNuclide == item ? 'active' : ''"
|
||||
v-for="(item, index) in nuclideList"
|
||||
:key="item.id"
|
||||
@click="handleNuclideClick(index)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nuclide-review-table-table">
|
||||
<div class="title">
|
||||
<a-form-model>
|
||||
<a-row>
|
||||
<a-col :span="6">
|
||||
<a-form-model-item label="Name">
|
||||
{{ currNuclide.title }}
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-model-item label="Half Life">
|
||||
2
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-model-item label="Half Life Err">
|
||||
3
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<a-form-model-item label="Lines">
|
||||
4
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
</div>
|
||||
<a-table
|
||||
:class="list.length ? 'has-data' : ''"
|
||||
:columns="columns"
|
||||
:dataSource="list"
|
||||
:scroll="{ y: 180 }"
|
||||
:customRow="customRow"
|
||||
:pagination="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表格部分结束 -->
|
||||
|
||||
<!-- 以下是图表部分 -->
|
||||
<div class="nuclide-review-chart">
|
||||
<div class="nuclide-review-chart-prev">
|
||||
<span @click="handleChangeChart('prev')">
|
||||
<
|
||||
</span>
|
||||
</div>
|
||||
<a-row class="nuclide-review-chart-list">
|
||||
<a-col class="nuclide-review-chart-item" :span="8" v-for="(chartItem, index) in currChartList" :key="index">
|
||||
<p>Line{{ chartItem.id }}</p>
|
||||
<div class="nuclide-review-chart-item-chart" :class="currTableItem.id == chartItem.id ? 'active' : ''">
|
||||
<nuclide-review-chart />
|
||||
</div>
|
||||
<p>Abundance: {{ chartItem.abundance }}</p>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<div class="nuclide-review-chart-next">
|
||||
<span @click="handleChangeChart('next')">
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图表部分结束 -->
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NuclideReviewChart from './NuclideReviewChart.vue'
|
||||
const columns = [
|
||||
{
|
||||
title: 'Id',
|
||||
dataIndex: 'id',
|
||||
width: '5%'
|
||||
},
|
||||
{
|
||||
title: 'Full Name',
|
||||
dataIndex: 'fullName',
|
||||
width: '15%'
|
||||
},
|
||||
{
|
||||
title: 'Energy',
|
||||
dataIndex: 'energy',
|
||||
width: '15%'
|
||||
},
|
||||
{
|
||||
title: 'Energy Err',
|
||||
dataIndex: 'energyErr',
|
||||
width: '15%'
|
||||
},
|
||||
{
|
||||
title: 'Abundance(%)',
|
||||
dataIndex: 'abundance',
|
||||
width: '15%'
|
||||
},
|
||||
{
|
||||
title: 'Abundance Err(%)',
|
||||
dataIndex: 'abundanceErr',
|
||||
width: '15%'
|
||||
},
|
||||
{
|
||||
title: 'KeyLine',
|
||||
dataIndex: 'keyLine',
|
||||
width: '15%'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
components: { NuclideReviewChart },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
nuclideList: [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Ag111',
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Eu157',
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'Mo99',
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Pb204M',
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '7',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
},
|
||||
{
|
||||
id: '8',
|
||||
fullName: 'fullName',
|
||||
energy: 'energy',
|
||||
energyErr: 'energyErr',
|
||||
abundance: 'abundance',
|
||||
abundanceErr: 'abundanceErr',
|
||||
keyLine: 'keyLine'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
list: [], // 表格里的数据
|
||||
currNuclide: {},
|
||||
|
||||
currTableItem: {}, // 选中的表格中的行
|
||||
|
||||
currChartList: [] // 当前展示的图表的列表,一般是3个
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 搜索栏的向前/向后按钮
|
||||
handleNuclideChange(direction) {
|
||||
const currIndex = this.nuclideList.findIndex(item => item == this.currNuclide)
|
||||
if (direction == 'prev' && currIndex > 0) {
|
||||
this.handleNuclideClick(currIndex - 1)
|
||||
} else if (direction == 'next' && currIndex !== this.nuclideList.length - 1) {
|
||||
this.handleNuclideClick(currIndex + 1)
|
||||
}
|
||||
},
|
||||
|
||||
handleNuclideClick(index) {
|
||||
this.currNuclide = this.nuclideList[index]
|
||||
this.list = this.currNuclide.data
|
||||
|
||||
this.selectTableRow(0)
|
||||
},
|
||||
|
||||
selectTableRow(index) {
|
||||
const record = this.list[index]
|
||||
this.currTableItem = record
|
||||
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
if (index == 0) {
|
||||
// 选中了第一个,则往后数三个
|
||||
endIndex = startIndex + 3
|
||||
} else if (index == this.list.length - 1) {
|
||||
// 选中了最后一个,则往前数三个
|
||||
endIndex = index + 1
|
||||
startIndex = endIndex - 3
|
||||
} else {
|
||||
startIndex = index - 1
|
||||
endIndex = index + 2
|
||||
}
|
||||
if (startIndex < 0) {
|
||||
startIndex = 0
|
||||
}
|
||||
this.currChartList = this.list.slice(startIndex, endIndex)
|
||||
},
|
||||
|
||||
// 向前/向后切换图表
|
||||
handleChangeChart(direction) {
|
||||
const currIndex = this.list.findIndex(item => item == this.currTableItem)
|
||||
if (direction == 'prev') {
|
||||
const willJumpIndex = currIndex - 3
|
||||
if (willJumpIndex >= 0) {
|
||||
this.selectTableRow(willJumpIndex)
|
||||
}
|
||||
else {
|
||||
this.selectTableRow(0)
|
||||
}
|
||||
}
|
||||
else if (direction == 'next') {
|
||||
const willJumpIndex = currIndex + 3
|
||||
if (willJumpIndex <= this.list.length - 2) {
|
||||
this.selectTableRow(willJumpIndex)
|
||||
}
|
||||
else {
|
||||
this.selectTableRow(this.list.length - 1)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 实现单击选中/反选功能
|
||||
customRow(record, index) {
|
||||
return {
|
||||
class: 'custom-table-row' + (this.currTableItem == record ? ' ant-table-row-selected' : ''),
|
||||
on: {
|
||||
click: () => {
|
||||
this.selectTableRow(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
if (this.value) {
|
||||
this.content = ''
|
||||
}
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nuclide-review {
|
||||
&-search {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-top: 1px solid rgba(12, 235, 201, 0.3);
|
||||
border-bottom: 1px solid rgba(12, 235, 201, 0.3);
|
||||
background-color: rgba(12, 235, 201, 0.05);
|
||||
|
||||
> span {
|
||||
color: @primary-color;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid @primary-color;
|
||||
border-radius: 50%;
|
||||
margin: 0 10px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.ant-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
&-table {
|
||||
display: flex;
|
||||
height: 250px;
|
||||
margin-top: 10px;
|
||||
|
||||
&-nuclide {
|
||||
width: 150px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-header {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
background-color: #126b82;
|
||||
}
|
||||
|
||||
&-content {
|
||||
background-color: #275466;
|
||||
flex: 1;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&-item {
|
||||
padding: 0 5px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.active {
|
||||
background-color: #296d81;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-table {
|
||||
margin-left: 20px;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.title {
|
||||
::v-deep {
|
||||
.ant-form {
|
||||
&-item {
|
||||
margin-bottom: 0;
|
||||
|
||||
&-label,
|
||||
&-control {
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-wrapper {
|
||||
&.has-data {
|
||||
::v-deep {
|
||||
.ant-table-body {
|
||||
height: 180px;
|
||||
background-color: #06282a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table-placeholder {
|
||||
height: 181px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-chart {
|
||||
margin-top: 20px;
|
||||
height: 300px;
|
||||
background-color: #05354c;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&-list {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-item {
|
||||
height: 100%;
|
||||
p {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&-chart {
|
||||
height: calc(100% - 60px);
|
||||
border: 4px solid transparent;
|
||||
|
||||
&.active {
|
||||
background-color: #0a6f82;
|
||||
border-color: #0d8696;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-prev,
|
||||
&-next {
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
color: @primary-color;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid @primary-color;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-table-row {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,489 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="1280" title="Interactive Analyse Tools" :footer="null">
|
||||
<div class="interactive-analysis-tools">
|
||||
<div class="interactive-analysis-tools-left">
|
||||
<div class="chart">
|
||||
<custom-chart :option="option" />
|
||||
</div>
|
||||
<div class="thumbnail"></div>
|
||||
<div class="table">
|
||||
<p class="title">
|
||||
<span @click="handleChangeMarkLine('prev')">< </span>
|
||||
6 Peaks with Anthro.Nuclides
|
||||
<span @click="handleChangeMarkLine('next')">></span>
|
||||
</p>
|
||||
<custom-table
|
||||
:class="list.length ? 'has-data' : ''"
|
||||
:list="list"
|
||||
:columns="columns"
|
||||
:scroll="{ y: 288 }"
|
||||
:selectedRowKeys.sync="selectedKeys"
|
||||
>
|
||||
</custom-table>
|
||||
<div class="operators">
|
||||
<a-button type="primary" @click="nuclideReviewModalVisible = true">Nuclide Review Window</a-button>
|
||||
<a-button type="primary" @click="handleAddComment('Peak')">Add Peak Comment</a-button>
|
||||
<a-button type="primary" @click="handleAddComment('General')">Add General Comment</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="interactive-analysis-tools-right">
|
||||
<title-over-boarder title="Peak">
|
||||
<div class="peak-box">
|
||||
<!-- 按钮组1 -->
|
||||
<template v-if="btnGroupType == 1">
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Insert</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Delete</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Fit</a-button>
|
||||
</div>
|
||||
|
||||
<div class="peak-box-item symbol" :key="4">
|
||||
<a-button type="primary" @click="handleChangeMarkLine('prev')"><</a-button>
|
||||
<a-button type="primary" @click="handleChangeMarkLine('next')">></a-button>
|
||||
</div>
|
||||
|
||||
<div class="peak-box-item base-line">
|
||||
<a-button type="primary" @click="btnGroupType = 2">BaseLine</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 按钮组2 -->
|
||||
<template v-if="btnGroupType == 2">
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">(A)dd CP</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">(R)emove CP</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">(M)odify CP</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Edit (S)lope</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Undo</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary">Replot</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary" @click="btnGroupType = 1">Accept</a-button>
|
||||
</div>
|
||||
<div class="peak-box-item">
|
||||
<a-button type="primary" @click="btnGroupType = 1">Cancel</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<div class="reset-btn-box">
|
||||
<a-button type="primary">Reset Chart</a-button>
|
||||
</div>
|
||||
<div class="identify-box">
|
||||
<title-over-boarder title="Nuclide Identify">
|
||||
<a-form-model class="tolerance">
|
||||
<a-form-model-item label="Tolerance">
|
||||
<a-input-number></a-input-number>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
<div class="identify-item">
|
||||
<div class="title">
|
||||
Possible Nuclide
|
||||
</div>
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
<div class="identify-item">
|
||||
<div class="title">
|
||||
Nuclide Identified
|
||||
</div>
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
<div class="identify-operators">
|
||||
<a-space>
|
||||
<a-input></a-input>
|
||||
<a-button type="primary">Add</a-button>
|
||||
<a-button type="primary" @click="handleDel">Del</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Comment弹窗 开始 -->
|
||||
<comment-modal v-model="commentModalVisible" :type="commentType" />
|
||||
<!-- Comment弹窗 结束 -->
|
||||
<!-- Fit Peaks and Baseline弹窗 开始 -->
|
||||
<fit-peaks-and-base-line-modal v-model="fitPeaksAndBaselineModalVisible" />
|
||||
<!-- Fit Peaks and Baseline弹窗 结束 -->
|
||||
<!-- Nuclide Review 弹窗开始 -->
|
||||
<nuclide-review-modal v-model="nuclideReviewModalVisible" />
|
||||
<!-- Nuclide Review 弹窗结束 -->
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
import TitleOverBoarder from '../../TitleOverBoarder.vue'
|
||||
import CommentModal from './components/CommentModal.vue'
|
||||
import FitPeaksAndBaseLineModal from './components/FitPeaksAndBaselineModal.vue'
|
||||
import NuclideReviewModal from './components/NuclideReviewModal.vue'
|
||||
|
||||
const initialOption = {
|
||||
grid: {
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
left: 100,
|
||||
right: 20
|
||||
},
|
||||
xAxis: {
|
||||
min: 1,
|
||||
max: 8192,
|
||||
interval: 1143,
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
min: 1,
|
||||
max: 994914,
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
name: 'Counts',
|
||||
nameLocation: 'center',
|
||||
nameGap: 60,
|
||||
nameTextStyle: {
|
||||
fontSize: 16,
|
||||
color: '#5b9cba'
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: '#FCFE02'
|
||||
},
|
||||
markLine: {
|
||||
data: [
|
||||
{
|
||||
xAxis: 1000
|
||||
}
|
||||
],
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
color: '#f00'
|
||||
},
|
||||
label: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: '#F87E28'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: [],
|
||||
itemStyle: {
|
||||
color: '#01F6FE'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
width: 60
|
||||
},
|
||||
{
|
||||
title: 'Energy (keV)',
|
||||
dataIndex: 'energy',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'Centroid (C)',
|
||||
dataIndex: 'centroid',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'FWHM (keV)',
|
||||
dataIndex: 'fwhm',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'Area',
|
||||
dataIndex: 'area',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'Detectability',
|
||||
dataIndex: 'detectability',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'Cmnt',
|
||||
dataIndex: 'cmnt',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: 'Nuclides',
|
||||
dataIndex: 'nuclides',
|
||||
width: 120
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CustomChart,
|
||||
TitleOverBoarder,
|
||||
CommentModal,
|
||||
FitPeaksAndBaseLineModal,
|
||||
NuclideReviewModal
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
option: initialOption,
|
||||
list: [],
|
||||
commentModalVisible: false, // Comment 弹窗是否显示
|
||||
commentType: 'Peak',
|
||||
|
||||
btnGroupType: 1, // 右侧 Peak 中的按钮组切换
|
||||
|
||||
selectedKeys: [], // 选中的列表
|
||||
|
||||
fitPeaksAndBaselineModalVisible: false, // Fit Peaks And Base Line 弹窗
|
||||
nuclideReviewModalVisible: false // Nuclide Review 弹窗
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换图表上的红色竖线
|
||||
handleChangeMarkLine(direction) {
|
||||
if (direction == 'prev') {
|
||||
this.option.series[0].markLine.data[0].xAxis = 900
|
||||
} else if (direction == 'next') {
|
||||
this.option.series[0].markLine.data[0].xAxis = 1100
|
||||
}
|
||||
this.list = new Array(20).fill(0).map((_, index) => ({
|
||||
id: index.toString(),
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
fwhm: 'fwhm',
|
||||
area: 'area',
|
||||
detectability: 'detectability',
|
||||
cmnt: 'cmnt',
|
||||
nuclides: 'nuclides'
|
||||
}))
|
||||
},
|
||||
// 显示comment弹窗
|
||||
handleAddComment(type) {
|
||||
this.commentType = type
|
||||
this.commentModalVisible = true
|
||||
},
|
||||
|
||||
// 删除
|
||||
handleDel() {
|
||||
if (!this.selectedKeys.length) {
|
||||
this.$message.warn('Please Select At Least 1 Peak To Delete')
|
||||
return
|
||||
}
|
||||
|
||||
this.$warning({
|
||||
title: 'Warning',
|
||||
content: 'Are you sure to delete this peak?',
|
||||
onOk: () => {
|
||||
console.log('%c [ ]-294', 'font-size:13px; background:pink; color:#bf2c9f;', this.selectedKeys)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.interactive-analysis-tools {
|
||||
display: flex;
|
||||
|
||||
&-left {
|
||||
width: 75%;
|
||||
margin-right: 20px;
|
||||
|
||||
.chart {
|
||||
height: 331px;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
height: 50px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 35px;
|
||||
background-color: #255369;
|
||||
}
|
||||
|
||||
.table {
|
||||
.title {
|
||||
color: #0cebc9;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-table {
|
||||
&.has-data {
|
||||
::v-deep {
|
||||
.ant-table-body {
|
||||
height: 288px;
|
||||
background-color: #06282a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table-placeholder {
|
||||
height: 289px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operators {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
gap: 10px;
|
||||
|
||||
.ant-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
.peak-box {
|
||||
height: 326px;
|
||||
|
||||
&-item:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
display: flex;
|
||||
|
||||
.ant-btn {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.base-line {
|
||||
margin-top: 136px;
|
||||
}
|
||||
|
||||
.reset-btn-box {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.identify-box {
|
||||
.tolerance {
|
||||
::v-deep {
|
||||
.ant-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
&-control-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-control {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-number {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.identify-item {
|
||||
.title {
|
||||
background-color: #497e9d;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.content {
|
||||
height: 80px;
|
||||
background-color: #275466;
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.identify-operators {
|
||||
display: flex;
|
||||
|
||||
.ant-btn {
|
||||
width: 50px;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,193 @@
|
|||
<template>
|
||||
<custom-modal
|
||||
v-model="visible"
|
||||
:width="900"
|
||||
title="Analysis Settings"
|
||||
class="analysis-settings"
|
||||
:okHanlder="handleOk"
|
||||
>
|
||||
<!-- 第一行 -->
|
||||
<div class="analysis-settings-item">
|
||||
<title-over-boarder title="Peak Searching">
|
||||
<a-form-model :colon="false" :labelCol="{ style: { width: '160px' } }">
|
||||
<a-form-model-item label="ECutAnalysis_Low">
|
||||
<div class="input-with-unit">
|
||||
<a-input></a-input>
|
||||
KeV
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="ECutAnalysis_High">
|
||||
<div class="input-with-unit">
|
||||
<a-input></a-input>
|
||||
KeV
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="EnergyTolerance">
|
||||
<div class="input-with-unit">
|
||||
<a-input></a-input>
|
||||
KeV
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="PSS_low">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</title-over-boarder>
|
||||
<title-over-boarder title="Calibration Peak Searching">
|
||||
<a-form-model :colon="false" :labelCol="{ style: { width: '170px' } }">
|
||||
<a-form-model-item label="CalibrationPSS_low">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="CalibrationPSS_high">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item>
|
||||
<a-checkbox>
|
||||
Update Calibration
|
||||
</a-checkbox>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item>
|
||||
<a-checkbox>
|
||||
Keep Calibration Peak Search Peaks
|
||||
</a-checkbox>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
|
||||
<!-- 第二行 -->
|
||||
<div class="analysis-settings-item">
|
||||
<title-over-boarder title="Baseline Param">
|
||||
<a-form-model :colon="false" :labelCol="{ style: { width: '90px' } }">
|
||||
<a-form-model-item label="k_back">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="k_alpha">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="k_beta">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</title-over-boarder>
|
||||
<div>
|
||||
<a-form-model :colon="false" :labelCol="{ style: { width: '150px' } }">
|
||||
<title-over-boarder title="BaseImprove">
|
||||
<a-form-model-item label="BaseImprovePSS">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
</title-over-boarder>
|
||||
<title-over-boarder title="LC Computing" style="margin-top: 20px">
|
||||
<a-form-model-item label="RiskLevelK">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
</title-over-boarder>
|
||||
</a-form-model>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三行 -->
|
||||
<div class="analysis-settings-item">
|
||||
<title-over-boarder title="Activity Reference Time">
|
||||
<custom-date-picker show-time v-model="formModel.activityReferenceTime"></custom-date-picker>
|
||||
</title-over-boarder>
|
||||
<title-over-boarder title="Concentration Reference Time">
|
||||
<custom-date-picker show-time v-model="formModel.concentrationReferenceTime"></custom-date-picker>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TitleOverBoarder from '../TitleOverBoarder.vue'
|
||||
export default {
|
||||
components: { TitleOverBoarder },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formModel: {
|
||||
activityReferenceTime: undefined,
|
||||
concentrationReferenceTime: undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleOk() {
|
||||
console.log('%c [ handleOk ]-121', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.analysis-settings {
|
||||
&-item {
|
||||
display: flex;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
> div {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form {
|
||||
&-item {
|
||||
margin-bottom: 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-form-item {
|
||||
&-label {
|
||||
text-align: left;
|
||||
|
||||
label {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&-control-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input {
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.input-with-unit {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.ant-input {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
130
src/views/spectrumAnalysis/components/Modals/ComparisonModal.vue
Normal file
130
src/views/spectrumAnalysis/components/Modals/ComparisonModal.vue
Normal file
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" title="Comparison" :width="800" :footer="null" class="comparison-modal">
|
||||
<div class="comparison-list">
|
||||
<div class="comparison-list-item" v-for="(item, index) in compareList" :key="index">
|
||||
<div class="comparison-list-item-title">{{ item.title }}</div>
|
||||
<custom-table :list="item.list" :columns="columns"></custom-table>
|
||||
</div>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const columns = [
|
||||
{
|
||||
title: 'Isotope',
|
||||
dataIndex: 'isotope'
|
||||
},
|
||||
{
|
||||
title: 'Concentration',
|
||||
dataIndex: 'concentration'
|
||||
},
|
||||
{
|
||||
title: 'Uncertainty',
|
||||
dataIndex: 'uncertainty'
|
||||
},
|
||||
{
|
||||
title: 'MDC[mBq / m3 ]',
|
||||
dataIndex: 'mdc'
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
compareList: [
|
||||
{
|
||||
title: 'ARMD',
|
||||
list: [
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
},
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
},
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'IDC',
|
||||
list: [
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
},
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
},
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
},
|
||||
{
|
||||
isotope: 'isotope',
|
||||
concentration: 'concentration',
|
||||
uncertainty: 'uncertainty',
|
||||
mdc: 'mdc'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.comparison-modal {
|
||||
::v-deep {
|
||||
.ant-modal-body {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comparison-list {
|
||||
&-item {
|
||||
&-title {
|
||||
color: #0cebc9;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,333 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="1280" title="Efficiency Calibration" :footer="null">
|
||||
<div class="efficiency-calibration">
|
||||
<div class="left">
|
||||
<!-- Calibration Data -->
|
||||
<title-over-boarder title="Calibration Data">
|
||||
<div class="calibration-data">
|
||||
<a-form-model
|
||||
:colon="false"
|
||||
:labelCol="{
|
||||
style: {
|
||||
width: '70px',
|
||||
textAlign: 'left',
|
||||
flexShrink: 0
|
||||
}
|
||||
}"
|
||||
:wrapperCol="{
|
||||
style: {
|
||||
flex: 1
|
||||
}
|
||||
}"
|
||||
>
|
||||
<a-form-model-item label="Energy">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="Efficiency">
|
||||
<a-input></a-input>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="' '">
|
||||
<a-button type="primary">Insert</a-button>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="' '">
|
||||
<a-button type="primary">Modify</a-button>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="' '">
|
||||
<a-button type="primary">Delete</a-button>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
<!-- 表格 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:dataSource="list"
|
||||
:pagination="false"
|
||||
:class="list.length ? 'has-data' : ''"
|
||||
:scroll="{ y: 182 }"
|
||||
></a-table>
|
||||
<!-- 表格结束 -->
|
||||
<div class="operators">
|
||||
<div>
|
||||
<a-button type="primary">Call</a-button>
|
||||
<a-button type="primary">Save</a-button>
|
||||
</div>
|
||||
<div>
|
||||
<a-select :value="''">
|
||||
<a-select-option value="">
|
||||
Interpolation
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-button type="primary">Apply</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<!-- Equation -->
|
||||
<title-over-boarder class="mt-20" title="Equation">
|
||||
<div class="equation">
|
||||
Efficiency = 59.541 + (88.034 - 59.541) * (E - 1)/ (0.058243 - 1)
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<!-- curve -->
|
||||
<title-over-boarder class="mt-20" title="curve">
|
||||
<div class="curve">
|
||||
<custom-chart :option="option" />
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
<div class="right">
|
||||
<title-over-boarder title="Data Source" style="height: 100%">
|
||||
<div class="data-source">
|
||||
<div class="data-source-main">
|
||||
<div class="title">PHD</div>
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
<div class="footer mt-20">
|
||||
<a-button type="primary">Set to Current</a-button>
|
||||
<div class="mt-20">PHD</div>
|
||||
</div>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ModalMixin from '@/mixins/ModalMixin'
|
||||
import TitleOverBoarder from '../TitleOverBoarder.vue'
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Energy(keV)',
|
||||
dataIndex: 'energy'
|
||||
},
|
||||
{
|
||||
title: 'Efficiency',
|
||||
dataIndex: 'efficiency'
|
||||
},
|
||||
{
|
||||
title: 'Fit',
|
||||
dataIndex: 'fit'
|
||||
},
|
||||
{
|
||||
title: 'Delta(%)',
|
||||
dataIndex: 'delta'
|
||||
}
|
||||
]
|
||||
|
||||
const initialOption = {
|
||||
grid: {
|
||||
top: 20,
|
||||
right: 20,
|
||||
bottom: 50,
|
||||
left: 70
|
||||
},
|
||||
title: {
|
||||
text: 'Energy(keV)',
|
||||
textStyle: {
|
||||
color: '#8FD4F8',
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal'
|
||||
},
|
||||
right: 10,
|
||||
bottom: 0
|
||||
},
|
||||
xAxis: {
|
||||
min: 42,
|
||||
max: 2740,
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
axisLabel: {
|
||||
color: '#fff'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 'Efficiency',
|
||||
nameLocation: 'center',
|
||||
nameGap: 50,
|
||||
nameTextStyle: {
|
||||
color: '#8FD4F8',
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#EDF005'
|
||||
},
|
||||
data: [
|
||||
[42, 0],
|
||||
[100, 0.2],
|
||||
[978, 0.1]
|
||||
],
|
||||
color: 'red'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { TitleOverBoarder, CustomChart },
|
||||
mixins: [ModalMixin],
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
energy: 'energy',
|
||||
efficiency: 'efficiency',
|
||||
fit: 'fit',
|
||||
delta: 'delta'
|
||||
}
|
||||
],
|
||||
option: initialOption
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.efficiency-calibration {
|
||||
display: flex;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
|
||||
.calibration-data {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.ant-form {
|
||||
width: 25%;
|
||||
|
||||
::v-deep {
|
||||
.ant-form-item {
|
||||
margin-bottom: 15px;
|
||||
|
||||
&-label,
|
||||
&-control {
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-wrapper {
|
||||
width: 50%;
|
||||
|
||||
&.has-data {
|
||||
::v-deep {
|
||||
.ant-table-body {
|
||||
height: 182px;
|
||||
background-color: #06282a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table-placeholder {
|
||||
height: 183px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operators {
|
||||
width: 25%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.ant-select {
|
||||
width: 100%;
|
||||
}
|
||||
.ant-btn {
|
||||
width: 100%;
|
||||
|
||||
&:last-child {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.equation {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
background-color: #1b5465;
|
||||
}
|
||||
|
||||
.curve {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 20%;
|
||||
margin-left: 20px;
|
||||
|
||||
.data-source {
|
||||
.title {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: #296d81;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.content {
|
||||
height: 300px;
|
||||
background-color: #275466;
|
||||
}
|
||||
|
||||
.footer {
|
||||
.ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> div {
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: #285367;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
465
src/views/spectrumAnalysis/components/Modals/KorsumModal.vue
Normal file
465
src/views/spectrumAnalysis/components/Modals/KorsumModal.vue
Normal file
|
@ -0,0 +1,465 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" title="Korsum" :width="1120" :footer="null">
|
||||
<div class="korsum">
|
||||
<!-- 输入开始 -->
|
||||
<title-over-boarder title="Input">
|
||||
<div class="korsum-input">
|
||||
<!-- 公式部分 -->
|
||||
<a-form-model
|
||||
class="korsum-input-formula"
|
||||
:labelCol="{
|
||||
style: {
|
||||
width: '110px'
|
||||
}
|
||||
}"
|
||||
>
|
||||
<a-form-model-item label="Total Effi = exp(">
|
||||
<!-- 第一行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.totalEffi[0]"></a-input-number>
|
||||
<span class="operator">* Er + </span>
|
||||
<a-input-number v-model="formula.totalEffi[1]"></a-input-number>
|
||||
<span class="operator">+ </span>
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.totalEffi[2]"></a-input-number>
|
||||
<span class="operator">/ Er + </span>
|
||||
<a-input-number v-model="formula.totalEffi[3]"></a-input-number>
|
||||
<span class="operator">/ Er <sup>2</sup> + </span>
|
||||
</div>
|
||||
<!-- 第三行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.totalEffi[4]"></a-input-number>
|
||||
<span class="operator"> / Er <sup>3</sup> + </span>
|
||||
<a-input-number v-model="formula.totalEffi[5]"></a-input-number>
|
||||
<span class="operator">/ Er <sup>4</sup> ) </span>
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="Efficiency = exp(">
|
||||
<!-- 第一行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.efficiency[0]"></a-input-number>
|
||||
<span class="operator">* Er + </span>
|
||||
<a-input-number v-model="formula.efficiency[1]"></a-input-number>
|
||||
<span class="operator">+ </span>
|
||||
</div>
|
||||
<!-- 第二行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.efficiency[2]"></a-input-number>
|
||||
<span class="operator">/ Er + </span>
|
||||
<a-input-number v-model="formula.efficiency[3]"></a-input-number>
|
||||
<span class="operator">/ Er <sup>2</sup> + </span>
|
||||
</div>
|
||||
<!-- 第三行 -->
|
||||
<div>
|
||||
<a-input-number v-model="formula.efficiency[4]"></a-input-number>
|
||||
<span class="operator"> / Er <sup>3</sup> + </span>
|
||||
<a-input-number v-model="formula.efficiency[5]"></a-input-number>
|
||||
<span class="operator">/ Er <sup>4</sup> ) </span>
|
||||
</div>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
<!-- 公式结束 -->
|
||||
|
||||
<!-- 标题 -->
|
||||
<p class="korsum-input-title">
|
||||
Input
|
||||
</p>
|
||||
<!-- 标题结束 -->
|
||||
|
||||
<!-- 表格开始 -->
|
||||
<a-table
|
||||
class="korsum-input-table"
|
||||
:class="list.length ? 'has-data' : ''"
|
||||
:columns="columns"
|
||||
:dataSource="list"
|
||||
:scroll="{ y: 288 }"
|
||||
:pagination="false"
|
||||
>
|
||||
<template slot="energy" slot-scope="text, record">
|
||||
<a-input-number v-model="record.energy"></a-input-number>
|
||||
</template>
|
||||
<template slot="totalEfficiency" slot-scope="text, record">
|
||||
<a-input-number v-model="record.totalEfficiency"></a-input-number>
|
||||
</template>
|
||||
<template slot="peakEfficiency" slot-scope="text, record">
|
||||
<a-input-number v-model="record.peakEfficiency"></a-input-number>
|
||||
</template>
|
||||
<template slot="uncertainty" slot-scope="text, record">
|
||||
<a-input-number v-model="record.uncertainty"></a-input-number>
|
||||
</template>
|
||||
</a-table>
|
||||
<!-- 表格结束 -->
|
||||
|
||||
<!-- 按钮开始 -->
|
||||
<div class="korsum-input-buttons">
|
||||
<a-button type="primary" @click="handleAnalyze">Analyse</a-button>
|
||||
<a-button type="primary" @click="handleExit">Exit</a-button>
|
||||
</div>
|
||||
<!-- 按钮结束 -->
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<!-- 输入结束 -->
|
||||
|
||||
<!-- 输出开始 -->
|
||||
<title-over-boarder title="Output">
|
||||
<div class="korsum-output">
|
||||
<div class="korsum-output-main">
|
||||
<div class="korsum-output-list">
|
||||
<div
|
||||
class="korsum-output-list-item"
|
||||
:class="selectedItem == item ? 'active' : ''"
|
||||
v-for="(item, index) in outputList"
|
||||
:key="index"
|
||||
@click="handleOutputItemClick(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
<a-table
|
||||
class="korsum-output-table"
|
||||
:columns="outputColumns"
|
||||
:dataSource="outputTableList"
|
||||
:class="outputTableList.length ? 'has-data' : ''"
|
||||
:scroll="{ y: 584 }"
|
||||
:pagination="false"
|
||||
></a-table>
|
||||
</div>
|
||||
|
||||
<div class="korsum-output-operation">
|
||||
<div class="left">
|
||||
<a-input v-model="filterWord"></a-input>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a-button type="primary" @click="handleExport">Export to Excel</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<!-- 输出结束 -->
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TitleOverBoarder from '../TitleOverBoarder.vue'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Energy',
|
||||
dataIndex: 'energy',
|
||||
scopedSlots: {
|
||||
customRender: 'energy'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Total Efficiency',
|
||||
dataIndex: 'totalEfficiency',
|
||||
scopedSlots: {
|
||||
customRender: 'totalEfficiency'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Peak Efficiency',
|
||||
dataIndex: 'peakEfficiency',
|
||||
scopedSlots: {
|
||||
customRender: 'peakEfficiency'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Uncertainty(%)',
|
||||
dataIndex: 'uncertainty',
|
||||
scopedSlots: {
|
||||
customRender: 'uncertainty'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const outputColumns = [
|
||||
{
|
||||
title: 'Energy',
|
||||
dataIndex: 'energy'
|
||||
},
|
||||
{
|
||||
title: 'Correct Factor',
|
||||
dataIndex: 'correctFactor'
|
||||
},
|
||||
{
|
||||
title: 'Uncertainty(%)',
|
||||
dataIndex: 'uncertainty'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
components: { TitleOverBoarder },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
this.outputColumns = outputColumns
|
||||
return {
|
||||
formula: {
|
||||
totalEffi: [0, 0, 0, 0, 0, 0],
|
||||
efficiency: [0, 0, 0, 0, 0, 0]
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: 1,
|
||||
energy: 10,
|
||||
totalEfficiency: 0.005,
|
||||
peakEfficiency: 0.002,
|
||||
uncertainty: 10.0
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
energy: 10,
|
||||
totalEfficiency: 0.005,
|
||||
peakEfficiency: 0.002,
|
||||
uncertainty: 10.0
|
||||
}
|
||||
],
|
||||
selectedItem: {}, // output中左侧选中的项
|
||||
outputTableList: [], // output中表格列表数据
|
||||
|
||||
filterWord: '' // 筛选
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 分析
|
||||
handleAnalyze() {
|
||||
console.log('%c [ 分析 ]-178', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 退出
|
||||
handleExit() {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// output栏点击左侧列表
|
||||
handleOutputItemClick(item) {
|
||||
this.selectedItem = item
|
||||
this.outputTableList = item.list
|
||||
},
|
||||
|
||||
// 导出到excel
|
||||
handleExport() {
|
||||
console.log('%c [ 导出到excel ]-246', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
},
|
||||
outputList() {
|
||||
const list = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'SN-125',
|
||||
list: [
|
||||
{
|
||||
id: 12,
|
||||
energy: 'energy',
|
||||
correctFactor: 'correctFactor',
|
||||
uncertainty: 'uncertainty'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'EU-157',
|
||||
list: [
|
||||
{
|
||||
id: 12,
|
||||
energy: 'energy',
|
||||
correctFactor: 'correctFactor',
|
||||
uncertainty: 'uncertainty'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
return list.filter(item => item.title.toLowerCase().includes(this.filterWord.toLowerCase()))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
::v-deep {
|
||||
.title-over-border-content {
|
||||
height: 711px;
|
||||
}
|
||||
}
|
||||
|
||||
.korsum {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.title-over-border {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-input {
|
||||
&-formula {
|
||||
::v-deep {
|
||||
.ant-form-item {
|
||||
margin-bottom: 10px;
|
||||
|
||||
&-label {
|
||||
::after {
|
||||
content: ' ';
|
||||
margin: 0 2px;
|
||||
}
|
||||
> label {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-number {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.operator {
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
background-color: @primary-color;
|
||||
}
|
||||
|
||||
&-table {
|
||||
&.has-data {
|
||||
::v-deep {
|
||||
.ant-table-body {
|
||||
height: 288px;
|
||||
background-color: #06282a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ant-table-placeholder {
|
||||
height: 289px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-number {
|
||||
height: 26px;
|
||||
|
||||
::v-deep {
|
||||
.ant-input-number-input {
|
||||
height: 26px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.ant-btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-output {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-main {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-list {
|
||||
width: 120px;
|
||||
height: 619px;
|
||||
background: #275466;
|
||||
padding: 5px;
|
||||
overflow: auto;
|
||||
|
||||
&-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
background-color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-table {
|
||||
flex: 1;
|
||||
&.has-data {
|
||||
::v-deep {
|
||||
.ant-table-body {
|
||||
height: 584px;
|
||||
background-color: #06282a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ant-table-placeholder {
|
||||
height: 585px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-operation {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.left {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.right {
|
||||
flex: 1;
|
||||
|
||||
.ant-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
448
src/views/spectrumAnalysis/components/Modals/LoadFromDBModal.vue
Normal file
448
src/views/spectrumAnalysis/components/Modals/LoadFromDBModal.vue
Normal file
|
@ -0,0 +1,448 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="1280" title="Load From Database" class="load-from-db-modal">
|
||||
<search-form ref="searchFormRef" :items="formItems" v-model="queryParam">
|
||||
<a-space slot="additional">
|
||||
<a-button @click="handleReset">Reset</a-button>
|
||||
<a-button type="primary" @click="searchQuery">Search</a-button>
|
||||
</a-space>
|
||||
</search-form>
|
||||
<custom-table
|
||||
size="middle"
|
||||
rowKey="sampleId"
|
||||
:columns="columns"
|
||||
:list="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
:selectedRowKeys.sync="selectedRowKeys"
|
||||
:selectionRows.sync="selectionRows"
|
||||
:multiple="true"
|
||||
>
|
||||
</custom-table>
|
||||
<!-- 底部操作栏 -->
|
||||
<template slot="custom-footer">
|
||||
<a-space>
|
||||
<a-radio-group v-model="queryParam.dbName">
|
||||
<a-radio value="auto">From Auto DB</a-radio>
|
||||
<a-radio value="man">From Interactive DB</a-radio>
|
||||
</a-radio-group>
|
||||
<a-button type="primary" @click="handleLoad">Load</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
|
||||
import { getAction } from '../../../../api/manage'
|
||||
import moment from 'moment'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'SampleID',
|
||||
align: 'left',
|
||||
dataIndex: 'sampleId'
|
||||
},
|
||||
{
|
||||
title: 'Station',
|
||||
align: 'left',
|
||||
dataIndex: 'stationName'
|
||||
},
|
||||
{
|
||||
title: 'Detector',
|
||||
align: 'left',
|
||||
dataIndex: 'detectorsName'
|
||||
},
|
||||
{
|
||||
title: 'Sample',
|
||||
align: 'left',
|
||||
dataIndex: 'sampleType'
|
||||
},
|
||||
{
|
||||
title: 'DataType',
|
||||
align: 'left',
|
||||
dataIndex: 'dataType'
|
||||
},
|
||||
{
|
||||
title: 'Qualifier',
|
||||
align: 'left',
|
||||
dataIndex: 'spectralQualifie'
|
||||
},
|
||||
{
|
||||
title: 'Col.Stop',
|
||||
align: 'left',
|
||||
dataIndex: 'collectStop'
|
||||
},
|
||||
{
|
||||
title: 'Acq.Start',
|
||||
align: 'left',
|
||||
dataIndex: 'acquisitionStart'
|
||||
},
|
||||
{
|
||||
title: 'Acq.real',
|
||||
align: 'left',
|
||||
dataIndex: 'acquisitionRealSec'
|
||||
},
|
||||
{
|
||||
title: 'Acq.live',
|
||||
align: 'left',
|
||||
dataIndex: 'acquisitionLiveSec'
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
align: 'left',
|
||||
dataIndex: 'status'
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
mixins: [JeecgListMixin],
|
||||
data() {
|
||||
this.columns = columns
|
||||
this.disableMixinCreated = true
|
||||
return {
|
||||
queryParam: {
|
||||
menuTypes: undefined,
|
||||
startDate: moment()
|
||||
.add(-7, 'd')
|
||||
.format('YYYY-MM-DD'),
|
||||
endDate: moment().format('YYYY-MM-DD'),
|
||||
dbName: 'auto'
|
||||
},
|
||||
selectedRowKeys: [],
|
||||
selectionRows: [],
|
||||
|
||||
stationList: [],
|
||||
detectorList: [],
|
||||
url: {
|
||||
list: '/spectrumAnalysis/getDBSpectrumList'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadData(arg) {
|
||||
const params = this.getQueryParams() //查询条件
|
||||
const { startDate, endDate, menuTypes } = params
|
||||
if (!menuTypes) {
|
||||
this.$message.warn('Please Select SampleType First')
|
||||
return
|
||||
}
|
||||
|
||||
if(!startDate || !endDate) {
|
||||
this.$message.warn(`'From' Date And 'To' Date Cannot Be Null`)
|
||||
return
|
||||
}
|
||||
|
||||
if(moment(startDate).isAfter(moment(endDate))) {
|
||||
this.$message.warn(`'From' Date Cannot Be Late Than 'To' Date`)
|
||||
return
|
||||
}
|
||||
|
||||
//加载数据 若传入参数1则加载第一页的内容
|
||||
if (arg === 1) {
|
||||
this.ipagination.current = 1
|
||||
}
|
||||
|
||||
if (params.checkboxGroup) {
|
||||
params.checkboxGroup.forEach(item => {
|
||||
params[item] = true
|
||||
})
|
||||
delete params.checkboxGroup
|
||||
}
|
||||
|
||||
this.onClearSelected()
|
||||
|
||||
this.loading = true
|
||||
getAction(this.url.list, params)
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
this.dataSource = res.result.records || res.result
|
||||
if (res.result.total) {
|
||||
this.ipagination.total = res.result.total
|
||||
} else {
|
||||
this.ipagination.total = 0
|
||||
}
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载
|
||||
*/
|
||||
async handleLoad() {
|
||||
if (!this.selectedRowKeys.length) {
|
||||
this.$message.warn('Please Select Databases To Load')
|
||||
return
|
||||
}
|
||||
this.selectedRowKeys = []
|
||||
this.visible = false
|
||||
this.$emit('loadSample', this.selectionRows)
|
||||
},
|
||||
|
||||
// 获取台站和探测器列表
|
||||
async getStationAndDetectorList(value) {
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const { success, result, message } = await getAction('/spectrumAnalysis/getDBSearchList', {
|
||||
menuTypes: value
|
||||
})
|
||||
if (success) {
|
||||
this.stationList = result.stationCode.map(item => ({ label: item, value: item }))
|
||||
this.detectorList = result.detectorCode.map(item => ({ label: item, value: item }))
|
||||
} else {
|
||||
this.$message.error(message)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
},
|
||||
|
||||
// 重置搜索栏
|
||||
handleReset() {
|
||||
this.$refs.searchFormRef.$refs.form.resetFields()
|
||||
},
|
||||
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
},
|
||||
formItems() {
|
||||
return [
|
||||
{
|
||||
label: 'SampleType',
|
||||
type: 'custom-select',
|
||||
name: 'menuTypes',
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
label: 'All',
|
||||
value: 'G,B'
|
||||
},
|
||||
{
|
||||
label: 'Gamma',
|
||||
value: 'G'
|
||||
},
|
||||
{
|
||||
label: 'Beta',
|
||||
value: 'B'
|
||||
}
|
||||
],
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '18%'
|
||||
},
|
||||
on: {
|
||||
change: event => {
|
||||
this.getStationAndDetectorList(event)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Station',
|
||||
type: 'custom-select',
|
||||
name: 'stationName',
|
||||
props: {
|
||||
options: this.stationList,
|
||||
showSearch: true,
|
||||
filterOption: this.filterOption,
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '19%'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Detector',
|
||||
type: 'custom-select',
|
||||
name: 'detectorsName',
|
||||
props: {
|
||||
options: this.detectorList,
|
||||
showSearch: true,
|
||||
filterOption: this.filterOption,
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '19%'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Sample',
|
||||
type: 'custom-select',
|
||||
name: 'sampleType',
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
label: 'P',
|
||||
value: 'P'
|
||||
},
|
||||
{
|
||||
label: 'B',
|
||||
value: 'B'
|
||||
},
|
||||
{
|
||||
label: 'G',
|
||||
value: 'G'
|
||||
}
|
||||
],
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '14%'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'DataType',
|
||||
type: 'custom-select',
|
||||
name: 'dataType',
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
label: 'S',
|
||||
value: 'S'
|
||||
},
|
||||
{
|
||||
label: 'G',
|
||||
value: 'G'
|
||||
},
|
||||
{
|
||||
label: 'D',
|
||||
value: 'D'
|
||||
},
|
||||
{
|
||||
label: 'Q',
|
||||
value: 'Q'
|
||||
},
|
||||
{
|
||||
label: 'B',
|
||||
value: 'B'
|
||||
},
|
||||
{
|
||||
label: 'C',
|
||||
value: 'C'
|
||||
}
|
||||
],
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '14%'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Qualifier',
|
||||
type: 'custom-select',
|
||||
name: 'spectralQualifie',
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
label: 'FULL',
|
||||
value: 'FULL'
|
||||
},
|
||||
{
|
||||
label: 'PREL',
|
||||
value: 'PREL'
|
||||
}
|
||||
],
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '16%',
|
||||
paddingRight: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'SampleID',
|
||||
type: 'a-input',
|
||||
name: 'sampleId',
|
||||
props: {
|
||||
allowClear: true
|
||||
},
|
||||
style: {
|
||||
width: '264px'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
type: 'a-checkbox-group',
|
||||
name: 'checkboxGroup',
|
||||
props: {
|
||||
options: [
|
||||
{ label: 'All User', value: 'allUser' },
|
||||
{ label: 'Collect Stop', value: 'CollectStop' },
|
||||
{ label: 'Acq.Start', value: 'AcqStart' }
|
||||
]
|
||||
},
|
||||
style: {
|
||||
width: '305px',
|
||||
paddingRight: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'From',
|
||||
type: 'custom-date-picker',
|
||||
name: 'startDate',
|
||||
props: {
|
||||
format: 'YYYY-MM-DD',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
style: {
|
||||
minWidth: 'auto'
|
||||
}
|
||||
},
|
||||
style: {
|
||||
width: '19%'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'To',
|
||||
type: 'custom-date-picker',
|
||||
name: 'endDate',
|
||||
props: {
|
||||
format: 'YYYY-MM-DD',
|
||||
valueFormat: 'YYYY-MM-DD',
|
||||
style: {
|
||||
minWidth: 'auto'
|
||||
}
|
||||
},
|
||||
style: {
|
||||
paddingRight: 0,
|
||||
marginRight: '22px',
|
||||
width: '19%'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.load-from-db-modal {
|
||||
::v-deep {
|
||||
.search-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,172 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="1200" title="Load Data From File">
|
||||
<a-table :data-source="list" :columns="columns" :pagination="false" bordered>
|
||||
<template slot="sampleData" slot-scope="text, record">
|
||||
<phd-select type="file" @change="handleFileChange(record, 'sampleData', $event)" :title="text && text.name">
|
||||
{{ text && text.name }}
|
||||
</phd-select>
|
||||
</template>
|
||||
<template slot="gasBkData" slot-scope="text, record">
|
||||
<phd-select type="file" @change="handleFileChange(record, 'gasBkData', $event)" :title="text && text.name">
|
||||
{{ text && text.name }}
|
||||
</phd-select>
|
||||
</template>
|
||||
<template slot="detBkData" slot-scope="text, record">
|
||||
<phd-select type="file" @change="handleFileChange(record, 'detBkData', $event)" :title="text && text.name">
|
||||
{{ text && text.name }}
|
||||
</phd-select>
|
||||
</template>
|
||||
<template slot="qcData" slot-scope="text, record">
|
||||
<phd-select type="file" @change="handleFileChange(record, 'qcData', $event)" :title="text && text.name">
|
||||
{{ text && text.name }}
|
||||
</phd-select>
|
||||
</template>
|
||||
<template slot="status" slot-scope="text">
|
||||
<span class="status"></span>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<template slot="custom-footer">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleReset">Reset</a-button>
|
||||
<a-button type="primary" @click="handleLoad">Load</a-button>
|
||||
<a-button type="primary" @click="handleCancel">Cancel</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
<!-- 底部按钮结束 -->
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PhdSelect from '../PHDSelect.vue'
|
||||
const columns = [
|
||||
{
|
||||
title: 'SampleData',
|
||||
dataIndex: 'sampleData',
|
||||
width: '23%',
|
||||
ellipsis: true,
|
||||
scopedSlots: {
|
||||
customRender: 'sampleData'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'GasBkData',
|
||||
dataIndex: 'gasBkData',
|
||||
width: '23%',
|
||||
ellipsis: true,
|
||||
scopedSlots: {
|
||||
customRender: 'gasBkData'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'DetBkData',
|
||||
dataIndex: 'detBkData',
|
||||
width: '23%',
|
||||
ellipsis: true,
|
||||
scopedSlots: {
|
||||
customRender: 'detBkData'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'QCData',
|
||||
dataIndex: 'qcData',
|
||||
width: '23%',
|
||||
ellipsis: true,
|
||||
scopedSlots: {
|
||||
customRender: 'qcData'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
align: 'center',
|
||||
scopedSlots: {
|
||||
customRender: 'status'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
components: { PhdSelect },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
list: this.getInitialList()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 初始化为10*4的表格
|
||||
getInitialList() {
|
||||
return new Array(10).fill(0).map(() => ({
|
||||
sampleData: undefined,
|
||||
gasBkData: undefined,
|
||||
detBkData: undefined,
|
||||
qcData: undefined
|
||||
}))
|
||||
},
|
||||
|
||||
handleFileChange(record, key, fileInfo) {
|
||||
record[key] = fileInfo
|
||||
},
|
||||
|
||||
handleReset() {
|
||||
this.list = this.getInitialList()
|
||||
},
|
||||
|
||||
handleLoad() {
|
||||
console.log('%c [ handleLoad ]-123', 'font-size:13px; background:pink; color:#bf2c9f;', this.list)
|
||||
},
|
||||
|
||||
handleCancel() {
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.status {
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
margin-top: 8px;
|
||||
|
||||
background-color: #00e170;
|
||||
}
|
||||
::v-deep {
|
||||
@tableBorderColor: #000;
|
||||
|
||||
.ant-table-bordered .ant-table-thead > tr > th,
|
||||
.ant-table-bordered .ant-table-tbody > tr > td {
|
||||
border-right-color: @tableBorderColor;
|
||||
}
|
||||
.ant-table-thead > tr th {
|
||||
border-bottom: 1px solid @tableBorderColor;
|
||||
}
|
||||
|
||||
.ant-table-bordered .ant-table-body > table {
|
||||
border-color: @tableBorderColor;
|
||||
}
|
||||
|
||||
.ant-table-tbody tr td {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,239 @@
|
|||
<template>
|
||||
<custom-modal
|
||||
v-model="visible"
|
||||
:width="1231"
|
||||
title="Nuclide Activity and MDC"
|
||||
class="nuclide-activity-and-mdc-modal"
|
||||
:footer="null"
|
||||
>
|
||||
<!-- 顶部搜索栏 -->
|
||||
<a-form-model class="search-form">
|
||||
<div class="time-pickers">
|
||||
<a-form-model-item label="Activity reference time">
|
||||
<custom-date-picker show-time v-model="queryParam.activityReferenceTime" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="Concentration reference time">
|
||||
<custom-date-picker show-time v-model="queryParam.concentrationReferenceTime" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
<a-space class="operators" :size="20">
|
||||
<a-button :type="compareVisible ? 'grey' : 'primary'" @click="handleComparision">
|
||||
<img src="@/assets/images/spectrum/comparation.png" />
|
||||
{{ compareVisible ? 'Cancel comparison' : 'Comparison' }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleExportToExcel">
|
||||
<img src="@/assets/images/spectrum/download.png" />
|
||||
Export to Excel
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-model>
|
||||
<!-- 顶部搜索栏结束 -->
|
||||
<!-- 主体部分 -->
|
||||
<div v-if="compareVisible" class="comparison-list">
|
||||
<div class="comparison-list-item" v-for="(item, index) in compareList" :key="index">
|
||||
<div class="comparison-list-item-title">{{ item.title }}</div>
|
||||
<custom-table :list="item.list" :columns="columns"></custom-table>
|
||||
</div>
|
||||
</div>
|
||||
<custom-table v-else :list="list" :columns="columns"></custom-table>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const columns = [
|
||||
{
|
||||
title: 'Nuclide',
|
||||
dataIndex: 'nuclide'
|
||||
},
|
||||
{
|
||||
title: 'HalfLife',
|
||||
dataIndex: 'halfLife'
|
||||
},
|
||||
{
|
||||
title: 'Energy (keV)',
|
||||
dataIndex: 'energy'
|
||||
},
|
||||
{
|
||||
title: 'Yield (%)',
|
||||
dataIndex: 'yield'
|
||||
},
|
||||
{
|
||||
title: 'Efficiency',
|
||||
dataIndex: 'efficiency'
|
||||
},
|
||||
{
|
||||
title: 'Activity (Bq)',
|
||||
dataIndex: 'activity'
|
||||
},
|
||||
{
|
||||
title: 'Act Err (%)',
|
||||
dataIndex: 'actErr'
|
||||
},
|
||||
{
|
||||
title: 'MDA (Bq)',
|
||||
dataIndex: 'mda'
|
||||
},
|
||||
{
|
||||
title: 'Conc (uBq/m3)',
|
||||
dataIndex: 'conc'
|
||||
},
|
||||
{
|
||||
title: 'MDC (uBq/m3)',
|
||||
dataIndex: 'mdc'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
queryParam: {
|
||||
activityReferenceTime: undefined,
|
||||
concentrationReferenceTime: undefined
|
||||
},
|
||||
compareVisible: false,
|
||||
|
||||
list: [
|
||||
{
|
||||
nuclide: 'nuclide',
|
||||
halfLife: 'halfLife',
|
||||
energy: 'energy',
|
||||
yield: 'yield',
|
||||
efficiency: 'efficiency',
|
||||
activity: 'activity',
|
||||
actErr: 'actErr',
|
||||
mda: 'mda',
|
||||
conc: 'conc',
|
||||
mdc: 'mdc'
|
||||
}
|
||||
],
|
||||
|
||||
compareList: [
|
||||
{
|
||||
title: 'ARMD',
|
||||
list: [
|
||||
{
|
||||
nuclide: 'nuclide',
|
||||
halfLife: 'halfLife',
|
||||
energy: 'energy',
|
||||
yield: 'yield',
|
||||
efficiency: 'efficiency',
|
||||
activity: 'activity',
|
||||
actErr: 'actErr',
|
||||
mda: 'mda',
|
||||
conc: 'conc',
|
||||
mdc: 'mdc'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'IDC',
|
||||
list: [
|
||||
{
|
||||
nuclide: 'nuclide',
|
||||
halfLife: 'halfLife',
|
||||
energy: 'energy',
|
||||
yield: 'yield',
|
||||
efficiency: 'efficiency',
|
||||
activity: 'activity',
|
||||
actErr: 'actErr',
|
||||
mda: 'mda',
|
||||
conc: 'conc',
|
||||
mdc: 'mdc'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换比较
|
||||
handleComparision() {
|
||||
this.compareVisible = !this.compareVisible
|
||||
},
|
||||
|
||||
// 导出到Excel
|
||||
handleExportToExcel() {}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nuclide-activity-and-mdc-modal {
|
||||
::v-deep {
|
||||
.ant-modal-body {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-form {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.time-pickers {
|
||||
display: flex;
|
||||
.ant-form-item {
|
||||
margin-bottom: 0;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-form-item {
|
||||
&-label {
|
||||
> label {
|
||||
color: #ade6ee;
|
||||
}
|
||||
}
|
||||
|
||||
&-control-wrapper {
|
||||
width: 210px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.operators {
|
||||
.ant-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comparison-list {
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid rgba(13, 109, 118, 0.5);
|
||||
|
||||
&-item {
|
||||
&-title {
|
||||
color: #0cebc9;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<span class="status" :style="{ background: currStatus.color }">{{ currStatus.title }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const statusList = {
|
||||
0: {
|
||||
title: 'Done',
|
||||
color: '#008000'
|
||||
},
|
||||
1: {
|
||||
title: '==>',
|
||||
color: '#FFAA00'
|
||||
},
|
||||
2: {
|
||||
title: 'Pending',
|
||||
color: '#FF0000'
|
||||
}
|
||||
}
|
||||
export default {
|
||||
props: {
|
||||
status: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currStatus() {
|
||||
return statusList[this.status]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.status {
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" :width="400" title="Processing Monitor" :footer="null">
|
||||
<div class="processing">
|
||||
<div>
|
||||
<!-- 标题 -->
|
||||
<div class="processing-title">Calibration Updates</div>
|
||||
<!-- 列表 -->
|
||||
<div class="processing-list">
|
||||
<div class="processing-list-item">
|
||||
<status :status="0" />
|
||||
<div class="description">Energy - Mariscotti Centroids</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="0" />
|
||||
<div class="description">Resolution</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="0" />
|
||||
<div class="description">Energy - Fitted Centroids</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 20px;">
|
||||
<!-- 标题 -->
|
||||
<div class="processing-title">Spectrum Analysis</div>
|
||||
<!-- 列表 -->
|
||||
<div class="processing-list">
|
||||
<div class="processing-list-item">
|
||||
<status :status="0" />
|
||||
<div class="description">Peak Search</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="0" />
|
||||
<div class="description">Baseline Fitting</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="1" />
|
||||
<div class="description">Net Area Fitting</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="2" />
|
||||
<div class="description">Nuclide Identification</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="2" />
|
||||
<div class="description">Activity and MDA</div>
|
||||
</div>
|
||||
<div class="processing-list-item">
|
||||
<status :status="2" />
|
||||
<div class="description">QC Test</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Status from './components/status.vue'
|
||||
export default {
|
||||
components: {
|
||||
Status
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@color: #325050;
|
||||
.processing {
|
||||
&-title {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background-color: @color;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-list {
|
||||
&-item {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
|
||||
.description {
|
||||
flex: 1;
|
||||
background-color: @color;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,81 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" title="Save Setting" :width="380" :okHandler="handleOk">
|
||||
<div class="save-setting">
|
||||
<div class="save-setting-all">
|
||||
<a-checkbox v-model="saveAll">
|
||||
Save All
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<title-over-boarder title="Format">
|
||||
<a-radio-group v-model="saveFormat" class="format-radio-group">
|
||||
<a-radio value="txt">Save as Txt</a-radio>
|
||||
<a-radio value="excel">Save as Excel</a-radio>
|
||||
</a-radio-group>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { downloadFile } from '../../../../api/manage'
|
||||
import TitleOverBoarder from '../TitleOverBoarder.vue'
|
||||
export default {
|
||||
components: { TitleOverBoarder },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
saveAll: false,
|
||||
saveFormat: 'txt'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reset() {
|
||||
this.saveAll = false
|
||||
this.saveFormat = 'txt'
|
||||
},
|
||||
|
||||
handleOk() {
|
||||
console.log('%c [ save ]-22', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
downloadFile('', 'result.' + this.saveFormat, {})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
get() {
|
||||
if (this.value) {
|
||||
this.reset()
|
||||
}
|
||||
|
||||
return this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.save-setting {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&-all {
|
||||
width: 65%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.format-radio-group {
|
||||
.ant-radio-wrapper:first-child {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
250
src/views/spectrumAnalysis/components/Modals/ZeroTimeModal.vue
Normal file
250
src/views/spectrumAnalysis/components/Modals/ZeroTimeModal.vue
Normal file
|
@ -0,0 +1,250 @@
|
|||
<template>
|
||||
<custom-modal v-model="visible" title="Zero Time" :width="940" :footer="null">
|
||||
<div class="zero-time">
|
||||
<!-- 左侧 -->
|
||||
<div class="zero-time-left">
|
||||
<title-over-boarder title="Fission Product Infomation">
|
||||
<div class="fission-product">
|
||||
<div class="fission-product-container">
|
||||
<div class="fission-product-title">
|
||||
Fission Product 1
|
||||
</div>
|
||||
<div class="fission-product-list">
|
||||
<div class="fission-product-list-item" v-for="(item, index) in fissionProductList1" :key="index">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fission-product-container">
|
||||
<div class="fission-product-title">
|
||||
Fission Product 2
|
||||
</div>
|
||||
<div class="fission-product-list">
|
||||
<div class="fission-product-list-item" v-for="(item, index) in fissionProductList2" :key="index">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<!-- Result of Zero Time -->
|
||||
<title-over-boarder class="mt-20" title="Result of Zero Time">
|
||||
<div class="result-of-zero-time">2015-05-30 17:30:60</div>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
<!-- 左侧结束 -->
|
||||
|
||||
<!-- 右侧 -->
|
||||
<div class="zero-time-right">
|
||||
<!-- Active of Fission Product -->
|
||||
<title-over-boarder title="Active of Fission Product">
|
||||
<div class="active-of-fission-product">
|
||||
<div class="item">
|
||||
<div class="title">
|
||||
Fission Product 1
|
||||
</div>
|
||||
<div>
|
||||
<a-input></a-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="operator">
|
||||
-----Bq-----
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="title">
|
||||
Fission Product 2
|
||||
</div>
|
||||
<div>
|
||||
<a-input></a-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</title-over-boarder>
|
||||
<div class="zero-time-right-center mt-20">
|
||||
<!-- Fission Target -->
|
||||
<title-over-boarder class="fission-target" title="Fission Target">
|
||||
<a-radio-group>
|
||||
<a-radio>U-235</a-radio>
|
||||
<a-radio>U-238</a-radio>
|
||||
<a-radio>PU-239</a-radio>
|
||||
</a-radio-group>
|
||||
</title-over-boarder>
|
||||
<title-over-boarder class="fission-energy" title="Energy of Fission Neutron">
|
||||
<a-radio-group>
|
||||
<a-radio>T>Thermal_spectrum</a-radio>
|
||||
<a-radio>F>Fission_spectrum</a-radio>
|
||||
<a-radio>H->Fast_Neutron</a-radio>
|
||||
</a-radio-group>
|
||||
</title-over-boarder>
|
||||
</div>
|
||||
<title-over-boarder class="mt-20" title="Reference Time">
|
||||
<a-form-model layout="inline">
|
||||
<a-form-model-item label="Date">
|
||||
<custom-date-picker />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="Time">
|
||||
<a-time-picker></a-time-picker>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</title-over-boarder>
|
||||
|
||||
<div class="zero-time-right-buttons mt-20">
|
||||
<a-button type="primary">Analysis</a-button>
|
||||
<a-button type="primary">Save</a-button>
|
||||
<a-button type="primary">Exit</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧结束 -->
|
||||
</div>
|
||||
</custom-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TitleOverBoarder from '../TitleOverBoarder.vue'
|
||||
|
||||
export default {
|
||||
components: { TitleOverBoarder },
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fissionProductList1: [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Ba140'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Ce141'
|
||||
}
|
||||
],
|
||||
fissionProductList2: [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Ba140'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
get() {
|
||||
return this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.zero-time {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
|
||||
&-left {
|
||||
width: 40%;
|
||||
|
||||
.fission-product {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
|
||||
&-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&-title {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
font-size: 16px;
|
||||
background-color: #497e9d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-list {
|
||||
margin-top: 5px;
|
||||
height: 255px;
|
||||
overflow: auto;
|
||||
padding: 0 10px;
|
||||
background-color: #275466;
|
||||
|
||||
&-item {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-of-zero-time {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
background-color: #00ff7f;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
// 右侧开始
|
||||
&-right {
|
||||
flex: 1;
|
||||
|
||||
.active-of-fission-product {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
padding: 0 60px;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.operator {
|
||||
margin: 5px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&-center {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
.fission-target {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.fission-energy {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.ant-radio-wrapper {
|
||||
display: block;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.ant-btn {
|
||||
padding: 0 45px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
64
src/views/spectrumAnalysis/components/MultiLevelMenu.vue
Normal file
64
src/views/spectrumAnalysis/components/MultiLevelMenu.vue
Normal file
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<a-menu mode="vertical" :style="{ width }" class="multi-level-menu">
|
||||
<template v-for="(item, index) in children">
|
||||
<a-menu-item :key="index" v-bind="item.attrs" @click="handleMenuClick(item)">
|
||||
{{ item.title }}
|
||||
<div v-if="item.children" :key="index">
|
||||
<a-menu class="multi-level-menu-sub-menu">
|
||||
<a-menu-item v-for="child in item.children" :key="child.key" @click="handleSubMenuClick(item, child)">
|
||||
{{ child.title }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
</a-menu-item>
|
||||
</template>
|
||||
</a-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
children: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: 'auto'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleMenuClick(item) {
|
||||
if (!item.children) {
|
||||
this.$emit('menuClick', item)
|
||||
}
|
||||
},
|
||||
handleSubMenuClick(item, child) {
|
||||
this.$emit('submenuClick', { item, child })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.multi-level-menu {
|
||||
.ant-menu-item {
|
||||
overflow: visible;
|
||||
|
||||
.multi-level-menu-sub-menu {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
transform: translateX(100%);
|
||||
display: none;
|
||||
background: #03353f;
|
||||
}
|
||||
|
||||
&-active {
|
||||
.multi-level-menu-sub-menu {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
39
src/views/spectrumAnalysis/components/PHDSelect.vue
Normal file
39
src/views/spectrumAnalysis/components/PHDSelect.vue
Normal file
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<label class="file-select">
|
||||
<input type="file" @change="handleFileChange" accept=".phd, .PHD" />
|
||||
<div class="file-name">
|
||||
<slot />
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleFileChange(e) {
|
||||
const file = e.target.files[0]
|
||||
if (file) {
|
||||
this.$emit('change', file)
|
||||
}
|
||||
e.target.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.file-select {
|
||||
display: block;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
.file-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
360
src/views/spectrumAnalysis/components/PeakInfomation.vue
Normal file
360
src/views/spectrumAnalysis/components/PeakInfomation.vue
Normal file
|
@ -0,0 +1,360 @@
|
|||
<template>
|
||||
<a-modal v-model="visible" title="Peak Infomation" :width="1231" :footer="null" class="peak-infomation">
|
||||
<div v-if="compareVisible" class="comparison-list">
|
||||
<div class="comparison-list-item" v-for="(item, index) in compareList" :key="index">
|
||||
<div class="comparison-list-item-title">{{ item.title }}</div>
|
||||
<custom-table :list="item.list" :scroll="{ y: 230 }" :columns="columns"></custom-table>
|
||||
</div>
|
||||
</div>
|
||||
<custom-table v-else :columns="columns" :list="list"></custom-table>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="peak-infomation-footer">
|
||||
<a-space :size="20">
|
||||
<a-button :type="compareVisible ? 'grey' : 'primary'" @click="handleComparision">
|
||||
<img src="@/assets/images/spectrum/comparation.png" />
|
||||
{{ compareVisible ? 'Cancel comparison' : 'Comparison' }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleExportToExcel">
|
||||
<img src="@/assets/images/spectrum/download.png" />
|
||||
Export to Excel
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const columns = [
|
||||
{
|
||||
title: 'Index',
|
||||
dataIndex: 'index',
|
||||
align: 'center',
|
||||
customRender: (_, __, index) => {
|
||||
return index + 1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Energy(keV)',
|
||||
dataIndex: 'energy'
|
||||
},
|
||||
{
|
||||
title: 'Centroid',
|
||||
dataIndex: 'centroid'
|
||||
},
|
||||
{
|
||||
title: 'Multiplet',
|
||||
dataIndex: 'multiplet'
|
||||
},
|
||||
{
|
||||
title: 'Fwhm(keV)',
|
||||
dataIndex: 'fwhm'
|
||||
},
|
||||
{
|
||||
title: 'NetArea',
|
||||
dataIndex: 'netArea'
|
||||
},
|
||||
{
|
||||
title: 'AreaErr(%)',
|
||||
dataIndex: 'areaErr'
|
||||
},
|
||||
{
|
||||
title: 'Significant',
|
||||
dataIndex: 'significant'
|
||||
},
|
||||
{
|
||||
title: 'Sensitivity',
|
||||
dataIndex: 'sensitivity'
|
||||
},
|
||||
{
|
||||
title: 'Indentify',
|
||||
dataIndex: 'indentify'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
}
|
||||
],
|
||||
compareList: [
|
||||
{
|
||||
title: 'ARMD',
|
||||
list: [
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'IDC',
|
||||
list: [
|
||||
{
|
||||
id: 1,
|
||||
energy: 'energy',
|
||||
centroid: 'centroid',
|
||||
multiplet: 'multiplet',
|
||||
fwhm: 'fwhm',
|
||||
netArea: 'netArea',
|
||||
areaErr: 'areaErr',
|
||||
significant: 'significant',
|
||||
sensitivity: 'sensitivity',
|
||||
indentify: 'indentify'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
compareVisible: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 切换比较
|
||||
handleComparision() {
|
||||
this.compareVisible = !this.compareVisible
|
||||
},
|
||||
|
||||
// 导出到Excel
|
||||
handleExportToExcel() {}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.peak-infomation {
|
||||
::v-deep {
|
||||
.ant-modal-body {
|
||||
padding: 20px 16px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
|
||||
.ant-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comparison-list {
|
||||
&-item {
|
||||
&-title {
|
||||
color: #0cebc9;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
213
src/views/spectrumAnalysis/components/ResultDisplay.vue
Normal file
213
src/views/spectrumAnalysis/components/ResultDisplay.vue
Normal file
|
@ -0,0 +1,213 @@
|
|||
<template>
|
||||
<div class="result-display-content">
|
||||
<a-table :data-source="source1" rowKey="id" :columns="columns" :pagination="false">
|
||||
<template slot="flag">
|
||||
<a-checkbox></a-checkbox>
|
||||
</template>
|
||||
<template slot="concentration" slot-scope="text">
|
||||
<div class="concentration color-box">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="uncertainty" slot-scope="text">
|
||||
<div class="uncertainty color-box">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="mdc" slot-scope="text">
|
||||
<div class="mdc color-box">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="operator">
|
||||
<div class="search"></div>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-table :data-source="source2" rowKey="id" :columns="columns" :pagination="false">
|
||||
<template slot="flag">
|
||||
<a-checkbox></a-checkbox>
|
||||
</template>
|
||||
<template slot="concentration" slot-scope="text">
|
||||
<div class="concentration color-box error">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="uncertainty" slot-scope="text">
|
||||
<div class="uncertainty color-box">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="mdc" slot-scope="text">
|
||||
<div class="mdc color-box">
|
||||
{{ text }}
|
||||
</div>
|
||||
</template>
|
||||
<template slot="operator">
|
||||
<div class="search"></div>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const columns = [
|
||||
{
|
||||
title: 'Flag',
|
||||
align: 'center',
|
||||
scopedSlots: {
|
||||
customRender: 'flag'
|
||||
},
|
||||
width: 40
|
||||
},
|
||||
{
|
||||
title: 'Isotope',
|
||||
dataIndex: 'isotope',
|
||||
ellipsis: true,
|
||||
width: 76
|
||||
},
|
||||
{
|
||||
title: 'Concentration',
|
||||
dataIndex: 'concentration',
|
||||
scopedSlots: {
|
||||
customRender: 'concentration'
|
||||
},
|
||||
width: 128
|
||||
},
|
||||
{
|
||||
title: 'Uncertainty',
|
||||
dataIndex: 'uncertainty',
|
||||
scopedSlots: {
|
||||
customRender: 'uncertainty'
|
||||
},
|
||||
width: 118
|
||||
},
|
||||
{
|
||||
title: 'MDC[mBq/m3]',
|
||||
dataIndex: 'mdc',
|
||||
scopedSlots: {
|
||||
customRender: 'mdc'
|
||||
},
|
||||
width: 133
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
scopedSlots: {
|
||||
customRender: 'operator'
|
||||
},
|
||||
width: 34
|
||||
}
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.columns = columns
|
||||
return {
|
||||
source1: [],
|
||||
source2: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(val) {
|
||||
this.source1 = val.slice(0, 2)
|
||||
this.source2 = val.slice(2, 4)
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.result-display-content {
|
||||
display: flex;
|
||||
|
||||
.ant-table-wrapper {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.ant-table {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ant-table-thead > tr th {
|
||||
color: #00e9fe;
|
||||
font-family: MicrosoftYaHei;
|
||||
font-size: 16px;
|
||||
background-color: transparent !important;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
&:last-child {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-tbody {
|
||||
tr {
|
||||
background-color: transparent;
|
||||
|
||||
td {
|
||||
&:first-child {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
td {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.color-box {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.concentration {
|
||||
background-color: #ad8815;
|
||||
|
||||
&.error {
|
||||
background-color: #c11414;
|
||||
}
|
||||
}
|
||||
|
||||
.uncertainty {
|
||||
background-color: rgba(57, 184, 222, 0.4);
|
||||
}
|
||||
|
||||
.mdc {
|
||||
background-color: rgba(57, 184, 222, 0.4);
|
||||
}
|
||||
.search {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
background: url(~@/assets/images/spectrum/search.png) center no-repeat;
|
||||
|
||||
&:hover {
|
||||
background: url(~@/assets/images/spectrum/search-hover.png) center no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
83
src/views/spectrumAnalysis/components/SpectraListInMenu.vue
Normal file
83
src/views/spectrumAnalysis/components/SpectraListInMenu.vue
Normal file
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<a-menu class="spectra-list-in-menu">
|
||||
<a-menu-item v-for="item in list" :key="item.sampleId" @click="handleClick(item)">
|
||||
<span class="checkbox">
|
||||
<a-icon v-if="item.checked" type="check" style="color: #0de30d" />
|
||||
</span>
|
||||
<span class="name">{{ getFileName(item.inputFileName) }}</span>
|
||||
<a-icon type="delete" @click.stop="handleRemove(item)" />
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick(spectraItem) {
|
||||
this.list.forEach(item => (item.checked = false))
|
||||
spectraItem && (spectraItem.checked = true)
|
||||
this.$emit('change', spectraItem)
|
||||
this.$forceUpdate()
|
||||
},
|
||||
|
||||
handleRemove(spectraItem) {
|
||||
const index = this.list.findIndex(item => item == spectraItem)
|
||||
this.list.splice(index, 1)
|
||||
// 如果删除了一个选中的
|
||||
if (spectraItem.checked) {
|
||||
if (index == 0) {
|
||||
// 如果是第一个,则选中下一个
|
||||
this.handleClick(this.list[0])
|
||||
} else {
|
||||
// 如果不是第一个,则选中上一个
|
||||
this.handleClick(this.list[index - 1])
|
||||
}
|
||||
}
|
||||
this.$forceUpdate()
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
* @param {String} inputFileName
|
||||
*/
|
||||
getFileName(inputFileName) {
|
||||
if (inputFileName) {
|
||||
const arr = inputFileName.split('/')
|
||||
return arr[arr.length - 1]
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
list(newVal) {
|
||||
if (newVal.length) {
|
||||
this.handleClick(newVal[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.spectra-list-in-menu {
|
||||
.checkbox {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
margin: 0 5px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
</style>
|
319
src/views/spectrumAnalysis/components/SpectrumLineChart.vue
Normal file
319
src/views/spectrumAnalysis/components/SpectrumLineChart.vue
Normal file
|
@ -0,0 +1,319 @@
|
|||
<template>
|
||||
<div class="spectrum-line-chart">
|
||||
<div class="summary-text">
|
||||
<span>Channel: {{ summary.channel }}</span>
|
||||
<span>Count: {{ summary.count }}</span>
|
||||
<span class="error">Energy: {{ summary.energy }}</span>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<div class="left-title">{{ title + ' Count' }}</div>
|
||||
<custom-chart
|
||||
class="spectrum-line-chart-main"
|
||||
ref="chartRef"
|
||||
:option="option"
|
||||
style="height: 100%"
|
||||
@zr:mousemove="handleMouseMove"
|
||||
@zr:mousedown="handleMouseDown"
|
||||
@zr:mouseup="handleMouseUp"
|
||||
@brushEnd="handleBrushEnd"
|
||||
></custom-chart>
|
||||
</div>
|
||||
<div class="bottom-title">
|
||||
{{ title + ' Channel' }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js'
|
||||
|
||||
const initialOption = {
|
||||
grid: {
|
||||
top: 10,
|
||||
right: 15,
|
||||
bottom: 20
|
||||
},
|
||||
xAxis: {
|
||||
min: 0,
|
||||
max: 256,
|
||||
interval: 64,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgb(119, 181, 213, 0.5)'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(119, 181, 213, .2)'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#ade6ee'
|
||||
},
|
||||
name: '',
|
||||
nameLocation: 'center',
|
||||
nameTextStyle: {
|
||||
fontSize: 14,
|
||||
color: '#5b9cba'
|
||||
},
|
||||
nameGap: 25
|
||||
},
|
||||
yAxis: {
|
||||
min: 0,
|
||||
max: 0,
|
||||
interval: 0,
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgb(119, 181, 213, 0.5)'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(119, 181, 213, .2)'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#ade6ee'
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: ''
|
||||
},
|
||||
symbol: 'none',
|
||||
data: [],
|
||||
markLine: {
|
||||
symbol: 'none',
|
||||
animation: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: 'yellow'
|
||||
},
|
||||
silent: true,
|
||||
data: []
|
||||
}
|
||||
},
|
||||
brush: {}
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomChart
|
||||
},
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'red'
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Gamma'
|
||||
},
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const option = cloneDeep(initialOption)
|
||||
option.series.itemStyle.color = this.color
|
||||
option.xAxis.name = this.title + ' Channel'
|
||||
return {
|
||||
option,
|
||||
|
||||
summary: {
|
||||
channel: 0,
|
||||
count: 0,
|
||||
energy: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.option.brush = { toolbox: [] }
|
||||
},
|
||||
methods: {
|
||||
resize() {
|
||||
this.$refs.chartRef && this.$refs.chartRef.resize()
|
||||
},
|
||||
|
||||
// 设置辅助线位置
|
||||
setLinePosition(xAxis) {
|
||||
setTimeout(() => {
|
||||
if (xAxis) {
|
||||
this.option.series.markLine.data = [{ xAxis }]
|
||||
this.summary.channel = xAxis
|
||||
const find = this.data.find(item => item.x == xAxis)
|
||||
if (find) {
|
||||
this.summary.count = find.y
|
||||
}
|
||||
} else {
|
||||
this.option.series.markLine.data = []
|
||||
this.summary.channel = 0
|
||||
this.summary.count = 0
|
||||
this.summary.energy = 0
|
||||
}
|
||||
}, 0)
|
||||
},
|
||||
|
||||
// 设置范围
|
||||
setRange(min, max) {
|
||||
this.option.xAxis.min = min
|
||||
this.option.xAxis.max = max
|
||||
},
|
||||
|
||||
// 鼠标在图表上移动时
|
||||
handleMouseMove(param) {
|
||||
const { offsetX, offsetY } = param
|
||||
const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY)
|
||||
this.setLinePosition(point ? point[0].toFixed() : null)
|
||||
},
|
||||
|
||||
// 鼠标按下时开启可刷选状态
|
||||
handleMouseDown() {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor',
|
||||
// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
|
||||
key: 'brush',
|
||||
brushOption: {
|
||||
// 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
|
||||
brushType: 'lineX'
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleMouseUp() {
|
||||
setTimeout(() => {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
// 清理刷选的范围
|
||||
chart.dispatchAction({
|
||||
type: 'brush',
|
||||
areas: []
|
||||
})
|
||||
|
||||
// 改为不可刷选状态
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor'
|
||||
})
|
||||
}, 0)
|
||||
},
|
||||
|
||||
// 刷选完毕时
|
||||
handleBrushEnd(param) {
|
||||
const chart = this.$refs.chartRef.getChartInstance()
|
||||
|
||||
const areas = param.areas[0]
|
||||
if (areas) {
|
||||
const range = areas.range
|
||||
const [minX, maxX] = range
|
||||
|
||||
const point1 = chart.convertFromPixel({ seriesIndex: 0 }, [minX, 0])
|
||||
const point2 = chart.convertFromPixel({ seriesIndex: 0 }, [maxX, 0])
|
||||
|
||||
const [x1, x2] = [parseInt(point1[0].toFixed()), parseInt(point2[0].toFixed())] // 根据解析出的数据确定真实的范围
|
||||
this.option.xAxis.min = x1
|
||||
this.option.xAxis.max = x2
|
||||
|
||||
this.emitRangeChange([x1, x2])
|
||||
}
|
||||
|
||||
// 清理刷选的范围
|
||||
chart.dispatchAction({
|
||||
type: 'brush',
|
||||
areas: []
|
||||
})
|
||||
|
||||
// 改为不可刷选状态
|
||||
chart.dispatchAction({
|
||||
type: 'takeGlobalCursor'
|
||||
})
|
||||
},
|
||||
|
||||
emitRangeChange(range) {
|
||||
this.$emit('rangeChange', range)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newVal) {
|
||||
this.option.series.data = newVal.map(({ x, y }) => [x, y])
|
||||
|
||||
const max = Math.max(...newVal.map(item => item.y))
|
||||
this.option.yAxis.interval = Math.ceil(max / 4)
|
||||
this.option.yAxis.max = this.option.yAxis.interval * 4
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.spectrum-line-chart {
|
||||
height: 100%;
|
||||
|
||||
.summary-text {
|
||||
line-height: 10px;
|
||||
text-align: right;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
|
||||
.error {
|
||||
color: #ff5656;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #ade6ee;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 27px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
display: flex;
|
||||
margin-top: 7px;
|
||||
margin-bottom: 8px;
|
||||
height: calc(100% - 35px);
|
||||
|
||||
.left-title {
|
||||
writing-mode: vertical-rl;
|
||||
color: #5b9cba;
|
||||
font-size: 14px;
|
||||
transform: rotate(180deg);
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.spectrum-line-chart-main {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-title {
|
||||
line-height: 10px;
|
||||
font-size: 14px;
|
||||
color: #5b9cba;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<div class="btn-with-switch-icon">
|
||||
<i @click="handleClick('left')">
|
||||
<img src="@/assets/images/spectrum/left-arrow.png" />
|
||||
</i>
|
||||
<span>
|
||||
<slot></slot>
|
||||
</span>
|
||||
<i @click="handleClick('right')">
|
||||
<img src="@/assets/images/spectrum/right-arrow.png" />
|
||||
</i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleClick(direction) {
|
||||
this.$emit('change', direction)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.btn-with-switch-icon {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid #0a544e;
|
||||
padding: 0 4px;
|
||||
height: 100%;
|
||||
letter-spacing: 1px;
|
||||
color: #ade6ee;
|
||||
|
||||
i {
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,140 @@
|
|||
<template>
|
||||
<div class="detailed-infomation">
|
||||
<a-form :labelCol="{ style: { width: 120 } }">
|
||||
<a-row v-for="(row, index) in items" :key="index">
|
||||
<a-col v-for="(item, i) in row" :key="i" :span="item.span || 4">
|
||||
<a-form-item :label="item.label">
|
||||
{{ data[item.name] }}
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const items = [
|
||||
[
|
||||
{
|
||||
label: 'Sample Id',
|
||||
name: 'sampleId'
|
||||
},
|
||||
{
|
||||
label: 'Data Type',
|
||||
name: 'dataType'
|
||||
},
|
||||
{
|
||||
label: 'Collection Start',
|
||||
name: 'collectionStart',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Acquisition Start',
|
||||
name: 'acquisitionStart',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Auto.Cat',
|
||||
name: 'autoCat'
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
label: 'Station Code',
|
||||
name: 'stationCode'
|
||||
},
|
||||
{
|
||||
label: 'Spectral Qualifier',
|
||||
name: 'spectralQualifier'
|
||||
},
|
||||
{
|
||||
label: 'Sampling Time',
|
||||
name: 'samplingTime',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Acq.Real',
|
||||
name: 'acqReal',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Category',
|
||||
name: 'category'
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
label: 'Detector Code',
|
||||
name: 'detectorCode'
|
||||
},
|
||||
{
|
||||
label: 'SRID',
|
||||
name: 'srid'
|
||||
},
|
||||
{
|
||||
label: 'Quantity',
|
||||
name: 'quantity',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Acq.Live',
|
||||
name: 'acqLive',
|
||||
span: 6
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
label: 'System Type',
|
||||
name: 'systemType'
|
||||
},
|
||||
{
|
||||
label: 'Sample Status',
|
||||
name: 'sampleStatus'
|
||||
},
|
||||
{
|
||||
label: 'Flow Rate',
|
||||
name: 'flowRate',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
label: 'Decay Time',
|
||||
name: 'decayTime',
|
||||
span: 6
|
||||
}
|
||||
]
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
sampleId: 1,
|
||||
dataType: 'SAMPLEPHD'
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.items = items
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.detailed-infomation {
|
||||
width: 1200px;
|
||||
|
||||
.ant-form-item {
|
||||
margin-bottom: 0;
|
||||
|
||||
::v-deep {
|
||||
.ant-form-item-label > label {
|
||||
color: #ade6ee;
|
||||
}
|
||||
|
||||
.ant-form-item-children {
|
||||
color: #0cecca;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div class="graph-assistance">
|
||||
<div class="graph-assistance-item" v-for="conf in config" :key="conf.title">
|
||||
<span>{{ conf.label }}</span>
|
||||
<a-switch v-model="conf.checked" @change="handleChange(conf)"></a-switch>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const config = [
|
||||
{
|
||||
label: 'Log10',
|
||||
checked: true
|
||||
},
|
||||
{
|
||||
label: 'Cursor',
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
label: 'Lc',
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
label: 'Baseline',
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
label: 'Channel',
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
label: 'Lines',
|
||||
checked: false
|
||||
},
|
||||
{
|
||||
label: 'S CAC',
|
||||
checked: false
|
||||
}
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
config
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(conf) {
|
||||
console.log('%c [ conf ]-47', 'font-size:13px; background:pink; color:#bf2c9f;', conf)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.graph-assistance {
|
||||
display: flex;
|
||||
width: 790px;
|
||||
justify-content: space-between;
|
||||
|
||||
&-item {
|
||||
span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<div class="nuclear-library">
|
||||
<div class="nuclear-library-item" v-for="item in list" :key="item.id">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
list: [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Ac228'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Ac229'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Ac230'
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
title: 'Eu152'
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
title: 'I132'
|
||||
},
|
||||
{
|
||||
id: '6',
|
||||
title: 'Ir192'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nuclear-library {
|
||||
width: 230px;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
|
||||
&-item {
|
||||
padding: 4px 14px;
|
||||
// cursor: pointer;
|
||||
|
||||
// &:hover {
|
||||
// background-color: #055565;
|
||||
// }
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<a-popover :placement="placement" overlayClassName="popover-with-icon" v-model="innerVisible">
|
||||
<div class="pop-over-with-icon">
|
||||
<span class="text">
|
||||
<slot />
|
||||
</span>
|
||||
<img src="@/assets/images/global/select-down.png" alt="" />
|
||||
</div>
|
||||
<template slot="content">
|
||||
<slot name="content" />
|
||||
</template>
|
||||
</a-popover>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
},
|
||||
value: {
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerVisible: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
this.innerVisible = val
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
innerVisible(val) {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.pop-over-with-icon {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border: 1px solid #0a544e;
|
||||
height: 100%;
|
||||
padding: 0 11px;
|
||||
cursor: pointer;
|
||||
|
||||
.text {
|
||||
font-family: MicrosoftYaHei;
|
||||
color: #ade6ee;
|
||||
letter-spacing: 1px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-left: 5px;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&.ant-popover-open {
|
||||
img {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.popover-with-icon {
|
||||
.ant-popover-inner-content {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<div class="qc-flags">
|
||||
<div class="qc-flags-item" v-for="conf in config" :key="conf.label">
|
||||
<span :class="'dot' + (data[conf.name] ? ' green' : '')"></span>
|
||||
{{ conf.label }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 配置
|
||||
const config = [
|
||||
{
|
||||
label: 'Collection Time',
|
||||
name: 'collectionTime'
|
||||
},
|
||||
{
|
||||
label: 'Acq Time',
|
||||
name: 'acqTime'
|
||||
},
|
||||
{
|
||||
label: 'Decay Time',
|
||||
name: 'decayTime'
|
||||
},
|
||||
{
|
||||
label: 'SampVol',
|
||||
name: 'sampVol'
|
||||
},
|
||||
{
|
||||
label: 'Be7-FWHM',
|
||||
name: 'be7Fwhm'
|
||||
},
|
||||
{
|
||||
label: 'Ba140-MDC',
|
||||
name: 'ba140Mdc'
|
||||
},
|
||||
{
|
||||
label: 'Xe133-MDC',
|
||||
name: 'xe133Mdc'
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.config = config
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.qc-flags {
|
||||
display: flex;
|
||||
&-item {
|
||||
background-color: #46738e;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
height: 30px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: 20px;
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, #979797 0, #777a7c 100%);
|
||||
|
||||
&.green {
|
||||
background: radial-gradient(circle, #00fe7f 0, #00d56a 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<div class="spectra">
|
||||
<div
|
||||
:class="'spectra-item' + (item.title == innerValue ? ' active' : '')"
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
@click="handleClick(item)"
|
||||
>
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const list = [
|
||||
{
|
||||
title: 'Sample Data'
|
||||
},
|
||||
{
|
||||
title: 'GasBg Data'
|
||||
},
|
||||
{
|
||||
title: 'DetBg Data'
|
||||
},
|
||||
{
|
||||
title: 'QC Data'
|
||||
}
|
||||
]
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
this.list = list
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleClick(item) {
|
||||
this.innerValue = item.title
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
innerValue: {
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
},
|
||||
get() {
|
||||
return this.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.spectra {
|
||||
width: 159px;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
|
||||
&-item {
|
||||
padding: 4px 14px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
background-color: #055565;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
39
src/views/spectrumAnalysis/components/TitleOverBoarder.vue
Normal file
39
src/views/spectrumAnalysis/components/TitleOverBoarder.vue
Normal file
|
@ -0,0 +1,39 @@
|
|||
<template>
|
||||
<div class="title-over-border">
|
||||
<div class="title-over-border-title">{{ title }}</div>
|
||||
<div class="title-over-border-content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@color: rgba(12, 235, 201, 0.6);
|
||||
.title-over-border {
|
||||
border: 1px solid @color;
|
||||
position: relative;
|
||||
|
||||
&-title {
|
||||
color: @color;
|
||||
background-color: #022024;
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
left: 10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
325
src/views/spectrumAnalysis/gamma-analysis.vue
Normal file
325
src/views/spectrumAnalysis/gamma-analysis.vue
Normal file
|
@ -0,0 +1,325 @@
|
|||
<template>
|
||||
<div class="gamma-analysis">
|
||||
<!-- 二级交互栏 -->
|
||||
<div class="spectrum-analysis-sub-operators">
|
||||
<pop-over-with-icon placement="bottomLeft">
|
||||
Detailed-Information
|
||||
<detailed-infomation slot="content" />
|
||||
</pop-over-with-icon>
|
||||
<pop-over-with-icon placement="bottomLeft">
|
||||
QC Flags
|
||||
<qc-flags slot="content" :data="{ collectionTime: '123' }" />
|
||||
</pop-over-with-icon>
|
||||
<pop-over-with-icon>
|
||||
Graph Assistance
|
||||
<graph-assistance slot="content" />
|
||||
</pop-over-with-icon>
|
||||
<pop-over-with-icon>
|
||||
Nuclide Library
|
||||
<nuclear-library slot="content" />
|
||||
</pop-over-with-icon>
|
||||
<div class="peak-info">
|
||||
<button-with-switch-icon @change="handlePeakInfoChange">
|
||||
Peak Information
|
||||
</button-with-switch-icon>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 二级交互栏结束 -->
|
||||
<!-- 主体部分 -->
|
||||
<div class="gamma-analysis-main">
|
||||
<div class="gamma-analysis-chart">
|
||||
<custom-chart ref="chartRef" :option="option" style="height: 100%" />
|
||||
</div>
|
||||
<div class="gamma-analysis-thumbnail">
|
||||
<custom-chart :option="thumbnailOption" style="height: 100%" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 主体部分结束 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CustomChart from '@/components/CustomChart/index.vue'
|
||||
import PopOverWithIcon from './components/SubOperators/PopOverWithIcon.vue'
|
||||
import DetailedInfomation from './components/SubOperators/DetailedInfomation.vue'
|
||||
import QcFlags from './components/SubOperators/QcFlags.vue'
|
||||
import GraphAssistance from './components/SubOperators/GraphAssistance.vue'
|
||||
import NuclearLibrary from './components/SubOperators/NuclearLibrary.vue'
|
||||
import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue'
|
||||
|
||||
// 初始配置
|
||||
const initialOption = {
|
||||
grid: {
|
||||
top: 40,
|
||||
left: 60,
|
||||
right: 0
|
||||
},
|
||||
title: {
|
||||
text: '',
|
||||
left: 'center',
|
||||
bottom: 10,
|
||||
textStyle: {
|
||||
color: '#8FD4F8',
|
||||
rich: {
|
||||
a: {
|
||||
padding: [0, 20, 0, 0],
|
||||
fontSize: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
animation: false,
|
||||
type: 'cross',
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#ade6ee'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#ade6ee'
|
||||
}
|
||||
},
|
||||
data: new Array(3928).fill(0).map((_, index) => index)
|
||||
},
|
||||
yAxis: {
|
||||
name: 'Counts',
|
||||
nameTextStyle: {
|
||||
color: '#8FD4F8',
|
||||
fontSize: 16
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#ade6ee'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(173, 230, 238, .2)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#ade6ee'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
data: new Array(3928)
|
||||
.fill(0)
|
||||
.map((_, index) => (Math.random() < 0.05 ? parseInt(Math.random() * 16000) : parseInt(Math.random() * 800))),
|
||||
itemStyle: {
|
||||
color: '#24FF0B'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: 'none',
|
||||
markLine: {
|
||||
symbol: 'none',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
lineStyle: {
|
||||
type: 'solid'
|
||||
},
|
||||
data: [
|
||||
{
|
||||
xAxis: 100,
|
||||
lineStyle: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: new Array(3928)
|
||||
.fill(0)
|
||||
.map((_, index) => (Math.random() < 0.05 ? parseInt(Math.random() * 14000) : parseInt(Math.random() * 600))),
|
||||
itemStyle: {
|
||||
color: '#D8DE07'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: 'none'
|
||||
}
|
||||
],
|
||||
dataZoom: {
|
||||
type: 'inside',
|
||||
start: 0,
|
||||
end: 20,
|
||||
zoomLock: true
|
||||
}
|
||||
}
|
||||
|
||||
// 缩略图配置
|
||||
const thumbnailOption = {
|
||||
grid: {
|
||||
top: 0,
|
||||
left: 5,
|
||||
right: 5,
|
||||
bottom: 0
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: false
|
||||
},
|
||||
data: new Array(3928).fill(0).map((_, index) => index)
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
data: new Array(3928)
|
||||
.fill(0)
|
||||
.map((_, index) => (Math.random() < 0.05 ? parseInt(Math.random() * 16000) : parseInt(Math.random() * 800))),
|
||||
itemStyle: {
|
||||
color: '#24FF0B'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: 'none'
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
data: new Array(3928)
|
||||
.fill(0)
|
||||
.map((_, index) => (Math.random() < 0.05 ? parseInt(Math.random() * 14000) : parseInt(Math.random() * 600))),
|
||||
itemStyle: {
|
||||
color: '#D8DE07'
|
||||
},
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: 'none'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
},
|
||||
chartType: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CustomChart,
|
||||
PopOverWithIcon,
|
||||
DetailedInfomation,
|
||||
QcFlags,
|
||||
GraphAssistance,
|
||||
NuclearLibrary,
|
||||
ButtonWithSwitchIcon
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
option: initialOption,
|
||||
thumbnailOption
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.option.title.text = '{a|Channel:0} {a|Energy:0} {a|Counts:0} {a|Detectability:0}'
|
||||
|
||||
console.log('%c [ ]-108', 'font-size:13px; background:pink; color:#bf2c9f;', this.option)
|
||||
},
|
||||
methods: {
|
||||
resize() {
|
||||
this.$refs.chartRef.resize()
|
||||
},
|
||||
|
||||
// peak info 点击左右方向
|
||||
handlePeakInfoChange(direction) {
|
||||
this.moveMarkLine(direction)
|
||||
},
|
||||
|
||||
/**
|
||||
* 向某一个方向移动标记线
|
||||
* @param { 'left'| 'right' } direction
|
||||
*/
|
||||
moveMarkLine(direction) {
|
||||
if (direction == 'left') {
|
||||
this.option.series[0].markLine.data[0].xAxis = this.option.series[0].markLine.data[0].xAxis - 10
|
||||
} else {
|
||||
this.option.series[0].markLine.data[0].xAxis = this.option.series[0].markLine.data[0].xAxis + 10
|
||||
}
|
||||
|
||||
this.$emit('markLineChange', {})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler() {},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.gamma-analysis {
|
||||
height: 100%;
|
||||
|
||||
&-main {
|
||||
height: calc(100% - 51px);
|
||||
display: flex;
|
||||
overflow: auto hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-thumbnail {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 10px;
|
||||
width: 500px;
|
||||
height: 150px;
|
||||
background-color: #153e44;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,3 +1,754 @@
|
|||
<template>
|
||||
<div>能谱分析页面</div>
|
||||
</template>
|
||||
<div class="spectrum-analysis">
|
||||
<!-- 顶部操作栏 -->
|
||||
<div class="spectrum-analysis-operators">
|
||||
<a-dropdown
|
||||
class="spectrum-analysis-operators-item"
|
||||
overlayClassName="spectrum-analysis-operators-dropdown-overlay"
|
||||
:overlay-style="operation.style"
|
||||
v-for="operation in operations"
|
||||
:key="operation.title"
|
||||
>
|
||||
<a-button type="primary">{{ operation.title }}</a-button>
|
||||
<div slot="overlay">
|
||||
<template v-for="(child, index) in operation.children">
|
||||
<component :is="child.type" :key="index" v-bind="child.attrs" v-on="child.on">
|
||||
<component :is="item.type" v-for="item in child.children" :key="item.title" @click="item.handler">
|
||||
{{ item.title }}
|
||||
</component>
|
||||
</component>
|
||||
</template>
|
||||
</div>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
<!-- 顶部操作栏结束 -->
|
||||
|
||||
<!-- 频谱分析部分 -->
|
||||
<div class="spectrum-analysis-main">
|
||||
<gamma-analysis v-if="analysisType == ANALYZE_TYPE.GAMMA" ref="gammaAnalysisRef" />
|
||||
<beta-gamma-analysis
|
||||
v-if="analysisType == ANALYZE_TYPE.BETA_GAMMA"
|
||||
ref="betaGammaAnalysisRef"
|
||||
:data="analysisData"
|
||||
/>
|
||||
<resize-observer @notify="handleResize" />
|
||||
</div>
|
||||
<!-- 频谱分析部分结束 -->
|
||||
|
||||
<!-- 从数据库加载开始 -->
|
||||
<load-from-db-modal v-model="loadFromDbModalVisible" @loadSample="handleLoadSampleFromDB" />
|
||||
<!-- 从数据库加载结束 -->
|
||||
|
||||
<!-- 从文件加载开始 -->
|
||||
<load-from-file-modal v-model="loadFromFileModalVisible" />
|
||||
<!-- 从文件加载结束 -->
|
||||
|
||||
<!-- Peak Infomation 弹窗开始 -->
|
||||
<peak-infomation v-model="peakInfomationModalVisible" />
|
||||
<!-- Peak Infomation 弹窗结束 -->
|
||||
|
||||
<!-- Nuclide Activity and MDC 弹窗开始 -->
|
||||
<nuclide-activity-and-mdc-modal v-model="nuclideActivityAndMDCModalVisible" />
|
||||
<!-- Nuclide Activity and MDC 弹窗结束 -->
|
||||
|
||||
<!-- Save Setting 弹窗开始 -->
|
||||
<save-setting-modal v-model="saveSettingModalVisible" />
|
||||
<!-- Save Setting 弹窗结束 -->
|
||||
|
||||
<!-- 分析-设置弹窗开始 -->
|
||||
<analyze-setting-modal v-model="analyzeConfigureModalVisible" />
|
||||
<!-- 分析-设置弹窗结束 -->
|
||||
|
||||
<!-- 分析工具弹窗开始 -->
|
||||
<analyze-interactive-tool-modal v-model="analyzeInteractiveToolModalVisible" />
|
||||
<!-- 分析工具弹窗结束 -->
|
||||
|
||||
<!-- Korsum 弹窗开始 -->
|
||||
<korsum-modal v-model="korsumModalShow" />
|
||||
<!-- Korsum 弹窗结束 -->
|
||||
|
||||
<!-- ReProcessing 弹窗开始 -->
|
||||
<re-processing-modal v-model="reprocessingModalVisible" />
|
||||
<!-- ReProcessing 弹窗结束 -->
|
||||
|
||||
<!-- Zero Time 弹窗开始 -->
|
||||
<zero-time-modal v-model="zeroTimeModalVisible" />
|
||||
<!-- Zero Time 弹窗结束 -->
|
||||
|
||||
<!-- Efficiency Calibration 弹窗开始 -->
|
||||
<efficiency-calibration-modal v-model="efficiencyCalibrationModalShow" />
|
||||
<!-- Efficiency Calibration 弹窗结束 -->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import GammaAnalysis from './gamma-analysis.vue'
|
||||
import BetaGammaAnalysis from './beta-gamma-analysis.vue'
|
||||
import SpectraListInMenu from './components/SpectraListInMenu.vue'
|
||||
import LoadFromDbModal from './components/Modals/LoadFromDBModal.vue'
|
||||
import LoadFromFileModal from './components/Modals/LoadFromFileModal.vue'
|
||||
import PeakInfomation from './components/PeakInfomation.vue'
|
||||
import NuclideActivityAndMdcModal from './components/Modals/NuclideActivityAndMDCModal.vue'
|
||||
import MultiLevelMenu from './components/MultiLevelMenu.vue'
|
||||
import SaveSettingModal from './components/Modals/SaveSettingModal.vue'
|
||||
import AnalyzeSettingModal from './components/Modals/AnalyzeSettingModal.vue'
|
||||
import AnalyzeInteractiveToolModal from './components/Modals/AnalyzeInteractiveToolModal/index.vue'
|
||||
import { getAction } from '../../api/manage'
|
||||
import KorsumModal from './components/Modals/KorsumModal.vue'
|
||||
import ReProcessingModal from './components/Modals/ReProcessingModal/index.vue'
|
||||
import ZeroTimeModal from './components/Modals/ZeroTimeModal.vue'
|
||||
import EfficiencyCalibrationModal from './components/Modals/EfficiencyCalibrationModal.vue'
|
||||
|
||||
// 分析类型
|
||||
const ANALYZE_TYPE = {
|
||||
GAMMA: 'gammaAnalysis',
|
||||
BETA_GAMMA: 'betaGammaAnalysis'
|
||||
}
|
||||
export default {
|
||||
components: {
|
||||
BetaGammaAnalysis,
|
||||
GammaAnalysis,
|
||||
SpectraListInMenu,
|
||||
LoadFromDbModal,
|
||||
LoadFromFileModal,
|
||||
PeakInfomation,
|
||||
NuclideActivityAndMdcModal,
|
||||
MultiLevelMenu,
|
||||
SaveSettingModal,
|
||||
AnalyzeSettingModal,
|
||||
AnalyzeInteractiveToolModal,
|
||||
KorsumModal,
|
||||
ReProcessingModal,
|
||||
ZeroTimeModal,
|
||||
EfficiencyCalibrationModal
|
||||
},
|
||||
data() {
|
||||
this.ANALYZE_TYPE = ANALYZE_TYPE
|
||||
|
||||
return {
|
||||
analysisType: null, // 分析类型
|
||||
|
||||
sampleList: [],
|
||||
|
||||
loadFromDbModalVisible: false, // 从数据库加载弹窗
|
||||
loadFromFileModalVisible: false, // 从文件加载弹窗
|
||||
|
||||
analysisData: {}, // 要分析的谱数据
|
||||
|
||||
peakInfomationModalVisible: false,
|
||||
|
||||
nuclideActivityAndMDCModalVisible: false,
|
||||
|
||||
saveSettingModalVisible: false, // 保存设置弹窗
|
||||
|
||||
analyzeConfigureModalVisible: false, // 分析设置弹窗
|
||||
|
||||
reprocessingModalVisible: false, // 重新分析弹窗
|
||||
|
||||
analyzeInteractiveToolModalVisible: false, // 分析工具弹窗
|
||||
|
||||
zeroTimeModalVisible: false, // Zero Time 弹窗
|
||||
|
||||
korsumModalShow: false, // Korsum 弹窗
|
||||
|
||||
efficiencyCalibrationModalShow: false // Calibration -> efficiency弹窗
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 测试
|
||||
this.loadSelectedSample({
|
||||
dbName: 'auto',
|
||||
sampleType: 'B',
|
||||
sampleId: '1523651'
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 从数据库加载
|
||||
handleLoadFromDb() {
|
||||
this.loadFromDbModalVisible = true
|
||||
},
|
||||
|
||||
// 从数据库加载-选择完成
|
||||
handleLoadSampleFromDB(sampleList) {
|
||||
this.sampleList = sampleList
|
||||
},
|
||||
|
||||
// 加载选中的样本
|
||||
async loadSelectedSample({ dbName, sampleType, sampleId }) {
|
||||
// B是beta-gamma P G是gamma
|
||||
if (sampleType == 'B') {
|
||||
const { success, result, message } = await getAction('/spectrumAnalysis/getDBSpectrumChart', {
|
||||
dbName,
|
||||
sampleId: sampleId
|
||||
})
|
||||
if (success) {
|
||||
this.analysisData = result.sample
|
||||
this.analysisType = ANALYZE_TYPE.BETA_GAMMA
|
||||
} else {
|
||||
this.$message.error(message)
|
||||
}
|
||||
} else {
|
||||
// gamma
|
||||
}
|
||||
},
|
||||
|
||||
// 从文件加载
|
||||
handleLoadFromFile() {
|
||||
this.loadFromFileModalVisible = true
|
||||
},
|
||||
|
||||
// 清理全部
|
||||
handleCleanAll() {
|
||||
this.sampleList = []
|
||||
},
|
||||
|
||||
// 保存结果到文件, 服务端生成文件,前端下载
|
||||
handleSaveResultsToFile() {
|
||||
this.saveSettingModalVisible = true
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存结果到数据库
|
||||
* @param { 'all' | 'current' } type
|
||||
*/
|
||||
handleSaveResultsToDB(type) {
|
||||
console.log('%c [ saveResultsToDB ]-157', 'font-size:13px; background:pink; color:#bf2c9f;', type)
|
||||
},
|
||||
|
||||
/**
|
||||
* 将谱列表中所有谱数据均以IMS2.0格式保存为PHD文件,
|
||||
* 服务端生成文件,前端下载
|
||||
* @param { 'all' | 'current' } type
|
||||
*/
|
||||
handleSavePHDToFile(type) {
|
||||
console.log('%c [ savePHDToFile ]-162', 'font-size:13px; background:pink; color:#bf2c9f;', type)
|
||||
},
|
||||
|
||||
// 显示分析设置弹窗
|
||||
handleShowConfigureModal() {
|
||||
this.analyzeConfigureModalVisible = true
|
||||
},
|
||||
|
||||
handleReprocessAll() {
|
||||
console.log('%c [ handleReprocessAll ]-216', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 弹出能量刻度界面
|
||||
handleEnergy() {
|
||||
console.log('%c [ handleEnergy ]-163', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 弹出分辨率刻度界面
|
||||
handleResolution() {
|
||||
console.log('%c [ handleResolution ]-167', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 弹出 Nuclide Library 弹窗
|
||||
handleNuclideLib() {
|
||||
console.log('%c [ handleNuclideLib ]-178', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
handleConfigUserLib() {
|
||||
console.log('%c [ handleConfigUserLib ]-182', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 查看自动处理报告
|
||||
handleViewARR() {
|
||||
console.log('%c [ handleViewARR ]-186', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 查看交互分析报告
|
||||
handleViewRRR() {
|
||||
console.log('%c [ handleViewRRR ]-192', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 显示接收到的原始谱文件
|
||||
handleViewSpectrum() {
|
||||
console.log('%c [ handleViewSpectrum ]-198', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 可浏览原始谱中台站操作员对样品采集和测量过程的注释信息;可以浏览分析人员对分析过程的注释信息
|
||||
handleViewComments() {
|
||||
console.log('%c [ viewComments ]-162', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 可添加能谱分析注释
|
||||
handleAddComments() {
|
||||
console.log('%c [ handleAddComments ]-167', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 查看自动处理日志
|
||||
handleAutoAnalysisLog() {
|
||||
console.log('%c [ handleAutoAnalysisLog ]-211', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 查看交互分析日志
|
||||
handleGammaViewerLog() {
|
||||
console.log('%c [ handleGammaViewerLog ]-211', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 查看软件操作帮助文档
|
||||
handleHelp() {
|
||||
console.log('%c [ handleHelp ]-221', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
// 设置软件中主界面和交互分析界面中各曲线的颜色
|
||||
handleLineColorConfig() {
|
||||
console.log('%c [ handleLineColorConfig ]-225', 'font-size:13px; background:pink; color:#bf2c9f;')
|
||||
},
|
||||
|
||||
handleResize() {
|
||||
this.$refs.gammaAnalysisRef && this.$refs.gammaAnalysisRef.resize()
|
||||
this.$refs.betaGammaAnalysisRef && this.$refs.betaGammaAnalysisRef.resize()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
operations() {
|
||||
return [
|
||||
{
|
||||
title: 'SAMPLE',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Load From DB',
|
||||
handler: this.handleLoadFromDb
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Load From File',
|
||||
handler: this.handleLoadFromFile
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Clean All',
|
||||
handler: this.handleCleanAll
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'a-divider',
|
||||
attrs: {
|
||||
style: {
|
||||
marginTop: '5px',
|
||||
marginBottom: '5px',
|
||||
display: this.sampleList.length ? '' : 'none'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'SpectraListInMenu',
|
||||
attrs: {
|
||||
list: this.sampleList
|
||||
},
|
||||
on: {
|
||||
change: spectra => {
|
||||
if (spectra) {
|
||||
this.loadSelectedSample(spectra)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'SAVE',
|
||||
children: [
|
||||
{
|
||||
type: 'MultiLevelMenu',
|
||||
attrs: {
|
||||
children: [
|
||||
{
|
||||
title: 'Save Results to File'
|
||||
},
|
||||
{
|
||||
title: 'Save Results to DB',
|
||||
children: [
|
||||
{
|
||||
title: 'Save Current',
|
||||
key: 'current'
|
||||
},
|
||||
{
|
||||
title: 'Save All',
|
||||
key: 'all'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Save PHD to File',
|
||||
children: [
|
||||
{
|
||||
title: 'Save Current',
|
||||
key: 'current'
|
||||
},
|
||||
{
|
||||
title: 'Save All',
|
||||
key: 'all'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
width: '170px'
|
||||
},
|
||||
on: {
|
||||
menuClick: () => {
|
||||
this.handleSaveResultsToFile()
|
||||
},
|
||||
submenuClick: ({ item, child }) => {
|
||||
if (item.title == 'Save Results to DB') {
|
||||
this.handleSaveResultsToDB(child.key)
|
||||
} else if (item.title == 'Save PHD to File') {
|
||||
this.handleSavePHDToFile(child.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'ANALYZE',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Configure',
|
||||
handler: this.handleShowConfigureModal
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'ReProcessing',
|
||||
handler: () => {
|
||||
this.reprocessingModalVisible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Reprocess All',
|
||||
handler: this.handleReprocessAll
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Interactive Tool',
|
||||
handler: () => {
|
||||
this.analyzeInteractiveToolModalVisible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Zero Time',
|
||||
handler: () => {
|
||||
this.zeroTimeModalVisible = true
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Korsum',
|
||||
handler: () => {
|
||||
this.korsumModalShow = true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'CALIBRATION',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Energy',
|
||||
handler: this.handleEnergy
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Resolution',
|
||||
handler: this.handleResolution
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Efficiency',
|
||||
handler: () => {
|
||||
this.efficiencyCalibrationModalShow = true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'NUCLIDELIBRARY',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Nuclide Library',
|
||||
handler: this.handleNuclideLib
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Config User Library',
|
||||
handler: this.handleConfigUserLib
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'COMMENTS',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'View Comments',
|
||||
handler: this.handleViewComments
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Add Comments',
|
||||
handler: this.handleAddComments
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'REPORTS',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'View ARR',
|
||||
handler: this.handleViewARR
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'View RRR',
|
||||
handler: this.handleViewRRR
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'View Spectrum',
|
||||
handler: this.handleViewSpectrum
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'LOG',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Automatic Analysis Log',
|
||||
handler: this.handleAutoAnalysisLog
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'GammaViewer Log',
|
||||
handler: this.handleGammaViewerLog
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'HELP',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu',
|
||||
children: [
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Help',
|
||||
handler: this.handleHelp
|
||||
},
|
||||
{
|
||||
type: 'a-menu-item',
|
||||
title: 'Line Color Config',
|
||||
handler: this.handleLineColorConfig
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.spectrum-analysis {
|
||||
padding-top: 17px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// 顶部操作栏开始
|
||||
&-operators {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: nowrap;
|
||||
overflow: auto;
|
||||
|
||||
&-item {
|
||||
width: 158px;
|
||||
border: 1px solid rgba(12, 235, 201, 0.6);
|
||||
border-top-width: 3px;
|
||||
height: 30px;
|
||||
background-color: rgba(51, 202, 217, 0.2);
|
||||
color: #ccede8;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
span {
|
||||
text-shadow: none;
|
||||
line-height: 26px;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 224px;
|
||||
}
|
||||
&:nth-child(5) {
|
||||
width: 268px;
|
||||
}
|
||||
&:nth-child(6) {
|
||||
width: 257px;
|
||||
}
|
||||
&:nth-child(7) {
|
||||
width: 234px;
|
||||
}
|
||||
&:nth-child(8) {
|
||||
width: 125px;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 顶部操作栏结束
|
||||
|
||||
::v-deep {
|
||||
// 二级操作栏开始
|
||||
.spectrum-analysis-sub-operators {
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 19px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
overflow: auto;
|
||||
|
||||
.pop-over-with-icon {
|
||||
height: 32px;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 11px;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 256px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
width: 186px;
|
||||
}
|
||||
&:nth-child(3) {
|
||||
width: 246px;
|
||||
}
|
||||
&:nth-child(4) {
|
||||
width: 246px;
|
||||
}
|
||||
}
|
||||
|
||||
.peak-info {
|
||||
width: 306px;
|
||||
height: 32px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
// 二级操作栏结束
|
||||
}
|
||||
|
||||
// 主体部分开始
|
||||
&-main {
|
||||
margin-top: 15px;
|
||||
height: calc(100% - 45px);
|
||||
overflow: hidden;
|
||||
}
|
||||
// 主体部分结束
|
||||
}
|
||||
</style>
|
||||
<style lang="less">
|
||||
.spectrum-analysis-operators-dropdown-overlay {
|
||||
background-color: #03353f;
|
||||
.ant-menu {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
border-right: 0;
|
||||
|
||||
&-submenu {
|
||||
&-active {
|
||||
background-color: #055565 !important;
|
||||
}
|
||||
|
||||
&-title {
|
||||
height: 30px !important;
|
||||
line-height: 30px !important;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
|
||||
&:active {
|
||||
background-color: #055565 !important;
|
||||
}
|
||||
|
||||
.ant-menu-submenu-arrow {
|
||||
&::before,
|
||||
&::after {
|
||||
background: #fff !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-item {
|
||||
color: #fff;
|
||||
font-family: Arial;
|
||||
border: 0;
|
||||
background-color: transparent !important;
|
||||
padding: 4px 14px;
|
||||
height: 30px;
|
||||
line-height: 22px;
|
||||
margin: 0 !important;
|
||||
|
||||
&:hover {
|
||||
background-color: #055565 !important;
|
||||
}
|
||||
&-selected {
|
||||
font-weight: normal;
|
||||
}
|
||||
&-disabled {
|
||||
color: #476d74 !important;
|
||||
&:hover {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
:bodyStyle="{ padding: '15px 0 10px' }"
|
||||
title="Data Recevice status Monitoring"
|
||||
:width="1230"
|
||||
:showFooter="false"
|
||||
:footer="null"
|
||||
@fullscreen="onModalFullScreen"
|
||||
:getContainer="getModalContainer"
|
||||
>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
:selectedRowKeys.sync="selectedRowKeys"
|
||||
:scroll="{ y: 'calc(100vh - 365px)' }"
|
||||
:scroll="{ y: 'calc(100vh - 395px)' }"
|
||||
>
|
||||
<template slot="index" slot-scope="{ index }">
|
||||
{{ index + 1 }}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
:dataSource="dataSource"
|
||||
:pagination="ipagination"
|
||||
:loading="loading"
|
||||
:scroll="{ y: 'calc(100vh - 400px)' }"
|
||||
:scroll="{ y: 'calc(100vh - 402px)' }"
|
||||
@change="handleTableChange">
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<a @click="handleEdit(record)">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
:pagination="false"
|
||||
:dataSource="dataSource"
|
||||
:loading="loading"
|
||||
:scroll="{ y: 'calc(100vh - 285px)'}"
|
||||
:scroll="{ y: 'calc(100vh - 290px)'}"
|
||||
@expand="expandSubmenu"
|
||||
:expandedRowKeys="expandedRowKeys"
|
||||
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
:selectedRowKeys.sync="selectedRowKeys"
|
||||
:scroll="{ y: 'calc(100vh - 365px)' }"
|
||||
:scroll="{ y: 'calc(100vh - 370px)' }"
|
||||
>
|
||||
<template slot="index" slot-scope="{ index }">
|
||||
{{ index + 1 }}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
:selectedRowKeys.sync="selectedRowKeys"
|
||||
:scroll="{ y: 'calc(100vh - 365px)' }"
|
||||
:scroll="{ y: 'calc(100vh - 370px)' }"
|
||||
>
|
||||
<template slot="index" slot-scope="{ index }">
|
||||
{{ index + 1 }}
|
||||
|
|
Loading…
Reference in New Issue
Block a user