diff --git a/src/component/axis/AxisBuilder.ts b/src/component/axis/AxisBuilder.ts index 9e5151711b..b668dbf9e7 100644 --- a/src/component/axis/AxisBuilder.ts +++ b/src/component/axis/AxisBuilder.ts @@ -851,22 +851,25 @@ const builders: Record = { const nameDirection = cfg.nameDirection; const textStyleModel = axisModel.getModel('nameTextStyle'); const gap = (axisModel.get('nameGap') || 0); + // When nameMoveOverlap is enabled, apply nameGap after overlap + // resolution so it acts as offset from the auto-resolved position. + const initialGap = cfg.shouldNameMoveOverlap ? 0 : gap; const extent = axisModel.axis.getExtent(); const gapStartEndSignal = axisModel.axis.inverse ? -1 : 1; const pos = new Point(0, 0); const nameMoveDirVec = new Point(0, 0); if (nameLocation === 'start') { - pos.x = extent[0] - gapStartEndSignal * gap; + pos.x = extent[0] - gapStartEndSignal * initialGap; nameMoveDirVec.x = -gapStartEndSignal; } else if (nameLocation === 'end') { - pos.x = extent[1] + gapStartEndSignal * gap; + pos.x = extent[1] + gapStartEndSignal * initialGap; nameMoveDirVec.x = gapStartEndSignal; } else { // 'middle' or 'center' pos.x = (extent[0] + extent[1]) / 2; - pos.y = cfg.labelOffset + nameDirection * gap; + pos.y = cfg.labelOffset + nameDirection * initialGap; nameMoveDirVec.y = nameDirection; } const mt = matrixUtil.create(); @@ -976,6 +979,12 @@ const builders: Record = { assert(record.labelInfoList); } shared.resolveAxisNameOverlap(cfg, shared, axisModel, nameLayout, nameMoveDirVec, record); + if (gap > 0) { + labelLayoutApplyTranslation( + nameLayout, + new Point(gap * nameMoveDirVec.x, gap * nameMoveDirVec.y) + ); + } } } diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts index 058dea900e..c0ea876bb4 100644 --- a/src/coord/axisCommonTypes.ts +++ b/src/coord/axisCommonTypes.ts @@ -61,22 +61,23 @@ export interface AxisBaseOptionCommon extends ComponentOption, }; nameTextStyle?: AxisNameTextStyleOption; /** - * This is the offset of axis name from: + * The offset of axis name: * - If `nameMoveOverlap: false`: offset from axisLine. - * - If `nameMoveOverlap: true`: offset from axisLine+axisLabels. - * - * PENDING: should it named as "nameOffset" or support `[offsetX, offsetY]`? + * - If `nameMoveOverlap: true`: additional offset applied after automatic + * overlap resolution, i.e. offset from axisLine+axisLabels. */ nameGap?: number; /** * Whether to auto move axis name to avoid overlap with axis labels. * The procedure of axis name layout: - * 1. Firstly apply `nameRotate`, `nameTruncate`, `nameLocation`, `nameGap`. - * Note that if `nameGap` is applied after the overlap handling, it may still - * cause overlap and confuse users. - * 2. If `nameMoveOverlap: true`, move the name util it does not overlap with - * axis lables. `nameTextStyle.textMargin` can be used to adjust its gap from + * 1. Firstly apply `nameRotate`, `nameTruncate`, `nameLocation`. + * 2. If `nameMoveOverlap: true`, move the name until it does not overlap with + * axis labels, then apply `nameGap` as additional offset from the resolved + * position. Negative `nameGap` is ignored in this case to prevent reintroducing + * overlap. `nameTextStyle.textMargin` can be used to adjust its gap from * others in this case. + * If `nameMoveOverlap: false`, `nameGap` is applied in step 1 as offset + * from the axis line. * - If 'auto'/null/undefined, use `nameMoveOverlap`, except when `grid.containLabel` is * true. This is for backward compat - users have tuned the position based on no name moved. */