fix: beta图表中scatterGL盖住方框线的问题
This commit is contained in:
		
							parent
							
								
									d75ecd3017
								
							
						
					
					
						commit
						06d5776843
					
				| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
        <CustomChart
 | 
			
		||||
          ref="chartRef"
 | 
			
		||||
          :option="twoDOption"
 | 
			
		||||
          :opts="opts"
 | 
			
		||||
          @zr:mousemove="handleMouseMove"
 | 
			
		||||
          @zr:mousedown="handleMouseDown"
 | 
			
		||||
          @zr:mouseup="handleMouseUp"
 | 
			
		||||
| 
						 | 
				
			
			@ -132,24 +133,16 @@ const twoDOption = {
 | 
			
		|||
    max: 256,
 | 
			
		||||
    interval: 64
 | 
			
		||||
  },
 | 
			
		||||
  series: {
 | 
			
		||||
    type: 'scatterGL',
 | 
			
		||||
    symbolSize: 4,
 | 
			
		||||
    data: [],
 | 
			
		||||
    itemStyle: {
 | 
			
		||||
      color: '#fff'
 | 
			
		||||
    },
 | 
			
		||||
    markLine: {
 | 
			
		||||
      silent: true,
 | 
			
		||||
      symbol: 'none',
 | 
			
		||||
  series: [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'scatterGL',
 | 
			
		||||
      symbolSize: 4,
 | 
			
		||||
      data: [],
 | 
			
		||||
      animation: false,
 | 
			
		||||
      lineStyle: {
 | 
			
		||||
        type: 'solid',
 | 
			
		||||
        width: 2
 | 
			
		||||
      itemStyle: {
 | 
			
		||||
        color: '#fff'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  ],
 | 
			
		||||
  brush: {},
 | 
			
		||||
  animation: false
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -328,12 +321,19 @@ export default {
 | 
			
		|||
      twoDOption,
 | 
			
		||||
      threeDSurfaceOption,
 | 
			
		||||
      threeDScatterOption,
 | 
			
		||||
      showROI: true
 | 
			
		||||
      showROI: true,
 | 
			
		||||
      opts: {
 | 
			
		||||
        notMerge: false
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.twoDOption.brush = { toolbox: [] }
 | 
			
		||||
    this.opts.notMerge = true
 | 
			
		||||
    this.$nextTick(() => {
 | 
			
		||||
      this.opts.notMerge = false
 | 
			
		||||
      this.twoDOption.brush = { toolbox: [] }
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  methods: {
 | 
			
		||||
| 
						 | 
				
			
			@ -357,8 +357,6 @@ export default {
 | 
			
		|||
      this.twoDOption.yAxis.max = 256
 | 
			
		||||
 | 
			
		||||
      this.emitRangeChange([0, 256, 0, 256])
 | 
			
		||||
      this.reDrawRect()
 | 
			
		||||
 | 
			
		||||
      this.buildScatterList()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -436,9 +434,6 @@ export default {
 | 
			
		|||
        this.twoDOption.yAxis.max = rangeNumberFunc(y2)
 | 
			
		||||
 | 
			
		||||
        this.emitRangeChange([x1, x2, y1, y2])
 | 
			
		||||
 | 
			
		||||
        this.reDrawRect()
 | 
			
		||||
 | 
			
		||||
        this.buildScatterList()
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -452,14 +447,14 @@ export default {
 | 
			
		|||
        yAxis: { min: minY, max: maxY }
 | 
			
		||||
      } = this.twoDOption
 | 
			
		||||
 | 
			
		||||
      this.twoDOption.series.data = this.histogramDataDList
 | 
			
		||||
      this.twoDOption.series[0].data = this.histogramDataDList
 | 
			
		||||
        .filter(({ b, g, c }) => c && b >= minX && b <= maxX && g >= minY && g <= maxY)
 | 
			
		||||
        .map(({ b, g, c }) => this.buildScatterItem(b, g, c))
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 构造一个scatter 的点
 | 
			
		||||
    buildScatterItem(xAxis, yAxis, count) {
 | 
			
		||||
      const { r, g, b } = this.interpolateColor(1 - (count / this.currCount))
 | 
			
		||||
      const { r, g, b } = this.interpolateColor(1 - count / this.currCount)
 | 
			
		||||
      return {
 | 
			
		||||
        value: [xAxis, yAxis],
 | 
			
		||||
        itemStyle: {
 | 
			
		||||
| 
						 | 
				
			
			@ -488,7 +483,6 @@ export default {
 | 
			
		|||
        this.twoDOption.yAxis.max = x2
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.reDrawRect()
 | 
			
		||||
      this.buildScatterList()
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -498,217 +492,44 @@ export default {
 | 
			
		|||
 | 
			
		||||
      if (this.showROI) {
 | 
			
		||||
        this.boundaryData.forEach(({ minX, maxX, minY, maxY, color }) => {
 | 
			
		||||
          // rect 遵循 左下 右下 右上 左上 的顺序
 | 
			
		||||
          // rect 遵循 左下 右下 右上 左上 左下 的顺序
 | 
			
		||||
          const rect = [
 | 
			
		||||
            [minX, minY],
 | 
			
		||||
            [maxX, minY],
 | 
			
		||||
            [maxX, maxY],
 | 
			
		||||
            [minX, maxY]
 | 
			
		||||
            [minX, maxY],
 | 
			
		||||
            [minX, minY]
 | 
			
		||||
          ]
 | 
			
		||||
 | 
			
		||||
          rectList.push(...this.drawOneRect(rect, color))
 | 
			
		||||
          rectList.push(this.drawOneRect(rect, color))
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      this.twoDOption.series.markLine.data = rectList
 | 
			
		||||
      const lineSeries = rectList.map(rect => ({
 | 
			
		||||
        type: 'line',
 | 
			
		||||
        ...rect,
 | 
			
		||||
        zlevel: 11
 | 
			
		||||
      }))
 | 
			
		||||
 | 
			
		||||
      this.opts.notMerge = true
 | 
			
		||||
      this.twoDOption.series.splice(1, this.twoDOption.series.length - 1, ...lineSeries)
 | 
			
		||||
      this.$nextTick(() => {
 | 
			
		||||
        this.opts.notMerge = false
 | 
			
		||||
        this.twoDOption.brush = { toolbox: [] }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 绘制一个矩形框区域
 | 
			
		||||
     * 矩形框在这里的实现是由几条线段围起来的,但由于线段在超出图表区域显示有问题,故作了以下处理
 | 
			
		||||
     * @param {*} rect  左下 右下 右上 左上 的顺序
 | 
			
		||||
     * @param {*} rect  左下 右下 右上 左上 左下 的顺序
 | 
			
		||||
     */
 | 
			
		||||
    drawOneRect(rect, color) {
 | 
			
		||||
      const rectList = []
 | 
			
		||||
      const {
 | 
			
		||||
        xAxis: { min: minX, max: maxX },
 | 
			
		||||
        yAxis: { min: minY, max: maxY }
 | 
			
		||||
      } = this.twoDOption
 | 
			
		||||
 | 
			
		||||
      const inchartPoints = this.getInChartPoints(rect)
 | 
			
		||||
      const outchartPoints = rect.filter(pointItem => !inchartPoints.includes(pointItem))
 | 
			
		||||
      // 如果框选范围内只有俩点
 | 
			
		||||
      if (inchartPoints.length == 2) {
 | 
			
		||||
        const [point1, point2] = inchartPoints
 | 
			
		||||
        const isVerticleLine = this.isVerticleLine(point1, point2)
 | 
			
		||||
        // 如果是纵向标记线,判断另两个点是在左边还是右边
 | 
			
		||||
        if (isVerticleLine) {
 | 
			
		||||
          const find = outchartPoints.find(outcharPoint => point1[1] == outcharPoint[1]) // 找出纵坐标相同的在图表外面的点
 | 
			
		||||
          // 判断在图表外的这个点是在左边还是右边
 | 
			
		||||
          const isLeft = find[0] <= point1[0]
 | 
			
		||||
          /**
 | 
			
		||||
           * 如果在左边,推入左边俩点构成矩形
 | 
			
		||||
           * y
 | 
			
		||||
           * |________________
 | 
			
		||||
           * |                |
 | 
			
		||||
           * |________________|
 | 
			
		||||
           * |
 | 
			
		||||
           * |——————————————————— x
 | 
			
		||||
           **/
 | 
			
		||||
 | 
			
		||||
          if (isLeft) {
 | 
			
		||||
            inchartPoints.forEach(point => {
 | 
			
		||||
              rectList.push(this.generateLineDataByTwoPoints([minX, point[1]], point))
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point1, point2))
 | 
			
		||||
          }
 | 
			
		||||
          // 如果是右边,同理,推入右边俩点构成矩形
 | 
			
		||||
          else {
 | 
			
		||||
            inchartPoints.forEach(point => {
 | 
			
		||||
              rectList.push(this.generateLineDataByTwoPoints([maxX, point[1]], point))
 | 
			
		||||
            })
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point1, point2))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        // 如果是纵向标记线,判断另两个点是在上边还是下边
 | 
			
		||||
        else {
 | 
			
		||||
          const find = outchartPoints.find(outcharPoint => point1[0] == outcharPoint[0]) // 找出横坐标相同的在图表外面的点
 | 
			
		||||
          // 判断在图表外的这个点是在上边还是右边
 | 
			
		||||
          const isBottom = find[1] <= point1[1]
 | 
			
		||||
          /**
 | 
			
		||||
           * 如果在下边,推入下边俩点构成矩形
 | 
			
		||||
           **/
 | 
			
		||||
 | 
			
		||||
          if (isBottom) {
 | 
			
		||||
            inchartPoints.forEach(point => {
 | 
			
		||||
              rectList.push(this.generateLineDataByTwoPoints([point[0], minY], point))
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point1, point2))
 | 
			
		||||
          }
 | 
			
		||||
          // 如果是上边,同理,推入上边俩点构成矩形
 | 
			
		||||
          else {
 | 
			
		||||
            inchartPoints.forEach(point => {
 | 
			
		||||
              rectList.push(this.generateLineDataByTwoPoints([point[0], maxY], point))
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point1, point2))
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 只有一个点在范围内,则是选中了矩形的一个角
 | 
			
		||||
      else if (inchartPoints.length == 1) {
 | 
			
		||||
        const point = inchartPoints[0]
 | 
			
		||||
        const isLeft = !!outchartPoints.find(outPoint => outPoint[0] < point[0])
 | 
			
		||||
        const isBottom = !!outchartPoints.find(outPoint => outPoint[1] < point[1])
 | 
			
		||||
        // 截取的右上角
 | 
			
		||||
        if (isLeft && isBottom) {
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [minX, point[1]]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [point[0], minY]))
 | 
			
		||||
        }
 | 
			
		||||
        // 截取的右下角
 | 
			
		||||
        if (isLeft && !isBottom) {
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [minX, point[1]]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [point[0], maxY]))
 | 
			
		||||
        }
 | 
			
		||||
        // 截取的左下角
 | 
			
		||||
        if (!isLeft && !isBottom) {
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [maxX, point[1]]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [point[0], maxY]))
 | 
			
		||||
        }
 | 
			
		||||
        // 截取的左上角
 | 
			
		||||
        if (!isLeft && isBottom) {
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [maxX, point[1]]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints(point, [point[0], minY]))
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 全在里面
 | 
			
		||||
      else if (inchartPoints.length == 4) {
 | 
			
		||||
        // 按顺序挨个连起来,并且尾部连到头部
 | 
			
		||||
        rect.forEach((point, index) => {
 | 
			
		||||
          if (index == rect.length - 1) {
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point, rect[0]))
 | 
			
		||||
          } else {
 | 
			
		||||
            rectList.push(this.generateLineDataByTwoPoints(point, rect[index + 1]))
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      // 全不在里面
 | 
			
		||||
      else {
 | 
			
		||||
        // 筛选出所有的在框选范围内的横坐标
 | 
			
		||||
        const xAxisList = rect.map(item => item[0]).filter(xAxis => xAxis > minX && xAxis < maxX)
 | 
			
		||||
        const leftBottomPoint = rect[0]
 | 
			
		||||
        const rightBottomPoint = rect[1]
 | 
			
		||||
        const rightTopPoint = rect[3]
 | 
			
		||||
        const minYAxis = rightBottomPoint[1]
 | 
			
		||||
        const maYAxis = rightTopPoint[1]
 | 
			
		||||
        // 需要显示左右两侧的框线
 | 
			
		||||
        if (xAxisList.length == 4 && minYAxis < minY && maYAxis > maxY) {
 | 
			
		||||
          const minAxis = Math.min(...xAxisList)
 | 
			
		||||
          const maxAxis = Math.max(...xAxisList)
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([minAxis, minY], [minAxis, maxY]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([maxAxis, minY], [maxAxis, maxY]))
 | 
			
		||||
        }
 | 
			
		||||
        // 需要显示左右其中一条框线
 | 
			
		||||
        else if (xAxisList.length == 2 && minYAxis < minY && maYAxis > maxY) {
 | 
			
		||||
          const xAxis = xAxisList[0]
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([xAxis, minY], [xAxis, maxY]))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 筛选出所有的在框选范围内的横坐标
 | 
			
		||||
        const yAxisList = rect.map(item => item[1]).filter(xAxis => xAxis > minY && xAxis < maxY)
 | 
			
		||||
        const minXAxis = leftBottomPoint[0]
 | 
			
		||||
        const maxXAxis = rightBottomPoint[0]
 | 
			
		||||
        // 需要显示上下两侧的框线
 | 
			
		||||
        if (yAxisList.length == 4 && minXAxis < minX && maxXAxis > maxX) {
 | 
			
		||||
          const minAxis = Math.min(...yAxisList)
 | 
			
		||||
          const maxAxis = Math.max(...yAxisList)
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([minX, minAxis], [maxX, minAxis]))
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([minX, maxAxis], [maxX, maxAxis]))
 | 
			
		||||
        }
 | 
			
		||||
        // 需要显示左右其中一条框线
 | 
			
		||||
        else if (yAxisList.length == 2 && minXAxis < minX && maxXAxis > maxX) {
 | 
			
		||||
          const yAxis = yAxisList[0]
 | 
			
		||||
          rectList.push(this.generateLineDataByTwoPoints([minX, yAxis], [maxX, yAxis]))
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // 补齐颜色
 | 
			
		||||
      rectList.forEach(item => {
 | 
			
		||||
        item[0].lineStyle = {
 | 
			
		||||
      return {
 | 
			
		||||
        data: rect,
 | 
			
		||||
        symbol: 'none',
 | 
			
		||||
        itemStyle: {
 | 
			
		||||
          color
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      return rectList
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取在框选范围内的点列表
 | 
			
		||||
     * @param { Array<Array<number>> } rectInfo
 | 
			
		||||
     */
 | 
			
		||||
    getInChartPoints(rectInfo) {
 | 
			
		||||
      const {
 | 
			
		||||
        xAxis: { min: minX, max: maxX },
 | 
			
		||||
        yAxis: { min: minY, max: maxY }
 | 
			
		||||
      } = this.twoDOption
 | 
			
		||||
 | 
			
		||||
      return rectInfo.filter(point => {
 | 
			
		||||
        const [xAxis, yAxis] = point
 | 
			
		||||
        return xAxis >= minX && xAxis <= maxX && yAxis >= minY && yAxis <= maxY
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据俩点判断是横向还是纵向
 | 
			
		||||
     * x坐标相同,则是纵向,否则横向
 | 
			
		||||
     */
 | 
			
		||||
    isVerticleLine(point1, point2) {
 | 
			
		||||
      return point1[0] == point2[0] ? true : false
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据两个点生成一个markLine直线
 | 
			
		||||
     */
 | 
			
		||||
    generateLineDataByTwoPoints(point1, point2) {
 | 
			
		||||
      return [
 | 
			
		||||
        {
 | 
			
		||||
          xAxis: point1[0],
 | 
			
		||||
          yAxis: point1[1]
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          xAxis: point2[0],
 | 
			
		||||
          yAxis: point2[1]
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // 随机颜色算法
 | 
			
		||||
| 
						 | 
				
			
			@ -759,7 +580,7 @@ export default {
 | 
			
		|||
    boundary: {
 | 
			
		||||
      handler(newVal) {
 | 
			
		||||
        newVal.forEach((item, index) => {
 | 
			
		||||
          item.color = rectColorList[index%5]
 | 
			
		||||
          item.color = rectColorList[index % 5]
 | 
			
		||||
        })
 | 
			
		||||
        this.boundaryData = newVal
 | 
			
		||||
        this.reDrawRect()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user