KLineChart icon indicating copy to clipboard operation
KLineChart copied to clipboard

[Feature] 当多个副图存在的时候,可以设置某个副图最大化

Open flameOnYou opened this issue 1 month ago • 1 comments

Feature Description

实现smax的状态,代码如下

setPaneOptions (options: PaneOptions): void {
    let shouldMeasureHeight = false
    let shouldLayout = false
    const validId = isValid(options.id)
    for (const currentPane of this._drawPanes) {
      const currentPaneId = currentPane.getId()
      if ((validId && options.id === currentPaneId) || !validId) {
        if (currentPaneId !== PaneIdConstants.X_AXIS) {
          if (isNumber(options.height) && options.height > 0) {
            const minHeight = Math.max(options.minHeight ?? currentPane.getOptions().minHeight, 0)
            const height = Math.max(minHeight, options.height)
            shouldLayout = true
            shouldMeasureHeight = true
            currentPane.setOriginalBounding({ height })
            this._recalculatePaneHeight(currentPane, height, -height)
          }
          if (
            isValid(options.state) &&
            currentPane.getOptions().state !== options.state
          ) {
            shouldMeasureHeight = true
            shouldLayout = true
            const state = options.state
            switch (state) {
              case 'smax': {
                const totalHeight = this._chartBounding.height
                const candleHeight = this._candlePane.getBounding().height
                const xAxisHeight = this._xAxisPane.getBounding().height
                const separatorSize = this.getStyles().separator.size
                const subPanes = this._drawPanes.filter(p => p.getId() !== PaneIdConstants.CANDLE && p.getId() !== PaneIdConstants.X_AXIS)
                const targetPane = subPanes.find(p => p.getId() === currentPaneId)
                const otherPanes = subPanes.filter(p => p.getId() !== currentPaneId)
                const remainHeight = totalHeight - candleHeight - xAxisHeight - separatorSize * (subPanes.length - 1)
                const maxHeight = remainHeight - PANE_MIN_HEIGHT * (otherPanes.length)
                if (targetPane != null) {
                  targetPane.setBounding({ height: maxHeight })
                  targetPane.setOptions({ state })
                }
                otherPanes.forEach(p => {
                  p.setBounding({ height: PANE_MIN_HEIGHT })
                  p.setOptions({ state: 'minimize' })
                })
                this._drawPanes.forEach(pane => {
                  if (pane.getId() !== PaneIdConstants.X_AXIS) {
                    pane.setVisible(true)
                    this._separatorPanes.get(pane)?.setVisible(true)
                  }
                })
                break
              }
              case 'maximize': {
                const maximizePane = this._drawPanes.find(pane => {
                  const paneId = pane.getId()
                  return pane.getOptions().state === 'maximize' && paneId !== PaneIdConstants.X_AXIS
                })
                if (!isValid(maximizePane)) {
                  if (currentPane.getOptions().state === 'normal') {
                    currentPane.setOriginalBounding({ height: currentPane.getBounding().height })
                  }
                  currentPane.setOptions({ state })
                  const totalHeight = this._chartBounding.height
                  currentPane.setBounding({ height: totalHeight - this._xAxisPane.getBounding().height })
                  this._drawPanes.forEach(pane => {
                    if (pane.getId() !== PaneIdConstants.X_AXIS && pane.getId() !== currentPaneId) {
                      pane.setBounding({ height: pane.getOriginalBounding().height })
                      pane.setVisible(false)
                      this._separatorPanes.get(pane)?.setVisible(false)
                    }
                  })
                }
                break
              }
              case 'minimize': {
                const height = currentPane.getBounding().height
                const currentState = currentPane.getOptions().state
                let changeHeight = height - PANE_MIN_HEIGHT
                if (currentState === 'maximize') {
                  changeHeight = currentPane.getOriginalBounding().height - PANE_MIN_HEIGHT
                }
                if (
                  this._recalculatePaneHeight(
                    currentPane,
                    PANE_MIN_HEIGHT,
                    changeHeight
                  )
                ) {
                  if (currentState === 'normal') {
                    currentPane.setOriginalBounding({ height })
                  }
                  currentPane.setOptions({ state })
                }
                this._drawPanes.forEach(pane => {
                  if (pane.getId() !== PaneIdConstants.X_AXIS) {
                    pane.setVisible(true)
                    this._separatorPanes.get(pane)?.setVisible(true)
                  }
                })
                break
              }
              default: {
                const height = currentPane.getOriginalBounding().height
                if (
                  this._recalculatePaneHeight(
                    currentPane,
                    height,
                    currentPane.getBounding().height - height
                  )
                ) {
                  currentPane.setOptions({ state })
                }
                this._drawPanes.forEach(pane => {
                  if (pane.getId() !== PaneIdConstants.X_AXIS) {
                    pane.setVisible(true)
                    this._separatorPanes.get(pane)?.setVisible(true)
                  }
                })
                break
              }
            }
          }
        }
        if (isValid(options.axis)) {
          shouldLayout = true
        }
        const ops = { ...options }
        delete ops.state
        currentPane.setOptions(ops)
        if (currentPaneId === options.id) {
          break
        }
      }
    }
    if (shouldLayout) {
      this.layout({
        measureHeight: shouldMeasureHeight,
        measureWidth: true,
        update: true,
        buildYAxisTick: true,
        forceBuildYAxisTick: true
      })
    }
  }

To Do

1.新增smax状态

flameOnYou avatar Nov 07 '25 16:11 flameOnYou

复制进Chart.ts对应代码即可,v10.8版本测试通过

flameOnYou avatar Nov 07 '25 16:11 flameOnYou