diff --git a/packages/vrender-components/__tests__/browser/examples/label-arc.ts b/packages/vrender-components/__tests__/browser/examples/label-arc.ts index af23058b9..0ed64cf6a 100644 --- a/packages/vrender-components/__tests__/browser/examples/label-arc.ts +++ b/packages/vrender-components/__tests__/browser/examples/label-arc.ts @@ -1152,7 +1152,7 @@ const latestData = [ // VGRAMMAR_DATA_ID_KEY_16: 0 }, { - type: 'silicon', + type: 'silicon11111111', value: '27.72', __VCHART_DEFAULT_DATA_INDEX: 1, __VCHART_DEFAULT_DATA_KEY: 'silicon_silicon_0', @@ -1287,7 +1287,7 @@ function createContent(stage: Stage) { height: 500, // position: 'outside', - position: 'inside', + position: 'inside-outer', textStyle: { // angle: 0 @@ -1306,7 +1306,7 @@ function createContent(stage: Stage) { tangentConstraint: false }, - // centerOffset: 10, + offsetRadius: -50, // smartInvert: false, diff --git a/packages/vrender-components/src/label/arc.ts b/packages/vrender-components/src/label/arc.ts index 4420a9315..3eaa3675a 100644 --- a/packages/vrender-components/src/label/arc.ts +++ b/packages/vrender-components/src/label/arc.ts @@ -277,12 +277,18 @@ export class ArcLabel extends LabelBase { const leftArcs = Array.from(this._arcLeft.values()); const rightArcs = Array.from(this._arcRight.values()); const arcs: ArcInfo[] = []; - if (position === 'inside') { - arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks)); - arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks)); - } else { - arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks)); - arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks)); + switch (position) { + case 'inside': + case 'inside-inner': + case 'inside-outer': + arcs.push(...this._layoutInsideLabels(rightArcs, attribute, currentMarks)); + arcs.push(...this._layoutInsideLabels(leftArcs, attribute, currentMarks)); + break; + case 'outside': + default: + arcs.push(...this._layoutOutsideLabels(rightArcs, attribute, currentMarks)); + arcs.push(...this._layoutOutsideLabels(leftArcs, attribute, currentMarks)); + break; } return arcs; } @@ -290,9 +296,11 @@ export class ArcLabel extends LabelBase { /** * 布局内部标签 */ - private _layoutInsideLabels(arcs: ArcInfo[], attribute: any, currentMarks: any[]) { + private _layoutInsideLabels(arcs: ArcInfo[], attribute: ArcLabelAttrs, currentMarks: any[]) { const labelConfig = attribute; const spaceWidth = labelConfig.spaceWidth as number; + const position = labelConfig?.position ?? 'inside'; + const offsetRadius = labelConfig?.offsetRadius ?? -spaceWidth; arcs.forEach((arc: ArcInfo) => { const { labelSize, radian } = arc; @@ -319,8 +327,16 @@ export class ArcLabel extends LabelBase { arc.labelText = text; const labelWidth = Math.min(limit, arc.labelSize.width); const align = this._computeAlign(arc, attribute); - const alignOffset = align === 'left' ? labelWidth : align === 'right' ? 0 : labelWidth / 2; - const labelRadius = outerRadius - spaceWidth - alignOffset; + let alignOffset = 0; + if (position === 'inside') { + alignOffset = align === 'left' ? labelWidth : align === 'right' ? 0 : labelWidth / 2; + } + let labelRadius; + if (position === 'inside-inner') { + labelRadius = innerRadius - offsetRadius + alignOffset; + } else { + labelRadius = outerRadius + offsetRadius - alignOffset; + } arc.labelPosition = circlePoint(arc.circleCenter.x, arc.circleCenter.y, labelRadius, arc.middleAngle); arc.labelLimit = labelWidth; if (!isGreater(labelWidth, 0)) { @@ -330,6 +346,11 @@ export class ArcLabel extends LabelBase { // arc.angle = degrees(arc.middleAngle); arc.angle = attribute?.textStyle?.angle ?? arc.middleAngle; + let offsetAngle = labelConfig?.offsetAngle ?? 0; + if (['inside-inner', 'inside-outer'].includes(position as string)) { + offsetAngle += Math.PI / 2; + } + arc.angle += offsetAngle; }); return arcs; } @@ -337,7 +358,7 @@ export class ArcLabel extends LabelBase { /** * 布局外部标签 */ - private _layoutOutsideLabels(arcs: ArcInfo[], attribute: any, currentMarks: any[]) { + private _layoutOutsideLabels(arcs: ArcInfo[], attribute: ArcLabelAttrs, currentMarks: any[]) { const center = { x: currentMarks[0].attribute?.x ?? 0, y: currentMarks[0].attribute?.y ?? 0 }; const height = center.y * 2; const line2MinLength = attribute.line.line2MinLength as number; @@ -406,6 +427,9 @@ export class ArcLabel extends LabelBase { arc.labelVisible = false; } arc.angle = attribute?.textStyle?.angle ?? 0; + if (attribute?.offsetAngle) { + arc.angle += attribute.offsetAngle; + } arc.labelLine = { ...attribute?.line diff --git a/packages/vrender-components/src/label/type.ts b/packages/vrender-components/src/label/type.ts index a993ad3a5..1a482e624 100644 --- a/packages/vrender-components/src/label/type.ts +++ b/packages/vrender-components/src/label/type.ts @@ -278,7 +278,7 @@ export interface ArcLabelAttrs extends BaseLabelAttrs { * 标签位置 * @default 'outside' */ - position?: Functional<'inside' | 'outside'>; + position?: Functional<'inside' | 'outside' | 'inside-inner' | 'inside-outer'>; // 画布宽度 width?: number; @@ -305,6 +305,14 @@ export interface ArcLabelAttrs extends BaseLabelAttrs { * 标签旋转角度 */ angle?: number; + /** + * 标签旋转角度的偏移角度 + */ + offsetAngle?: number; + /** + * 标签相对于 `outerRadius` 的径向偏移,目前仅作用于 inside 标签 + */ + offsetRadius?: number; /** * 标签横向点对齐 */