2023-06-28 19:25:11 +08:00
|
|
|
<template>
|
|
|
|
<div class="spectrum-line-chart">
|
2023-07-07 17:44:20 +08:00
|
|
|
<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"
|
2023-07-07 17:44:20 +08:00
|
|
|
@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'
|
2023-07-04 19:46:38 +08:00
|
|
|
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: {
|
2023-06-29 17:43:15 +08:00
|
|
|
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'
|
|
|
|
},
|
2023-06-29 17:43:15 +08:00
|
|
|
nameGap: 25
|
2023-06-28 19:25:11 +08:00
|
|
|
},
|
|
|
|
yAxis: {
|
2023-06-29 17:43:15 +08:00
|
|
|
min: 0,
|
2023-07-11 19:35:18 +08:00
|
|
|
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',
|
2023-07-11 19:35:18 +08:00
|
|
|
data: [],
|
2023-07-04 19:46:38 +08:00
|
|
|
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'
|
2023-07-11 19:35:18 +08:00
|
|
|
},
|
|
|
|
data: {
|
|
|
|
type: Array,
|
|
|
|
default: () => []
|
2023-07-13 19:18:23 +08:00
|
|
|
},
|
|
|
|
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 {
|
2023-07-07 17:44:20 +08:00
|
|
|
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()
|
2023-07-04 19:46:38 +08:00
|
|
|
},
|
|
|
|
|
|
|
|
// 设置辅助线位置
|
|
|
|
setLinePosition(xAxis) {
|
|
|
|
setTimeout(() => {
|
|
|
|
if (xAxis) {
|
|
|
|
this.option.series.markLine.data = [{ xAxis }]
|
2023-07-07 17:44:20 +08:00
|
|
|
this.summary.channel = xAxis
|
2023-07-11 19:35:18 +08:00
|
|
|
const find = this.data.find(item => item.x == xAxis)
|
|
|
|
if (find) {
|
|
|
|
this.summary.count = find.y
|
|
|
|
}
|
2023-07-13 19:18:23 +08:00
|
|
|
const energy = this.energy[xAxis]
|
|
|
|
if(energy) {
|
|
|
|
this.summary.energy = energy[0].toFixed(2)
|
|
|
|
}
|
2023-07-04 19:46:38 +08:00
|
|
|
} else {
|
|
|
|
this.option.series.markLine.data = []
|
2023-07-07 17:44:20 +08:00
|
|
|
this.summary.channel = 0
|
|
|
|
this.summary.count = 0
|
|
|
|
this.summary.energy = 0
|
2023-07-04 19:46:38 +08:00
|
|
|
}
|
|
|
|
}, 0)
|
|
|
|
},
|
|
|
|
|
2023-07-06 19:40:48 +08:00
|
|
|
// 设置范围
|
|
|
|
setRange(min, max) {
|
|
|
|
this.option.xAxis.min = min
|
|
|
|
this.option.xAxis.max = max
|
|
|
|
},
|
|
|
|
|
|
|
|
// 鼠标在图表上移动时
|
2023-07-04 19:46:38 +08:00
|
|
|
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'
|
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
2023-07-07 17:44:20 +08:00
|
|
|
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
|
|
|
}
|
2023-07-11 19:35:18 +08:00
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
data: {
|
|
|
|
handler(newVal) {
|
|
|
|
this.option.series.data = newVal.map(({ x, y }) => [x, y])
|
|
|
|
|
2023-07-13 19:18:23 +08:00
|
|
|
const max = Math.max(...newVal.map(item => item.y)) * 1.1
|
2023-07-11 19:35:18 +08:00
|
|
|
this.option.yAxis.interval = Math.ceil(max / 4)
|
|
|
|
this.option.yAxis.max = this.option.yAxis.interval * 4
|
|
|
|
},
|
|
|
|
immediate: true
|
|
|
|
}
|
2023-06-28 19:25:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
.spectrum-line-chart {
|
|
|
|
height: 100%;
|
|
|
|
|
2023-07-07 17:44:20 +08:00
|
|
|
.summary-text {
|
2023-07-06 19:40:48 +08:00
|
|
|
line-height: 10px;
|
|
|
|
text-align: right;
|
|
|
|
font-size: 14px;
|
2023-07-07 17:44:20 +08:00
|
|
|
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;
|
2023-07-07 17:44:20 +08:00
|
|
|
user-select: none;
|
2023-06-28 19:25:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|