From 8352466a24ff3e2d131e5d5e2e193f13bd1fbbe2 Mon Sep 17 00:00:00 2001 From: "lixuefei.1313" Date: Wed, 10 Sep 2025 19:06:42 +0800 Subject: [PATCH 1/3] feat: support includFullBand api in markArea --- .../vchart/src/component/marker/interface.ts | 7 ++ .../marker/mark-area/cartesian-mark-area.ts | 5 +- packages/vchart/src/component/marker/utils.ts | 85 +++++++++++++++++-- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/packages/vchart/src/component/marker/interface.ts b/packages/vchart/src/component/marker/interface.ts index 28fb3d169c..b2d67958b6 100644 --- a/packages/vchart/src/component/marker/interface.ts +++ b/packages/vchart/src/component/marker/interface.ts @@ -340,6 +340,13 @@ export type IMarkerSpec = IComponentSpec & { * @since 1.11.0 */ coordinateType?: string; + + /** + * 在band轴下标注组件是否包含全band + * @default false + * @since 2.0.5 + */ + includeFullBand?: boolean; }; export type IMarkerSymbol = IMarkerRef & { diff --git a/packages/vchart/src/component/marker/mark-area/cartesian-mark-area.ts b/packages/vchart/src/component/marker/mark-area/cartesian-mark-area.ts index 140b451993..3b743e06eb 100644 --- a/packages/vchart/src/component/marker/mark-area/cartesian-mark-area.ts +++ b/packages/vchart/src/component/marker/mark-area/cartesian-mark-area.ts @@ -38,11 +38,12 @@ export class CartesianMarkArea extends BaseMarkArea { const isPositionLayout = isValid(spec.positions); const autoRange = spec.autoRange ?? false; + const includeFullBand = spec.includeFullBand ?? false; let points: IPoint[] = []; let lines: IPoint[][] = []; if (doXYProcess) { - lines = xyLayout(data, startRelativeSeries, endRelativeSeries, relativeSeries, autoRange); + lines = xyLayout(data, startRelativeSeries, endRelativeSeries, relativeSeries, autoRange, includeFullBand); // 格式为 [[{x, y}], [{x, y}]] // 顺序为左下角开始逆时针绘制 const [start, end] = lines; @@ -61,7 +62,7 @@ export class CartesianMarkArea extends BaseMarkArea { ]; } } else if (doXProcess || doYProcess) { - lines = xyLayout(data, startRelativeSeries, endRelativeSeries, relativeSeries, autoRange); + lines = xyLayout(data, startRelativeSeries, endRelativeSeries, relativeSeries, autoRange, includeFullBand); const [start, end] = lines; if (start && start.length && end && end.length) { points = [...start, end[1], end[0]]; diff --git a/packages/vchart/src/component/marker/utils.ts b/packages/vchart/src/component/marker/utils.ts index a0abc90935..4688031a53 100644 --- a/packages/vchart/src/component/marker/utils.ts +++ b/packages/vchart/src/component/marker/utils.ts @@ -28,8 +28,20 @@ import type { IRegion } from '../../region/interface'; // eslint-disable-next-line no-duplicate-imports import type { OffsetPoint } from './interface'; import type { IAxisHelper, IPolarAxisHelper } from '../axis'; +import type { BandScale } from '@visactor/vscale'; import { isContinuous } from '@visactor/vscale'; +type FullBandTemp = { + min: { + value: number; + index: number; + }; + max: { + value: number; + index: number; + }; +}; + function isNeedExtendDomain(domain: number[], datum: number, autoRange: boolean) { if (!autoRange) { return false; @@ -141,7 +153,8 @@ export function xyLayout( startRelativeSeries: IMarkerSupportSeries, endRelativeSeries: IMarkerSupportSeries, relativeSeries: IMarkerSupportSeries, - autoRange: boolean + autoRange: boolean, + includeFullBand: boolean = false ) { const regionStart = startRelativeSeries.getRegion(); const regionStartLayoutStartPoint = regionStart.getLayoutStartPoint(); @@ -174,20 +187,33 @@ export function xyLayout( data.latestData[0] && data.latestData[0].latestData ? data.latestData[0].latestData : data.latestData; const xDomain = (relativeSeries as ICartesianSeries).getXAxisHelper().getScale(0).domain(); const yDomain = (relativeSeries as ICartesianSeries).getYAxisHelper().getScale(0).domain(); + + const xAxisHelper = (relativeSeries as ICartesianSeries).getXAxisHelper(); + const yAxisHelper = (relativeSeries as ICartesianSeries).getXAxisHelper(); + const isXExpand = includeFullBand && !xAxisHelper.isContinuous && !!xAxisHelper.getBandwidth; + const isyExpand = includeFullBand && !yAxisHelper.isContinuous && !!yAxisHelper.getBandwidth; + const xTemp: FullBandTemp = { min: null, max: null }; + const yTemp: FullBandTemp = { min: null, max: null }; + dataPoints.forEach((datum: IPoint) => { const isValidX = isValid(datum.x); const isValidY = isValid(datum.y); + let x; + let y; if (isValidX && isValidY) { - const x = getXValue(datum, xDomain, autoRange, refSeries, regionWidth, regionStartLayoutStartPoint); - const y = getYValue(datum, yDomain, autoRange, refSeries, regionHeight, regionStartLayoutStartPoint); + x = getXValue(datum, xDomain, autoRange, refSeries, regionWidth, regionStartLayoutStartPoint); + y = getYValue(datum, yDomain, autoRange, refSeries, regionHeight, regionStartLayoutStartPoint); + setTempWithValid(x, isXExpand, xTemp, lines.length); + setTempWithValid(y, isyExpand, yTemp, lines.length); lines.push([{ x, y }]); } else if (isValidX) { - const x = getXValue(datum, xDomain, autoRange, refSeries, regionWidth, regionStartLayoutStartPoint); - const y = Math.max( + x = getXValue(datum, xDomain, autoRange, refSeries, regionWidth, regionStartLayoutStartPoint); + y = Math.max( regionStartLayoutStartPoint.y + regionStart.getLayoutRect().height, regionEndLayoutStartPoint.y + regionEnd.getLayoutRect().height ); const y1 = Math.min(regionStartLayoutStartPoint.y, regionEndLayoutStartPoint.y); + setTempWithValid(x, isXExpand, xTemp, lines.length); lines.push([ { x: x, @@ -199,12 +225,13 @@ export function xyLayout( } ]); } else if (isValidY) { - const x = Math.min(regionStartLayoutStartPoint.x, regionEndLayoutStartPoint.x); - const y = getYValue(datum, yDomain, autoRange, refSeries, regionHeight, regionStartLayoutStartPoint); + x = Math.min(regionStartLayoutStartPoint.x, regionEndLayoutStartPoint.x); + y = getYValue(datum, yDomain, autoRange, refSeries, regionHeight, regionStartLayoutStartPoint); const x1 = Math.max( regionStartLayoutStartPoint.x + regionStart.getLayoutRect().width, regionEndLayoutStartPoint.x + regionEnd.getLayoutRect().width ); + setTempWithValid(y, isyExpand, yTemp, lines.length); lines.push([ { x: x, @@ -217,10 +244,52 @@ export function xyLayout( ]); } }); - + setTempToLines(lines, xAxisHelper, yAxisHelper, xTemp, yTemp); return lines; } +function setTempToLines( + lines: IPoint[][], + xAxisHelper: IAxisHelper | IPolarAxisHelper, + yAxisHelper: IAxisHelper | IPolarAxisHelper, + xTemp: FullBandTemp, + yTemp: FullBandTemp +) { + const xBandSize = xAxisHelper.getBandwidth(0) * (1 + (xAxisHelper.getScale(0) as BandScale).paddingInner()); + const yBandSize = yAxisHelper.getBandwidth(0) * (1 + (yAxisHelper.getScale(0) as BandScale).paddingInner()); + + if (xTemp.min) { + lines[xTemp.min.index].forEach(p => (p.x -= xBandSize / 2)); + } + if (xTemp.max) { + lines[xTemp.max.index].forEach(p => (p.x += xBandSize / 2)); + } + if (yTemp.min) { + lines[yTemp.min.index].forEach(p => (p.y -= yBandSize / 2)); + } + if (yTemp.max) { + lines[yTemp.max.index].forEach(p => (p.y += yBandSize / 2)); + } +} + +function setTempWithValid(v: number, isExpand: boolean, temp: FullBandTemp, index: number): number { + if (isExpand) { + if (temp.min === null || temp.min.value > v) { + temp.min = { + value: v, + index + }; + } + if (temp.max === null || temp.max.value < v) { + temp.max = { + value: v, + index + }; + } + } + return v; +} + export function polarLayout( data: DataView, startRelativeSeries: IMarkerSupportSeries, From b5a6750ddef49486c989bf522f35195da5dbb663 Mon Sep 17 00:00:00 2001 From: "lixuefei.1313" Date: Wed, 10 Sep 2025 19:11:27 +0800 Subject: [PATCH 2/3] feat: support includFullBand api in markArea --- packages/vchart/src/component/marker/utils.ts | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/vchart/src/component/marker/utils.ts b/packages/vchart/src/component/marker/utils.ts index 4688031a53..c687fa208a 100644 --- a/packages/vchart/src/component/marker/utils.ts +++ b/packages/vchart/src/component/marker/utils.ts @@ -185,11 +185,13 @@ export function xyLayout( const lines: IPoint[][] = []; const dataPoints = data.latestData[0] && data.latestData[0].latestData ? data.latestData[0].latestData : data.latestData; - const xDomain = (relativeSeries as ICartesianSeries).getXAxisHelper().getScale(0).domain(); - const yDomain = (relativeSeries as ICartesianSeries).getYAxisHelper().getScale(0).domain(); const xAxisHelper = (relativeSeries as ICartesianSeries).getXAxisHelper(); const yAxisHelper = (relativeSeries as ICartesianSeries).getXAxisHelper(); + + const xDomain = xAxisHelper.getScale(0).domain(); + const yDomain = yAxisHelper.getScale(0).domain(); + const isXExpand = includeFullBand && !xAxisHelper.isContinuous && !!xAxisHelper.getBandwidth; const isyExpand = includeFullBand && !yAxisHelper.isContinuous && !!yAxisHelper.getBandwidth; const xTemp: FullBandTemp = { min: null, max: null }; @@ -255,20 +257,23 @@ function setTempToLines( xTemp: FullBandTemp, yTemp: FullBandTemp ) { - const xBandSize = xAxisHelper.getBandwidth(0) * (1 + (xAxisHelper.getScale(0) as BandScale).paddingInner()); - const yBandSize = yAxisHelper.getBandwidth(0) * (1 + (yAxisHelper.getScale(0) as BandScale).paddingInner()); - - if (xTemp.min) { - lines[xTemp.min.index].forEach(p => (p.x -= xBandSize / 2)); - } - if (xTemp.max) { - lines[xTemp.max.index].forEach(p => (p.x += xBandSize / 2)); - } - if (yTemp.min) { - lines[yTemp.min.index].forEach(p => (p.y -= yBandSize / 2)); + if (xTemp.min || xTemp.max) { + const xBandSize = xAxisHelper.getBandwidth(0) * (1 + (xAxisHelper.getScale(0) as BandScale).paddingInner()); + if (xTemp.min) { + lines[xTemp.min.index].forEach(p => (p.x -= xBandSize / 2)); + } + if (xTemp.max) { + lines[xTemp.max.index].forEach(p => (p.x += xBandSize / 2)); + } } - if (yTemp.max) { - lines[yTemp.max.index].forEach(p => (p.y += yBandSize / 2)); + if (yTemp.min || yTemp.max) { + const yBandSize = yAxisHelper.getBandwidth(0) * (1 + (yAxisHelper.getScale(0) as BandScale).paddingInner()); + if (yTemp.min) { + lines[yTemp.min.index].forEach(p => (p.y -= yBandSize / 2)); + } + if (yTemp.max) { + lines[yTemp.max.index].forEach(p => (p.y += yBandSize / 2)); + } } } From de598a20f27ed0ef12017b55412bbc44c3de6bcd Mon Sep 17 00:00:00 2001 From: "lixuefei.1313" Date: Wed, 10 Sep 2025 19:13:19 +0800 Subject: [PATCH 3/3] docs: update changlog of rush --- ...-includeFullBand-in-markarea_2025-09-10-11-13.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vchart/feat-support-includeFullBand-in-markarea_2025-09-10-11-13.json diff --git a/common/changes/@visactor/vchart/feat-support-includeFullBand-in-markarea_2025-09-10-11-13.json b/common/changes/@visactor/vchart/feat-support-includeFullBand-in-markarea_2025-09-10-11-13.json new file mode 100644 index 0000000000..6c6d9933e9 --- /dev/null +++ b/common/changes/@visactor/vchart/feat-support-includeFullBand-in-markarea_2025-09-10-11-13.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "feat: support includFullBand api in markArea\n\n", + "type": "none", + "packageName": "@visactor/vchart" + } + ], + "packageName": "@visactor/vchart", + "email": "lixuef1313@163.com" +} \ No newline at end of file