WIP: Spectrum Analyze页面开发

This commit is contained in:
Xu Zhimeng 2023-06-28 19:25:11 +08:00
parent 3cfc33d2c0
commit f36c94fa4e
20 changed files with 1850 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -46,6 +46,6 @@ export default {
</script>
<style lang="less" scoped>
.custom-chart {
height: 100%;
height: 100% !important;
}
</style>

View File

@ -869,6 +869,7 @@ input[type='number']::-webkit-outer-spin-button {
&-arrow {
border-left-color: #03353f !important;
border-top-color: #03353f !important;
z-index: -1;
}
}

View File

@ -0,0 +1,154 @@
<template>
<div class="beta-gamma-analysis">
<div class="beta-gamma-spectrum-sample">
<beta-gamma-chart-container>
<template slot="title">
Beta-Gamma Spectrum: Sample
</template>
<beta-gamma-spectrum-chart ref="scatterChartRef" />
</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" />
</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" />
</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" title="Beta" color="#00ff1e" />
</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" title="Beta" color="#00ff1e" />
</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>
</div>
</template>
<script>
import BetaGammaChartContainer from './components/BetaGammaChartContainer.vue'
import BetaGammaSpectrumChart from './components/BetaGammaSpectrumChart.vue'
import ResultDisplay from './components/ResultDisplay.vue'
import SpectrumLineChart from './components/SpectrumLineChart.vue'
export default {
components: { BetaGammaChartContainer, SpectrumLineChart, ResultDisplay, BetaGammaSpectrumChart },
data() {
return {
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'
}
]
}
},
methods: {
resize() {
this.$refs.scatterChartRef && this.$refs.scatterChartRef.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()
}
}
}
</script>
<style lang="less" scoped>
.beta-gamma-analysis {
height: 100%;
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>

View File

@ -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>

View File

@ -0,0 +1,158 @@
<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
>
</div>
<div class="beta-gamma-spectrum-chart-main">
<custom-chart ref="chartRef" :option="option" />
</div>
</div>
</template>
<script>
import CustomChart from '@/components/CustomChart/index.vue'
const buttons = ['2D', '3D Surface', '3D Scatter', 'Unzoom']
const option = {
visualMap: [{
min: 0,
max: 256,
calculable: true,
orient: 'vertical',
right: 0,
top: 0,
bottom: 0,
inRange: {
color: ['#fff', '#f00']
}
}],
grid: {
top: 15,
left: 55,
right: 40,
bottom: 45
},
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,
data: new Array(256).fill(0).map((_, index) => index)
},
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,
data: new Array(256).fill(0).map((_, index) => index)
},
series: {
type: 'scatter',
symbolSize: 2,
data: new Array(256).fill(0).map(() => [parseInt(Math.random() * 256), parseInt(Math.random() * 256)])
}
}
export default {
components: {
CustomChart
},
data() {
this.buttons = buttons
return {
active: 0,
option
}
},
methods: {
handleChange(index) {
this.active = index
},
resize() {
this.$refs.chartRef.resize()
}
}
}
</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;
&.active {
background-color: #1397a3;
}
}
}
&-main {
height: calc(100% - 26px);
}
}
</style>

View File

@ -0,0 +1,209 @@
<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-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>

View File

@ -0,0 +1,143 @@
<template>
<div class="spectrum-line-chart">
<div class="title">{{ title + ' Count'}}</div>
<custom-chart class="spectrum-line-chart-main" ref="chartRef" :option="option" style="height: 100%"></custom-chart>
</div>
</template>
<script>
import CustomChart from '@/components/CustomChart/index.vue'
import { cloneDeep } from 'lodash'
const initialOption = {
grid: {
top: 25,
right: 0,
bottom: 40
},
title: {
text: '',
left: 'right',
top: 0,
textStyle: {
color: '#ade6ee',
fontSize: 12,
rich: {
a: {
padding: [0, 27, 0, 0]
},
b: {
color: '#ff5656'
}
}
}
},
xAxis: {
type: 'category',
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,
data: new Array(256).fill(0).map((_, index) => index)
},
yAxis: {
axisLine: {
show: true,
lineStyle: {
color: 'rgb(119, 181, 213, 0.5)'
}
},
splitLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .2)'
}
},
axisLabel: {
color: '#ade6ee'
}
},
series: {
type: 'line',
itemStyle: {
color: ''
},
symbol: 'none',
data: new Array(256)
.fill(0)
.map((_, index) => (Math.random() < 0.05 ? parseInt(Math.random() * 19644) : parseInt(Math.random() * 800)))
}
}
export default {
components: {
CustomChart
},
props: {
color: {
type: String,
default: 'red'
},
title: {
type: String,
default: 'Gamma'
}
},
data() {
const option = cloneDeep(initialOption)
option.title.text = `{a|Channel: 136}{a|Count: 1475}{b|Energy: 381.409}`
option.series.itemStyle.color = this.color
option.xAxis.name = this.title + ' Channel'
return {
option
}
},
methods: {
resize() {
this.$refs.chartRef && this.$refs.chartRef.resize()
}
}
}
</script>
<style lang="less" scoped>
.spectrum-line-chart {
display: flex;
height: 100%;
.title {
writing-mode: vertical-rl;
color: #5b9cba;
font-size: 16px;
transform: rotate(180deg);
text-align: center;
user-select: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&-main {
flex: 1;
}
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<div class="btn-with-switch-icon">
<img src="@/assets/images/spectrum/left-arrow.png" @click="handleClick('left')" />
<span>
<slot></slot>
</span>
<img src="@/assets/images/spectrum/right-arrow.png" @click="handleClick('right')" />
</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 12px;
height: 100%;
letter-spacing: 1px;
color: #ade6ee;
span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0 5px;
}
img {
cursor: pointer;
}
}
</style>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,64 @@
<template>
<a-popover :placement="placement" overlayClassName="popover-with-icon">
<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'
}
}
}
</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>

View File

@ -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>

View File

@ -0,0 +1,14 @@
<template>
<div class="spectra">
spectra
</div>
</template>
<script>
export default {}
</script>
<style lang="less" scoped>
.spectra {
}
</style>

View File

@ -0,0 +1,271 @@
<template>
<div class="gamma-analysis">
<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>
</template>
<script>
import CustomChart from '@/components/CustomChart/index.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
},
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()
},
/**
* 向某一个方向移动标记线
* @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%;
position: relative;
&-chart {
height: 100%;
}
&-thumbnail {
position: absolute;
top: 50px;
right: 10px;
width: 500px;
height: 150px;
background-color: #153E44;
}
}
</style>

View File

@ -1,3 +1,345 @@
<template>
<div>能谱分析页面</div>
<div class="spectrum-analysis">
<!-- 顶部操作栏 -->
<div class="spectrum-analysis-operators">
<a-dropdown class="spectrum-analysis-operators-item" v-for="operation in operations" :key="operation.title">
<a-button type="primary">{{ operation.title }}</a-button>
<template slot="overlay">
<a-menu>
<a-menu-item v-for="child in operation.children" :key="child.title" @click="child.handler">
{{ child.title }}
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</div>
<!-- 顶部操作栏结束 -->
<!-- 二级交互栏 -->
<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>
<!-- gamma 独有的二级交互栏 -->
<template v-if="analysisType == ANALYZE_TYPE.GAMMA">
<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>
</template>
<!-- gamma 独有的二级交互栏结束 -->
<!-- beta-gamma 独有的二级交互栏 -->
<template v-if="analysisType == ANALYZE_TYPE.BETA_GAMMA">
<pop-over-with-icon placement="bottomLeft" style="width: 159px">
Spectra
<spectra slot="content" />
</pop-over-with-icon>
</template>
<!-- beta-gamma 独有的二级交互栏结束 -->
</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" />
<resize-observer @notify="handleResize" />
</div>
<!-- 频谱分析部分结束 -->
</div>
</template>
<script>
import ButtonWithSwitchIcon from './components/sub-operators/ButtonWithSwitchIcon.vue'
import DetailedInfomation from './components/sub-operators/DetailedInfomation.vue'
import GraphAssistance from './components/sub-operators/GraphAssistance.vue'
import NuclearLibrary from './components/sub-operators/NuclearLibrary.vue'
import PopOverWithIcon from './components/sub-operators/PopOverWithIcon.vue'
import QcFlags from './components/sub-operators/QcFlags.vue'
import GammaAnalysis from './gamma-analysis.vue'
import BetaGammaAnalysis from './beta-gamma-analysis.vue'
import Spectra from './components/sub-operators/Spectra.vue'
//
const ANALYZE_TYPE = {
GAMMA: 'gammaAnalysis',
BETA_GAMMA: 'betaGammaAnalysis'
}
export default {
components: {
PopOverWithIcon,
ButtonWithSwitchIcon,
BetaGammaAnalysis,
GammaAnalysis,
QcFlags,
GraphAssistance,
DetailedInfomation,
NuclearLibrary,
Spectra
},
data() {
this.ANALYZE_TYPE = ANALYZE_TYPE
return {
analysisType: ANALYZE_TYPE.BETA_GAMMA //
}
},
methods: {
handleLoadFromDb() {
console.log('%c [ handleLoadFromDb ]-46', 'font-size:13px; background:pink; color:#bf2c9f;')
},
handleLoadFromFile() {
console.log('%c [ handleLoadFromFile ]-46', 'font-size:13px; background:pink; color:#bf2c9f;')
},
// peak info
handlePeakInfoChange(direction) {
this.$refs.gammaAnalysisRef.moveMarkLine(direction)
},
handleResize() {
this.$refs.gammaAnalysisRef && this.$refs.gammaAnalysisRef.resize()
this.$refs.betaGammaAnalysisRef && this.$refs.betaGammaAnalysisRef.resize()
}
},
computed: {
operations() {
return [
{
title: 'SAMPLE',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'SAVE',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'ANALYZE',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'CALIBRATION',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'NUCLIDELIBRARY',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'COMMENTS',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'REPORTS',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'LOG',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
},
{
title: 'HELP',
children: [
{
title: 'Load From DB',
handler: this.handleLoadFromDb
},
{
title: 'Load From File',
handler: this.handleLoadFromFile
}
]
}
]
}
}
}
</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;
}
}
}
//
//
&-sub-operators {
flex-shrink: 0;
margin-top: 15px;
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 {
flex: 1;
margin-top: 19px;
height: calc(100% - 100px);
}
//
}
</style>