<template>
  <div class="gamma-analysis">
    <a-spin :spinning="isLoading">
      <!-- 二级交互栏 -->
      <div class="spectrum-analysis-sub-operators">
        <pop-over-with-icon placement="bottomLeft">
          Detailed-Information
          <detailed-infomation slot="content" :data="detailedInfomation" />
        </pop-over-with-icon>
        <pop-over-with-icon placement="bottomLeft">
          QC Flags
          <qc-flags slot="content" :data="qcFlags" />
        </pop-over-with-icon>
        <pop-over-with-icon>
          Graph Assistance
          <graph-assistance
            v-if="!isLoading"
            slot="content"
            @change="handleGraphAssistanceChange"
            @reset="handleReset"
          />
        </pop-over-with-icon>
        <pop-over-with-icon>
          Nuclide Library
          <nuclear-library slot="content" :list="nuclideLibraryList" />
        </pop-over-with-icon>
        <div class="peak-info">
          <button-with-switch-icon @change="handlePeakInfoChange" @click="handleTogglePeak"></button-with-switch-icon>
        </div>
      </div>
      <!-- 二级交互栏结束 -->
      <!-- 主体部分 -->
      <div class="gamma-analysis-main">
        <div class="gamma-analysis-chart">
          <CustomChart
            ref="chartRef"
            :option="option"
            :opts="opts"
            @zr:click="handleChartClick"
            @zr:mousedown="handleMouseDown"
            @zr:mouseup="handleMouseUp"
            @brushEnd="handleBrushEnd"
            style="height: 100%"
          />
          <!-- 右上角缩略图 -->
          <div class="gamma-analysis-thumbnail">
            <CustomChart
              ref="thumbnailChartRef"
              :option="thumbnailOption"
              @zr:click="handleThumbnailChartClick"
              style="height: 100%"
            />
          </div>
          <!-- 缩略图结束 -->

          <!-- 自定义tooltip，用于展示Peak Infomation -->
          <div
            v-if="peakInfomationTooltip.visible"
            class="peak-infomation-tooltip"
            :style="{
              top: peakInfomationTooltip.top + 'px',
              left: peakInfomationTooltip.left + 'px',
            }"
          >
            <div class="peak-infomation-tooltip-content" v-html="peakInfomationTooltip.content"></div>
          </div>
          <!-- tooltip结束 -->
        </div>
      </div>
      <!-- 主体部分结束 -->
    </a-spin>
  </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'
import { getAction } from '@/api/manage'
import Response from './response.json'
import { buildLineSeries, findSeriesByName, getXAxisAndYAxisByPosition, rangeNumber } from '@/utils/chartHelper'
import { cloneDeep } from 'lodash'
import axios from 'axios'

// 初始配置
const initialOption = {
  grid: {
    top: 40,
    left: 60,
    right: 50,
    containLabel: true,
  },
  title: {
    text: '',
    left: 'center',
    bottom: 10,
    textStyle: {
      color: '#8FD4F8',
      rich: {
        a: {
          padding: [0, 20, 0, 0],
          fontSize: 16,
        },
      },
    },
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      lineStyle: {
        color: '#3CAEBB',
        width: 1,
        type: 'solid',
      },
    },
    formatter: undefined,
    className: 'figure-chart-option-tooltip',
  },
  xAxis: {
    name: 'Channel',
    nameTextStyle: {
      color: '#8FD4F8',
      fontSize: 16,
      align: 'right',
      verticalAlign: 'top',
      padding: [30, 0, 0, 0],
    },
    axisLine: {
      lineStyle: {
        color: '#ade6ee',
      },
    },
    splitLine: {
      show: false,
    },
    axisLabel: {
      textStyle: {
        color: '#ade6ee',
      },
    },
    min: 1,
    max: 'dataMax',
    animation: false,
    axisLabel: {
      formatter: (value) => {
        return parseInt(value)
      },
    },
  },
  yAxis: {
    name: 'Counts',
    type: 'value',
    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',
      },
    },
    min: 1,
    max: 'dataMax',
    animation: false,
    axisLabel: {
      formatter: (value) => {
        return value.toFixed(1)
      },
    },
  },
  series: [],
  brush: {},
}

// 缩略图配置
const thumbnailOption = {
  grid: {
    top: 0,
    left: 5,
    right: 5,
    bottom: 0,
  },
  xAxis: {
    type: 'category',
    axisLine: {
      show: false,
    },
    splitLine: {
      show: false,
    },
    axisLabel: {
      show: false,
    },
    min: 1,
    max: 'dataMax',
  },
  yAxis: {
    type: 'value',
    axisLine: {
      show: false,
    },
    splitLine: {
      show: false,
    },
    axisLabel: {
      show: false,
    },
    min: 1,
    max: 'dataMax',
  },
  series: [],
}

const graphAssistance = {
  axisType: 'Channel',
  Baseline: true,
  SCAC: true,
  Lc: true,
}

export default {
  props: {
    sample: {
      type: Object,
    },
  },
  components: {
    CustomChart,
    PopOverWithIcon,
    DetailedInfomation,
    QcFlags,
    GraphAssistance,
    NuclearLibrary,
    ButtonWithSwitchIcon,
  },
  data() {
    return {
      isLoading: false,
      option: cloneDeep(initialOption),
      opts: {
        notMerge: false,
      },
      thumbnailOption: cloneDeep(thumbnailOption),

      detailedInfomation: [],
      qcFlags: [],
      graphAssistance: cloneDeep(graphAssistance),

      channelPeakGroup: [],
      energyPeakGroup: [],

      nuclideLibraryList: [], // 当前鼠标点击选中的channel
      peakInfomationTooltip: {
        // Peak Infomation的位置
        visible: false,
        content: '',
        top: 0,
        left: 0,
      },
    }
  },
  created() {
    this.option.title.text = '{a|Channel:0} {a|Energy:0} {a|Counts:0} {a|Detectability:0}'
    this.$bus.$on('colorChange', this.handleColorChange)
    this.$bus.$on('gammaRefresh', this.handleRefresh)
    this.$bus.$on('accept', this.handleAccept)
  },
  destroyed() {
    this.$bus.$off('colorChange', this.handleColorChange)
    this.$bus.$off('gammaRefresh', this.handleRefresh)
    this.$bus.$off('accept', this.handleAccept)
  },
  mounted() {
    this.option.brush = { toolbox: [] }
  },
  methods: {
    async getSampleDetail() {
      const { dbName, sampleId } = this.sample
      try {
        this.isLoading = true

        this.reset()

        // const { success, result, message } = Response

        if (this._cancelToken && typeof this._cancelToken == 'function') {
          this._cancelToken()
        }

        const cancelToken = new axios.CancelToken((c) => {
          this._cancelToken = c
        })

        const { success, result, message } = await getAction(
          '/gamma/gammaByDB',
          {
            dbName,
            sampleId,
          },
          cancelToken
        )
        console.log('%c [ result ]-243', 'font-size:13px; background:pink; color:#bf2c9f;', result)
        if (success) {
          this.dataProsess(result)
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      }
    },

    async getSampleDetail_file() {
      const { inputFileName: fileName } = this.sample
      try {
        this.isLoading = true
        this.option.series = []
        this.thumbnailOption.series = []
        // const { success, result, message } = Response
        const { success, result, message } = await getAction('/gamma/gammaByFile', {
          fileName,
        })
        console.log('%c [ result ]-243', 'font-size:13px; background:pink; color:#bf2c9f;', result)
        if (success) {
          this.dataProsess(result)
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      }
    },

    dataProsess(result) {
      this.isLoading = false

      const {
        dead_time,
        live_time,
        real_time,
        start_time,

        DetailedInformation,
        QCFlag,

        allData,

        shadowChannelChart,
        shadowEnergyChart,

        shapeChannelData,
        shapeEnergyData,
      } = result

      this.detailedInfomation = DetailedInformation
      this.qcFlags = QCFlag

      const channelPeakGroup = allData.filter((item) => item.name == 'Peak' && item.group == 'channel')
      const energyPeakGroup = allData.filter((item) => item.name == 'Peak' && item.group == 'energy')

      const channelBaseLine = allData.find((item) => item.name == 'BaseLine' && item.group == 'channel') || {}
      const energyBaseLine = allData.find((item) => item.name == 'BaseLine' && item.group == 'energy')

      const channelLcLine = allData.find((item) => item.name == 'Lc' && item.group == 'channel') || {}
      const energyLcLine = allData.find((item) => item.name == 'Lc' && item.group == 'energy')

      const channelScacLine = allData.find((item) => item.name == 'Scac' && item.group == 'channel') || {}
      const energyScacLine = allData.find((item) => item.name == 'Scac' && item.group == 'energy')

      this.allEnergy = allData.find((item) => item.name == 'Energy' && item.group == 'energy') || {}
      this.allChannel = allData.find((item) => item.name == 'Count' && item.group == 'channel')

      // 保存Peak Line
      this.channelPeakGroup = channelPeakGroup
      this.energyPeakGroup = energyPeakGroup

      // 保存 Spectrum Line
      this.shadowChannelChart = shadowChannelChart
      this.shadowEnergyChart = shadowEnergyChart

      // 保存基线
      this.channelBaseLine = channelBaseLine
      this.energyBaseLine = energyBaseLine

      // 保存Lc
      this.channelLcLine = channelLcLine
      this.energyLcLine = energyLcLine

      // 保存Scac
      this.channelScacLine = channelScacLine
      this.energyScacLine = energyScacLine

      // 保存 基线控制点
      this.shapeChannelData = shapeChannelData
      this.shapeEnergyData = shapeEnergyData

      this.option.yAxis.max =
        shadowChannelChart.pointlist && Math.ceil(Math.max(...shadowChannelChart.pointlist.map((item) => item.y)) * 1.1)
      this.thumbnailOption.yAxis.max =
        shadowChannelChart.pointlist && Math.ceil(Math.max(...shadowChannelChart.pointlist.map((item) => item.y)) * 1.1)

      const series = []

      // 推入Spectrum Line
      series.push(
        buildLineSeries(
          'Spectrum',
          shadowChannelChart.pointlist && shadowChannelChart.pointlist.map(({ x, y }) => [x, y]),
          shadowChannelChart.color,
          {
            markLine: {
              silent: true,
              symbol: 'none',
              label: {
                show: false,
              },
              lineStyle: {
                color: 'red',
                width: 1,
              },
              data: [{ xAxis: -1 }],
            },
          }
        )
      )

      // 右上角缩略图推入Spectrum Line
      this.thumbnailOption.series.push(
        buildLineSeries(
          'Spectrum',
          shadowChannelChart.pointlist && shadowChannelChart.pointlist.map(({ x, y }) => [x, y]),
          shadowChannelChart.color,
          {
            silent: true,
            markLine: {
              silent: true,
              symbol: 'none',
              label: {
                show: false,
              },
              lineStyle: {
                type: 'solid',
                color: '#1397a3',
                width: 1,
              },
              data: [],
            },
          }
        )
      )

      // 推入BaseLine
      series.push(
        buildLineSeries(
          'BaseLine',
          channelBaseLine.pointlist && channelBaseLine.pointlist.map(({ x, y }) => [x, y]),
          channelBaseLine.color,
          {
            zlevel: 2,
          }
        )
      )

      // 推入LcLine线
      series.push(
        buildLineSeries(
          'LcLine',
          channelLcLine.pointlist && channelLcLine.pointlist.map(({ x, y }) => [x, y]),
          channelLcLine.color,
          {
            zlevel: 3,
          }
        )
      )

      // 推入Scac线
      series.push(
        buildLineSeries(
          'ScacLine',
          channelScacLine.pointlist && channelScacLine.pointlist.map(({ x, y }) => [x, y]),
          channelScacLine.color,
          {
            zlevel: 4,
          }
        )
      )

      // 推入基线控制点
      series.push({
        name: 'BaseLine_Ctrl_Point',
        type: 'scatter',
        data: shapeChannelData.map(({ size, color, point: { x, y } }) => {
          return {
            value: [x, y],
            itemStyle: {
              color: 'transparent',
              borderColor: color,
              borderWidth: size / 2,
            },
          }
        }),
        emphasis: {
          disabled: true,
        },
        animation: false,
        zlevel: 5,
      })

      // 推入Peak Line
      const peakLines = []
      channelPeakGroup.forEach((item, index) => {
        peakLines.push(
          buildLineSeries(
            `Peak_${index}`,
            item.pointlist.map(({ x, y }) => [x, y]),
            item.color,
            {
              zlevel: 6,
            }
          )
        )
      })
      series.push(...peakLines)
      this.option.series = series

      this.option.tooltip.formatter = this.tooltipFormatter
    },

    tooltipFormatter(params) {
      if (this.isEnergy()) {
        const energy = params[0].value[0]
        const channel = this.getChannelByEnergy(energy)

        return `<div class="channel">Channel: ${channel}</div>
              <div class="energy">Energy: ${energy.toFixed(2)}</div>`
      } else {
        const channel = parseInt(params[0].value[0].toFixed())
        const energy = this.allEnergy.pointlist && this.allEnergy.pointlist[channel - 1]
        return energy
          ? `<div class="channel">Channel: ${channel}</div>
              <div class="energy">Energy: ${energy.x.toFixed(2)}</div>`
          : undefined
      }
    },

    // Graph Assistance 操作
    handleGraphAssistanceChange({ type, label, value }) {
      // 类型变化
      if (type == 'labelChange') {
        switch (label) {
          case 'Linear':
            this.option.yAxis.type = 'value'
            this.thumbnailOption.yAxis.type = 'value'
            this.handleReset()
            break
          case 'Log10':
            this.option.yAxis.type = 'log'
            this.thumbnailOption.yAxis.type = 'log'
            this.handleReset()
            break
          case 'Channel':
          case 'Energy':
            this.graphAssistance.axisType = label
            this.option.xAxis.name = label

            this.handleReset()

            this.redrawLineBySeriesName(
              'BaseLine',
              this.energyBaseLine,
              this.channelBaseLine,
              this.graphAssistance.Baseline
            )
            this.redrawLineBySeriesName('LcLine', this.energyLcLine, this.channelLcLine, this.graphAssistance.Lc)
            this.redrawLineBySeriesName(
              'ScacLine',
              this.energyScacLine,
              this.channelScacLine,
              this.graphAssistance.SCAC
            )

            this.redrawLineBySeriesName('Spectrum', this.shadowEnergyChart, this.shadowChannelChart)
            this.redrawCtrlPointBySeriesName()
            this.redrawPeakLine()

            this.redrawThumbnailChart()
            break
          case 'Lines':
            this.option.series[0].type = 'line'
            this.option.series[0].symbol = 'none'

            this.thumbnailOption.series[0].type = 'line'
            this.thumbnailOption.series[0].symbol = 'none'
            break
          case 'Scatter':
            this.option.series[0].type = 'scatterGL'
            this.option.series[0].symbol = 'circle'

            this.thumbnailOption.series[0].type = 'scatterGL'
            this.thumbnailOption.series[0].symbol = 'circle'
            break
        }
      }
      // 值变化
      else if (type == 'valueChange') {
        this.graphAssistance[label] = value

        switch (label) {
          case 'Cursor':
            // 显示红色竖线
            if (value) {
              this.option.series[0].markLine.lineStyle.width = 2
            } else {
              this.option.series[0].markLine.lineStyle.width = 0
            }
            break
          case 'Baseline':
            this.redrawLineBySeriesName('BaseLine', this.energyBaseLine, this.channelBaseLine, value)
            break
          case 'Lc':
            this.redrawLineBySeriesName('LcLine', this.energyLcLine, this.channelLcLine, value)
            break
          case 'SCAC':
            this.redrawLineBySeriesName('ScacLine', this.energyScacLine, this.channelScacLine, value)
            break
        }
      }
    },

    // 根据seriesName重绘线
    redrawLineBySeriesName(seriesName, energyData, channelData, isShow = true) {
      const series = findSeriesByName(this.option.series, seriesName)
      if (isShow) {
        const data = this.isEnergy() ? energyData : channelData
        series.data = data.pointlist.map(({ x, y }) => [x, y])
      } else {
        series.data = []
      }
    },

    // 重绘控制点
    redrawCtrlPointBySeriesName() {
      const series = findSeriesByName(this.option.series, 'BaseLine_Ctrl_Point')
      const data = this.isEnergy() ? this.shapeEnergyData : this.shapeChannelData
      series.data = data.map(({ size, color, point: { x, y } }) => {
        return {
          value: [x, y],
          itemStyle: {
            color: 'transparent',
            borderColor: color,
            borderWidth: size / 2,
          },
        }
      })
    },

    // 重绘Peak Line
    redrawPeakLine() {
      this.option.series = this.option.series.filter((item) => {
        return !item.name.includes('Peak_')
      })

      const data = this.isEnergy() ? this.energyPeakGroup : this.channelPeakGroup
      const peakLines = []
      data.forEach((item, index) => {
        peakLines.push(
          buildLineSeries(
            `Peak_${index}`,
            item.pointlist.map(({ x, y }) => [x, y]),
            item.color,
            {
              zlevel: 6,
            }
          )
        )
      })

      this.option.series.push(...peakLines)
    },

    // 重绘右上角的缩略图
    redrawThumbnailChart() {
      const series = this.thumbnailOption.series[0]
      const data = this.isEnergy() ? this.shadowEnergyChart : this.shadowChannelChart
      series.data = data.pointlist.map(({ x, y }) => [x, y])
    },

    // 点击图表，设置红线
    handleChartClick(param) {
      const { offsetX, offsetY } = param
      const point = getXAxisAndYAxisByPosition(this.$refs.chartRef.getChartInstance(), offsetX, offsetY)
      if (point) {
        const xAxis = point[0]
        this.option.series[0].markLine.data[0].xAxis = xAxis

        const channel = this.isEnergy() ? this.getChannelByEnergy(xAxis) : parseInt(xAxis.toFixed())
        const energy = this.isEnergy()
          ? xAxis.toFixed(2)
          : this.allEnergy.pointlist && this.allEnergy.pointlist[channel - 1].x.toFixed(2)
        const counts = this.isEnergy() ? this.allEnergy.pointlist[channel - 1] : this.allChannel.pointlist[channel - 1]
        this.option.title.text = `{a|Channel:${channel}} {a|Energy:${energy}} {a|Counts:${counts.y}} {a|Detectability:0}`

        this.getSelPosNuclide(channel)
      }
    },

    // 获取 Nuclide Library 数据
    async getSelPosNuclide(channel) {
      try {
        this.loading = true
        const { sampleId, inputFileName: fileName } = this.sample

        const { success, result, message } = await getAction('/gamma/getSelPosNuclide', {
          sampleId,
          channel,
          fileName,
        })
        if (success) {
          const { identify } = result
          this.nuclideLibraryList = identify
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        this.list = []
        console.error(error)
      } finally {
        this.loading = false
      }
    },

    resize() {
      this.$refs.chartRef.resize()
      this.$refs.thumbnailChartRef.resize()
      this.closePeakInfomationTooltip()
    },

    // peak info 点击左右方向
    handlePeakInfoChange(direction) {
      this.moveMarkLine(direction)
    },

    // 触发Peak Infomation
    handleTogglePeak() {
      const xAxis = this.option.series[0].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)
        const max = Math.max(...allX)
        const min = Math.min(...allX)
        return channel >= min && channel <= max
      })
      if (-1 !== index) {
        this.getPeakInfo(index)
      } else {
        this.closePeakInfomationTooltip()
      }
    },

    // 获取 Peak 峰顶 信息
    async getPeakInfo(index) {
      try {
        const { inputFileName: fileName } = this.sample
        const { success, result, message } = await getAction('/gamma/clickPeakInformation', {
          fileName,
          index,
        })
        if (success) {
          const html = result.replaceAll('\n', '<br>')
          const currPeak = this.channelPeakGroup[index]
          const { x, y } = currPeak.pointlist.reduce((prev, curr) => {
            return prev && prev.y > curr.y ? prev : curr
          })

          const chart = this.$refs.chartRef.getChartInstance()

          const [xPix, yPix] = chart.convertToPixel({ seriesIndex: 0 }, [x, y])
          this.peakInfomationTooltip.content = html
          this.peakInfomationTooltip.visible = true
          this.peakInfomationTooltip.left = xPix
          this.peakInfomationTooltip.top = yPix - 20
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      }
    },

    // 关闭Peak Infomation
    closePeakInfomationTooltip() {
      this.peakInfomationTooltip.visible = false
    },

    /**
     * 向某一个方向移动标记线
     * @param { 'left'| 'right' } direction
     */
    moveMarkLine(direction) {
      const prevAxis = this.option.series[0].markLine.data[0].xAxis

      // 获取每一段 Channel 中的最大值
      const maxXAxises = this.channelPeakGroup.map((item) => {
        const allY = item.pointlist.map((item) => item.y)
        const max = item.pointlist.find((point) => point.y == Math.max(...allY))
        return max.x
      })
      if (direction == 'right') {
        // 找到第一个比prevAxis大的xAxis
        const find = maxXAxises.find((xAxis) => xAxis > prevAxis)
        if (find) {
          this.option.series[0].markLine.data[0].xAxis = find
        }
      } else if (direction == 'left') {
        // 找到第一个比prevAxis小的xAxis
        const find = maxXAxises.reverse().find((xAxis) => xAxis < prevAxis)
        if (find) {
          this.option.series[0].markLine.data[0].xAxis = find
        }
      }
    },

    // 鼠标按下时开启可刷选状态
    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()
        this.clearBrush(chart)
      }, 0)
    },

    clearBrush(chart) {
      // 清理刷选的范围
      chart.dispatchAction({
        type: 'brush',
        areas: [],
      })

      // 改为不可刷选状态
      chart.dispatchAction({
        type: 'takeGlobalCursor',
      })
    },

    // 刷选完毕时
    handleBrushEnd(param) {
      this.closePeakInfomationTooltip()

      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 xAxisMax = chart.getModel().getComponent('xAxis').axis.scale._extent[1]
        const yAxisMax = this.option.yAxis.max

        let [x1, y2, x2, y1] = [...point1, ...point2] // 根据解析出的数据确定真实的范围

        const xAxisLimit = rangeNumber(1, xAxisMax)
        const yAxisLimit = rangeNumber(1, yAxisMax)

        x1 = xAxisLimit(x1)
        x2 = xAxisLimit(x2)

        y1 = yAxisLimit(y1)
        y2 = yAxisLimit(y2)

        this.option.xAxis.min = x1
        this.option.xAxis.max = x2
        this.option.yAxis.min = y1
        this.option.yAxis.max = y2

        if (this.isEnergy()) {
          const channel1 = this.getChannelByEnergy(x1)
          const channel2 = this.getChannelByEnergy(x2)
          this.setThumbnailChartRect(channel1, y2, channel2, y1)
        } else {
          this.setThumbnailChartRect(x1, y2, x2, y1)
        }

        const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance()
        const [, maxYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y1]) // 方框的上下两条边的yAxis转为pix
        const [, minYPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, y2])
        const rectHeightPixel = maxYPixel - minYPixel // 计算方框的左右边长(pix)
        this.halfHeightPixel = rectHeightPixel / 2
      }

      this.clearBrush(chart)
    },

    // 在右上角缩略图中设置范围
    setThumbnailChartRect(x1, y2, x2, y1) {
      this.thumbnailChartRect = [x1, y2, x2, y1]

      const { markLine } = this.thumbnailOption.series[0]
      const pointList = [
        [
          [x1, y1],
          [x2, y1],
        ],
        [
          [x2, y1],
          [x2, y2],
        ],
        [
          [x2, y2],
          [x1, y2],
        ],
        [
          [x1, y2],
          [x1, y1],
        ],
      ]
      const lines = pointList.map((point) => {
        return this.generateLineDataByTwoPoints(point[0], point[1])
      })
      markLine.data = lines
    },

    // 缩略图点击
    handleThumbnailChartClick(param) {
      const { offsetX, offsetY } = param
      const thumbnailChart = this.$refs.thumbnailChartRef.getChartInstance()

      const point = getXAxisAndYAxisByPosition(thumbnailChart, offsetX, offsetY)
      if (point && this.thumbnailChartRect && this.thumbnailChartRect.length) {
        const [x1, y2, x2, y1] = this.thumbnailChartRect
        const halfWidth = Math.ceil((x2 - x1) / 2)

        const [, maxYAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, this.thumbnailOption.yAxis.max]) // 缩略图最大值转为pix
        const [, minYAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, 1])

        let [xAxis, yAxis] = point

        const xAxisMax = thumbnailChart.getModel().getComponent('xAxis').axis.scale._extent[1]

        const xAxisLimit = rangeNumber(1 + halfWidth, xAxisMax - halfWidth)

        const halfHeightPixel = this.halfHeightPixel
        const yAxisLimit = rangeNumber(maxYAxisPixel + halfHeightPixel, minYAxisPixel - halfHeightPixel)

        xAxis = xAxisLimit(xAxis)

        let [, yAxisPixel] = thumbnailChart.convertToPixel({ seriesIndex: 0 }, [0, yAxis])
        yAxisPixel = yAxisLimit(yAxisPixel)

        const minYAxis = thumbnailChart.convertFromPixel({ seriesIndex: 0 }, [0, yAxisPixel + halfHeightPixel])[1] // 再把y轴最小值从pix转为yAxis
        const maxYAxis = thumbnailChart.convertFromPixel({ seriesIndex: 0 }, [0, yAxisPixel - halfHeightPixel])[1]

        this.setThumbnailChartRect(xAxis - halfWidth, maxYAxis, xAxis + halfWidth, minYAxis)

        if (this.isEnergy()) {
          const x1 = parseInt(this.shadowEnergyChart.pointlist[xAxis - halfWidth].x)
          const x2 = parseInt(this.shadowEnergyChart.pointlist[xAxis + halfWidth].x)

          this.option.xAxis.min = x1
          this.option.xAxis.max = x2
        } else {
          this.option.xAxis.min = xAxis - halfWidth
          this.option.xAxis.max = xAxis + halfWidth
        }

        this.option.yAxis.min = minYAxis
        this.option.yAxis.max = maxYAxis
      }
    },

    // 重置
    handleReset() {
      this.option.xAxis.min = 1
      this.option.xAxis.max = 'dataMax'
      this.option.yAxis.min = 1
      this.option.yAxis.max = Math.ceil(Math.max(...this.shadowChannelChart.pointlist.map((item) => item.y)) * 1.1)

      this.thumbnailOption.series[0].markLine.data = []
      this.thumbnailChartRect = []
      this.closePeakInfomationTooltip()
    },

    // 从分析工具刷新部分数据
    handleRefresh(data) {
      const { allData, shadowChannelChart, shadowEnergyChart, shapeChannelData, shapeEnergyData } = data

      const channelPeakGroup = allData.filter((item) => item.name == 'Peak' && item.group == 'channel')
      const energyPeakGroup = allData.filter((item) => item.name == 'Peak' && item.group == 'energy')

      const channelBaseLine = allData.find((item) => item.name == 'BaseLine' && item.group == 'channel')
      const energyBaseLine = allData.find((item) => item.name == 'BaseLine' && item.group == 'energy')

      const channelLcLine = allData.find((item) => item.name == 'Lc' && item.group == 'channel')
      const energyLcLine = allData.find((item) => item.name == 'Lc' && item.group == 'energy')

      const channelScacLine = allData.find((item) => item.name == 'Scac' && item.group == 'channel')
      const energyScacLine = allData.find((item) => item.name == 'Scac' && item.group == 'energy')

      this.allEnergy = allData.find((item) => item.name == 'Energy' && item.group == 'energy')
      this.allChannel = allData.find((item) => item.name == 'Count' && item.group == 'channel')

      // 保存Peak Line
      this.channelPeakGroup = channelPeakGroup
      this.energyPeakGroup = energyPeakGroup

      // 保存 Spectrum Line
      this.shadowChannelChart = shadowChannelChart
      this.shadowEnergyChart = shadowEnergyChart

      // 保存基线
      this.channelBaseLine = channelBaseLine
      this.energyBaseLine = energyBaseLine

      // 保存Lc
      this.channelLcLine = channelLcLine
      this.energyLcLine = energyLcLine

      // 保存Scac
      this.channelScacLine = channelScacLine
      this.energyScacLine = energyScacLine

      // 保存 基线控制点
      this.shapeChannelData = shapeChannelData
      this.shapeEnergyData = shapeEnergyData

      this.opts.notMerge = true
      this.redrawPeakLine()
      this.redrawCtrlPointBySeriesName()

      this.redrawLineBySeriesName('BaseLine', this.energyBaseLine, this.channelBaseLine, this.graphAssistance.Baseline)
      this.redrawLineBySeriesName('LcLine', this.energyLcLine, this.channelLcLine, this.graphAssistance.Lc)
      this.redrawLineBySeriesName('ScacLine', this.energyScacLine, this.channelScacLine, this.graphAssistance.SCAC)
      this.redrawLineBySeriesName('Spectrum', this.shadowEnergyChart, this.shadowChannelChart)

      this.redrawThumbnailChart()
      this.$nextTick(() => {
        this.resetChartOpts()
      })
    },

    // 分析工具Accept时刷新部分数据
    handleAccept() {
      console.log('%c [ 分析工具Accept时刷新部分数据 ]-1046', 'font-size:13px; background:pink; color:#bf2c9f;')
    },

    // 重置图表配置
    resetChartOpts() {
      this.opts.notMerge = false
      this.option.brush = { toolbox: [] }
    },

    /**
     * 根据两个点生成一个markLine直线
     */
    generateLineDataByTwoPoints(point1, point2) {
      return [
        {
          xAxis: point1[0],
          yAxis: point1[1],
        },
        {
          xAxis: point2[0],
          yAxis: point2[1],
        },
      ]
    },

    getChannelByEnergy(energy) {
      let channel = 0
      for (let index = 1; index < this.allEnergy.pointlist.length; index++) {
        const currEnergy = this.allEnergy.pointlist[index].x
        if (currEnergy >= energy) {
          const prevEnergy = this.allEnergy.pointlist[index - 1].x
          if (currEnergy - energy > energy - prevEnergy.x) {
            channel = index
          } else {
            channel = index + 1
          }
          break
        }
      }
      return channel
    },

    // 重置页面信息
    reset() {
      this.selectedChannel = -1
      this.nuclideLibraryList = []
      this.closePeakInfomationTooltip()
      this.option.series = []
      this.thumbnailOption.series = []
      this.option.xAxis.name = 'Channel'
      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
      }

      if (this.thumbnailOption.series.length) {
        this.thumbnailOption.series[0].type = 'line'
        this.thumbnailOption.series[0].symbol = 'none'
      }
      this.graphAssistance = cloneDeep(graphAssistance)
    },

    handleColorChange(colorConfig) {
      // 如果还没加载完，加载新的
      if (this.isLoading) {
        this.getSampleDetail()
      }
      // 否则修改已有颜色
      else {
        this.changeColor(colorConfig)
      }
    },

    // 修改颜色
    changeColor(colorConfig) {
      const { Color_Spec, Color_Peak, Color_Lc, Color_Base, Color_Scac, Color_Compare, Color_Strip, Color_Fitbase } =
        colorConfig

      this.shadowChannelChart.color = Color_Spec
      this.shadowEnergyChart.color = Color_Spec

      for (let i = 0; i < this.channelPeakGroup.length; i++) {
        this.channelPeakGroup[i].color = Color_Peak
        this.energyPeakGroup[i].color = Color_Peak
      }

      this.channelLcLine.color = Color_Lc
      this.energyLcLine.color = Color_Lc

      this.channelBaseLine.color = Color_Base
      this.energyBaseLine.color = Color_Base

      this.channelScacLine.color = Color_Scac
      this.energyScacLine.color = Color_Scac

      this.changeColorBySeriesName('Spectrum', Color_Spec)
      this.changePeakLineColor(Color_Peak)
      this.changeColorBySeriesName('LcLine', Color_Lc)
      this.changeColorBySeriesName('BaseLine', Color_Base)
      this.changeColorBySeriesName('ScacLine', Color_Scac)

      const thumbnailChartSeries = findSeriesByName(this.thumbnailOption.series, 'Spectrum')
      thumbnailChartSeries.itemStyle.color = Color_Spec
    },

    // 根据series名修改颜色
    changeColorBySeriesName(seriesName, color) {
      const series = findSeriesByName(this.option.series, seriesName)
      series.itemStyle.color = color
    },

    // 改变Peak的颜色
    changePeakLineColor(color) {
      this.option.series
        .filter((item) => item.name.includes('Peak_'))
        .forEach((item) => {
          item.itemStyle.color = color
        })
    },

    isEnergy() {
      return this.graphAssistance.axisType == 'Energy'
    },
  },
  watch: {
    sample: {
      handler(newVal, oldVal) {
        console.log('newValnewVal', newVal)
        if (newVal.sampleId) {
          this.getSampleDetail()
        } else {
          this.getSampleDetail_file()
        }
      },
      immediate: true,
    },
  },
}
</script>

<style lang="less" scoped>
.gamma-analysis {
  height: 100%;

  .ant-spin-nested-loading {
    height: 100%;

    ::v-deep {
      .ant-spin-container {
        height: 100%;
      }
    }
  }

  &-main {
    height: calc(100% - 51px);
    display: flex;
    overflow: auto hidden;
    position: relative;
  }

  &-chart {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
  }

  &-thumbnail {
    position: absolute;
    top: 50px;
    right: 10px;
    width: 500px;
    height: 20%;
    background-color: #153e44;
  }
}
</style>
<style lang="less">
.peak-infomation-tooltip {
  position: absolute;
  border-style: solid;
  white-space: nowrap;
  z-index: 9;
  box-shadow: rgba(0, 0, 0, 0.2) 1px 2px 10px;
  border-width: 1px;
  border-radius: 4px;
  padding: 10px;
  border-color: rgb(255, 255, 255);
  pointer-events: none;
  background-color: #55a9fe;
  border-color: #55a9fe;
}
</style>
