AnalysisSystemForRadionucli.../src/views/spectrumAnalysis/components/SpectrumLineChart.vue

329 lines
6.9 KiB
Vue
Raw Normal View History

2023-06-28 19:25:11 +08:00
<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>
2023-07-06 19:40:48 +08:00
</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"
2023-07-06 19:40:48 +08:00
@brushEnd="handleBrushEnd"
></custom-chart>
</div>
<div class="bottom-title">
{{ title + ' Channel' }}
</div>
2023-06-28 19:25:11 +08:00
</div>
</template>
<script>
import CustomChart from '@/components/CustomChart/index.vue'
import { cloneDeep } from 'lodash'
import { getXAxisAndYAxisByPosition } from '@/utils/chartHelper.js'
2023-06-28 19:25:11 +08:00
const initialOption = {
grid: {
2023-07-06 19:40:48 +08:00
top: 10,
right: 15,
bottom: 20
2023-06-28 19:25:11 +08:00
},
xAxis: {
min: 0,
max: 256,
interval: 64,
2023-06-28 19:25:11 +08:00
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
2023-06-28 19:25:11 +08:00
},
yAxis: {
min: 0,
max: 0,
interval: 0,
2023-06-28 19:25:11 +08:00
axisLine: {
show: true,
lineStyle: {
color: 'rgb(119, 181, 213, 0.5)'
}
},
splitLine: {
lineStyle: {
color: 'rgba(119, 181, 213, .2)'
}
},
2023-07-06 19:40:48 +08:00
axisTick: {
show: false
},
2023-06-28 19:25:11 +08:00
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: []
}
2023-07-06 19:40:48 +08:00
},
brush: {}
2023-06-28 19:25:11 +08:00
}
export default {
components: {
CustomChart
},
props: {
color: {
type: String,
default: 'red'
},
title: {
type: String,
default: 'Gamma'
},
data: {
type: Array,
default: () => []
},
energy: {
type: Array,
default: () => []
2023-06-28 19:25:11 +08:00
}
},
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
}
2023-06-28 19:25:11 +08:00
}
},
2023-07-06 19:40:48 +08:00
mounted() {
this.option.brush = { toolbox: [] }
},
2023-06-28 19:25:11 +08:00
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
}
const energy = this.energy[xAxis]
if(energy) {
this.summary.energy = energy[0].toFixed(3)
}
} else {
this.option.series.markLine.data = []
this.summary.channel = 0
this.summary.count = 0
this.summary.energy = 0
}
}, 0)
},
2023-07-06 19:40:48 +08:00
// 设置范围
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)
2023-07-06 19:40:48 +08:00
},
// 鼠标按下时开启可刷选状态
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)
},
2023-07-06 19:40:48 +08:00
// 刷选完毕时
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)
2023-06-28 19:25:11 +08:00
}
},
watch: {
data: {
handler(newVal) {
this.option.series.data = newVal.map(({ x, y }) => [x, y])
const max = Math.max(...newVal.map(item => item.y))
const interval = Math.ceil((max / 4) * 1.1)
this.option.yAxis.interval = interval
this.option.yAxis.max = interval * 4
},
immediate: true
}
2023-06-28 19:25:11 +08:00
}
}
</script>
<style lang="less" scoped>
.spectrum-line-chart {
height: 100%;
.summary-text {
2023-07-06 19:40:48 +08:00
line-height: 10px;
text-align: right;
font-size: 14px;
user-select: none;
2023-07-06 19:40:48 +08:00
.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;
}
2023-06-28 19:25:11 +08:00
}
2023-07-06 19:40:48 +08:00
.bottom-title {
line-height: 10px;
font-size: 14px;
color: #5b9cba;
text-align: center;
user-select: none;
2023-06-28 19:25:11 +08:00
}
}
</style>