diff --git a/src/utils/chartHelper.js b/src/utils/chartHelper.js index 6560aae..e6cb5f0 100644 --- a/src/utils/chartHelper.js +++ b/src/utils/chartHelper.js @@ -104,4 +104,14 @@ export function rangeNumber(min, max) { return num => { return num > max ? max : num < min ? min : num } +} + +/** + * 获取图表某条轴线的最大值 + * @param {import("echarts").ECharts} chartInstance + * @param {'xAxis' | 'yAxis'} axis + * @returns + */ +export function getAxisMax(chartInstance, axis) { + return chartInstance.getModel().getComponent(axis).axis.scale._extent[1] } \ No newline at end of file diff --git a/src/views/spectrumAnalysis/gamma-analysis.vue b/src/views/spectrumAnalysis/gamma-analysis.vue index b2a957c..dd7374b 100644 --- a/src/views/spectrumAnalysis/gamma-analysis.vue +++ b/src/views/spectrumAnalysis/gamma-analysis.vue @@ -106,7 +106,13 @@ import NuclideLibrary from './components/SubOperators/NuclideLibrary.vue' import ButtonWithSwitchIcon from './components/SubOperators/ButtonWithSwitchIcon.vue' import { getAction, postAction } from '@/api/manage' import Response from './response.json' -import { buildLineSeries, findSeriesByName, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper' +import { + buildLineSeries, + findSeriesByName, + getAxisMax, + getXAxisAndYAxisByPosition, + rangeNumber, +} from '@/utils/chartHelper' import { cloneDeep } from 'lodash' import axios from 'axios' import NuclideReviewModal from './components/Modals/AnalyzeInteractiveToolModal/components/NuclideReviewModal.vue' @@ -256,6 +262,7 @@ const thumbnailOption = { const graphAssistance = { axisType: 'Channel', + spectrumType: 'Lines', Baseline: true, SCAC: true, Lc: true, @@ -462,6 +469,7 @@ export default { shadowChannelChart.pointlist && shadowChannelChart.pointlist.map(({ x, y }) => [x, y]), shadowChannelChart.color, { + symbolSize: 2, markLine: { silent: true, symbol: 'none', @@ -576,6 +584,7 @@ export default { }) series.push(...peakLines) + // 推入Compare Line series.push( buildLineSeries('Compare', [], '#fff', { symbolSize: 2, @@ -606,6 +615,8 @@ export default { // Graph Assistance 操作 handleGraphAssistanceChange({ type, label, value }) { + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum') const compareLineSeries = findSeriesByName(this.option.series, 'Compare') // 类型变化 @@ -651,24 +662,35 @@ export default { this.redrawLineBySeriesName('Compare', this.energyCompareLine, this.channelCompareLine) break case 'Lines': - this.option.series[0].type = 'line' - this.option.series[0].symbol = 'none' + this.graphAssistance.spectrumType = 'Lines' - this.thumbnailOption.series[0].type = 'line' - this.thumbnailOption.series[0].symbol = 'none' + spectrumLineSeries.type = 'line' + spectrumLineSeries.symbol = 'none' + + thumbnailSpectrumLineSeries.type = 'line' + thumbnailSpectrumLineSeries.symbol = 'none' compareLineSeries.type = 'line' compareLineSeries.symbol = 'none' + + this.redrawLineBySeriesName('Spectrum', this.shadowEnergyChart, this.shadowChannelChart) + this.redrawLineBySeriesName('Compare', this.energyCompareLine, this.channelCompareLine) break case 'Scatter': - this.option.series[0].type = 'scatterGL' - this.option.series[0].symbol = 'circle' + this.graphAssistance.spectrumType = 'Scatter' - this.thumbnailOption.series[0].type = 'scatterGL' - this.thumbnailOption.series[0].symbol = 'circle' + spectrumLineSeries.type = 'scatterGL' + spectrumLineSeries.symbol = 'circle' + + thumbnailSpectrumLineSeries.type = 'scatterGL' + thumbnailSpectrumLineSeries.symbol = 'circle' compareLineSeries.type = 'scatterGL' compareLineSeries.symbol = 'circle' + + this.$nextTick(() => { + this.rangeScatter() + }) break } } @@ -680,9 +702,9 @@ export default { case 'Cursor': // 显示红色竖线 if (value) { - this.option.series[0].markLine.lineStyle.width = 2 + spectrumLineSeries.markLine.lineStyle.width = 2 } else { - this.option.series[0].markLine.lineStyle.width = 0 + spectrumLineSeries.markLine.lineStyle.width = 0 } break case 'Baseline': @@ -758,7 +780,7 @@ export default { // 重绘右上角的缩略图 redrawThumbnailChart() { - const series = this.thumbnailOption.series[0] + const series = findSeriesByName(this.thumbnailOption.series, 'Spectrum') const data = this.isEnergy() ? this.shadowEnergyChart : this.shadowChannelChart series.data = data.pointlist.map(({ x, y }) => [x, y]) }, @@ -766,10 +788,11 @@ export default { // 点击图表,设置红线 handleChartClick(param) { const { offsetX, offsetY } = param - const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY) + const point = getXAxisAndYAxisByPosition(this.getChart(), offsetX, offsetY) if (point) { const xAxis = point[0] - this.option.series[0].markLine.data[0].xAxis = xAxis + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + spectrumLineSeries.markLine.data[0].xAxis = xAxis const channel = this.isEnergy() ? this.getChannelByEnergy(xAxis) : parseInt(xAxis.toFixed()) const energy = this.isEnergy() @@ -834,7 +857,8 @@ export default { // 触发Peak Infomation handleTogglePeak() { - const xAxis = this.option.series[0].markLine.data[0].xAxis + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + const xAxis = spectrumLineSeries.markLine.data[0].xAxis const channel = this.isEnergy() ? this.getChannelByEnergy(xAxis) : parseInt(xAxis.toFixed()) const index = this.channelPeakGroup.findIndex((peakItem) => { const allX = peakItem.pointlist.map((item) => item.x) @@ -864,9 +888,7 @@ export default { return prev && prev.y > curr.y ? prev : curr }) - const chart = this.$refs.chartRef.getChartInstance() - - const [xPix, yPix] = chart.convertToPixel({ seriesIndex: 0 }, [x, y]) + const [xPix, yPix] = this.getChart().convertToPixel({ seriesIndex: 0 }, [x, y]) this.peakInfomationTooltip.content = html this.peakInfomationTooltip.visible = true this.peakInfomationTooltip.left = xPix @@ -889,7 +911,8 @@ export default { * @param { 'left'| 'right' } direction */ moveMarkLine(direction) { - const prevAxis = this.option.series[0].markLine.data[0].xAxis + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + const prevAxis = spectrumLineSeries.markLine.data[0].xAxis // 获取每一段 Channel 中的最大值 const maxXAxises = this.channelPeakGroup.map((item) => { @@ -903,13 +926,13 @@ export default { // 找到第一个比prevAxis大的xAxis find = maxXAxises.find((xAxis) => xAxis > prevAxis) if (find) { - this.option.series[0].markLine.data[0].xAxis = find + spectrumLineSeries.markLine.data[0].xAxis = find } } else if (direction == 'left') { // 找到第一个比prevAxis小的xAxis find = maxXAxises.reverse().find((xAxis) => xAxis < prevAxis) if (find) { - this.option.series[0].markLine.data[0].xAxis = find + spectrumLineSeries.markLine.data[0].xAxis = find } } @@ -920,8 +943,7 @@ export default { // 鼠标按下时开启可刷选状态 handleMouseDown() { - const chart = this.$refs.chartRef.getChartInstance() - chart.dispatchAction({ + this.getChart().dispatchAction({ type: 'takeGlobalCursor', // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。 key: 'brush', @@ -934,8 +956,7 @@ export default { handleMouseUp() { setTimeout(() => { - const chart = this.$refs.chartRef.getChartInstance() - this.clearBrush(chart) + this.clearBrush(this.getChart()) }, 0) }, @@ -965,7 +986,7 @@ export default { 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 xAxisMax = chart.getModel().getComponent('xAxis').axis.scale._extent[1] + const xAxisMax = getAxisMax(chart, 'xAxis') const yAxisMax = this.option.yAxis.max let [x1, y2, x2, y1] = [...point1, ...point2] // 根据解析出的数据确定真实的范围 @@ -992,7 +1013,7 @@ export default { this.setThumbnailChartRect(x1, y2, x2, y1) } - const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance() + const thumbnailChart = this.getThumbnailChart() const [, maxYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y1]) // 方框的上下两条边的yAxis转为pix const [, minYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y2]) const rectHeightPixel = maxYPixel - minYPixel // 计算方框的左右边长(pix) @@ -1000,13 +1021,72 @@ export default { } this.clearBrush(chart) + + this.$nextTick(() => { + this.rangeScatter() + }) + }, + + /** + * 因scatterGL 不受axis中max和min的控制,手动处理溢出部分 + * @param {*} x1 xAxis min + * @param {*} x2 xAxis max + * @param {*} y1 yAxis min + * @param {*} y2 yAxis max + */ + rangeScatter() { + if (!this.isScatter()) { + return + } + + const { + xAxis: { min: x1 }, + yAxis: { min: y1 }, + } = this.option + + const chart = this.getChart() + const x2 = getAxisMax(chart, 'xAxis') + const y2 = getAxisMax(chart, 'yAxis') + + const channelSpectrumData = { + ...this.shadowChannelChart, + pointlist: this.pointlistLimit(this.shadowChannelChart.pointlist, x1, x2, y1, y2), + } + const energySpectrumData = { + ...this.shadowEnergyChart, + pointlist: this.pointlistLimit(this.shadowEnergyChart.pointlist, x1, x2, y1, y2), + } + this.redrawLineBySeriesName('Spectrum', energySpectrumData, channelSpectrumData) + + const channelCompareLine = { + ...this.channelCompareLine, + pointlist: this.pointlistLimit(this.channelCompareLine.pointlist, x1, x2, y1, y2), + } + const energyCompareLine = { + ...this.energyCompareLine, + pointlist: this.pointlistLimit(this.energyCompareLine.pointlist, x1, x2, y1, y2), + } + this.redrawLineBySeriesName('Compare', energyCompareLine, channelCompareLine) + }, + + /** + * 筛选范围内的点 + * @param {*} pointlist + * @param {*} x1 + * @param {*} x2 + * @param {*} y1 + * @param {*} y2 + */ + pointlistLimit(pointlist, x1, x2, y1, y2) { + return pointlist.filter(({ x, y }) => x >= x1 && x <= x2 && y >= y1 && y <= y2) }, // 在右上角缩略图中设置范围 setThumbnailChartRect(x1, y2, x2, y1) { this.thumbnailChartRect = [x1, y2, x2, y1] - const { markLine } = this.thumbnailOption.series[0] + const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum') + const { markLine } = thumbnailSpectrumLineSeries const pointList = [ [ [x1, y1], @@ -1034,7 +1114,7 @@ export default { // 缩略图点击 handleThumbnailChartClick(param) { const { offsetX, offsetY } = param - const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance() + const thumbnailChart = this.getThumbnailChart() const point = getXAxisAndYAxisByPosition(thumbnailChart, offsetX, offsetY) if (point && this.thumbnailChartRect && this.thumbnailChartRect.length) { @@ -1046,7 +1126,7 @@ export default { let [xAxis, yAxis] = point - const xAxisMax = thumbnailChart.getModel().getComponent('xAxis').axis.scale._extent[1] + const xAxisMax = getAxisMax(thumbnailChart, 'xAxis') const xAxisLimit = rangeNumber(1 + halfWidth, xAxisMax - halfWidth) @@ -1081,14 +1161,22 @@ export default { // 重置 handleReset() { - this.option.xAxis.min = 1 - this.option.xAxis.max = 'dataMax' - this.option.yAxis.min = 1 - this.option.yAxis.max = 'dataMax' + const spectrumLineMaxX = Math.max(...this.shadowChannelChart.pointlist.map(({ x }) => x)) + const spectrumLineMaxY = Math.max(...this.shadowChannelChart.pointlist.map(({ y }) => y)) - this.thumbnailOption.series[0].markLine.data = [] + this.option.xAxis.min = 1 + this.option.xAxis.max = spectrumLineMaxX + this.option.yAxis.min = 1 + this.option.yAxis.max = spectrumLineMaxY + + const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum') + thumbnailSpectrumLineSeries.markLine.data = [] this.thumbnailChartRect = [] this.closePeakInfomationTooltip() + + this.$nextTick(() => { + this.rangeScatter() + }) }, // 从分析工具刷新部分数据 @@ -1120,13 +1208,12 @@ export default { this.energyCompareLine = energyData this.redrawLineBySeriesName('Compare', energyData, channelData, true, channelData.color) - if (this.option.series[0].type == 'scatterGL') { + if (this.isScatter()) { lineSeries.type = 'scatterGL' } this.$nextTick(() => { - const chart = this.$refs.chartRef.getChartInstance() - const yAxisMax = chart.getModel().getComponent('yAxis').axis.scale._extent[1] + const yAxisMax = getAxisMax(this.getChart(), 'yAxis') this.thumbnailOption.yAxis.max = yAxisMax }) }, @@ -1231,14 +1318,16 @@ export default { this.option.yAxis.type = 'value' if (this.option.series.length) { - this.option.series[0].type = 'line' - this.option.series[0].symbol = 'none' - this.option.series[0].markLine.lineStyle.width = 2 + const spectrumLineSeries = findSeriesByName(this.option.series, 'Spectrum') + spectrumLineSeries.type = 'line' + spectrumLineSeries.symbol = 'none' + spectrumLineSeries.markLine.lineStyle.width = 2 } if (this.thumbnailOption.series.length) { - this.thumbnailOption.series[0].type = 'line' - this.thumbnailOption.series[0].symbol = 'none' + const thumbnailSpectrumLineSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum') + thumbnailSpectrumLineSeries.type = 'line' + thumbnailSpectrumLineSeries.symbol = 'none' } this.graphAssistance = cloneDeep(graphAssistance) }, @@ -1310,6 +1399,18 @@ export default { isEnergy() { return this.graphAssistance.axisType == 'Energy' }, + + isScatter() { + return this.graphAssistance.spectrumType == 'Scatter' + }, + + getChart() { + return this.$refs.chartRef.getChartInstance() + }, + + getThumbnailChart() { + return this.$refs.thumbnailChartRef.getChartInstance() + }, }, watch: { sample: {