From 5d4a3ef016e74af5c8c368477e2a14ed1f2644f6 Mon Sep 17 00:00:00 2001 From: Quinn Su Date: Wed, 9 Jul 2025 17:29:36 +0800 Subject: [PATCH] scale legend when set height --- src/component/legend/LegendView.ts | 58 ++++++- test/legend-height-formats.html | 244 +++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 test/legend-height-formats.html diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts index 2dc195fcae..66ccb9ad0c 100644 --- a/src/component/legend/LegendView.ts +++ b/src/component/legend/LegendView.ts @@ -26,6 +26,7 @@ import { enableHoverEmphasis } from '../../util/states'; import {setLabelStyle, createTextStyle} from '../../label/labelStyle'; import {makeBackground} from '../helper/listComponent'; import * as layoutUtil from '../../util/layout'; +import { parsePercent } from '../../util/number'; import ComponentView from '../../view/Component'; import LegendModel, { LegendItemStyleOption, @@ -141,7 +142,26 @@ class LegendView extends ComponentView { const maxSize = layoutUtil.getLayoutRect(positionInfo, refContainer, padding); - const mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition); + const userHeight = legendModel.get('height'); + let heightThreshold: number | null = null; + + if (userHeight != null) { + if (typeof userHeight === 'string') { + const parsed = parsePercent(userHeight, refContainer.height); + if (!isNaN(parsed) && isFinite(parsed) && parsed > 0) { + heightThreshold = parsed; + } + } + else if (typeof userHeight === 'number') { + if (!isNaN(userHeight) && isFinite(userHeight) && userHeight > 0) { + heightThreshold = userHeight; + } + } + } + + const mainRect = this.layoutInner( + legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition, heightThreshold + ); // Place mainGroup, based on the calculated `mainRect`. const layoutRect = layoutUtil.getLayoutRect( @@ -522,7 +542,8 @@ class LegendView extends ComponentView { maxSize: { width: number, height: number }, isFirstRender: boolean, selector: LegendOption['selector'], - selectorPosition: LegendOption['selectorPosition'] + selectorPosition: LegendOption['selectorPosition'], + heightThreshold: number | null ): ZRRectLike { const contentGroup = this.getContentGroup(); const selectorGroup = this.getSelectorGroup(); @@ -536,7 +557,38 @@ class LegendView extends ComponentView { maxSize.height ); - const contentRect = contentGroup.getBoundingRect(); + let contentRect = contentGroup.getBoundingRect(); + + if (heightThreshold != null) { + if (contentRect.height > heightThreshold) { + const exceedRatio = (contentRect.height - heightThreshold) / heightThreshold; + const scale = Math.max(1 / (1 + exceedRatio), 0.5); + + const adjustedMaxSize = { + width: maxSize.width / scale, + height: maxSize.height / scale, + }; + + layoutUtil.box( + legendModel.get('orient'), + contentGroup, + legendModel.get('itemGap'), + adjustedMaxSize.width, + adjustedMaxSize.height + ); + contentGroup.scaleX = scale; + contentGroup.scaleY = scale; + contentRect = contentGroup.getBoundingRect(); + } + else { + if (contentGroup.scaleX !== 1 || contentGroup.scaleY !== 1) { + contentGroup.scaleX = 1; + contentGroup.scaleY = 1; + contentRect = contentGroup.getBoundingRect(); + } + } + } + const contentPos = [-contentRect.x, -contentRect.y]; selectorGroup.markRedraw(); diff --git a/test/legend-height-formats.html b/test/legend-height-formats.html new file mode 100644 index 0000000000..8b0876dc9a --- /dev/null +++ b/test/legend-height-formats.html @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + + + + \ No newline at end of file