UNPKG

@antv/g6

Version:

A Graph Visualization Framework in JavaScript

107 lines (97 loc) 3.35 kB
import type { DisplayObjectConfig, Group, PathStyleProps } from '@antv/g'; import { Path } from '@antv/g'; import type { CardinalPlacement, Prefix } from '../../types'; import { getPolygonTextStyleByPlacement } from '../../utils/polygon'; import { subStyleProps } from '../../utils/prefix'; import { mergeOptions } from '../../utils/style'; import { getWordWrapWidthByBox } from '../../utils/text'; import type { LabelStyleProps } from '../shapes'; import { BaseShape } from './base-shape'; import { Label } from './label'; export interface ContourLabelStyleProps extends LabelStyleProps { /** * <zh/> 标签位置 * * <en/> Label position * @defaultValue 'bottom' */ placement?: CardinalPlacement | 'center'; /** * <zh/> 标签是否贴合轮廓 * * <en/> Whether the label is close to the contour * @defaultValue true */ closeToPath?: boolean; /** * <zh/> 标签是否跟随轮廓旋转,仅在 closeToPath 为 true 时生效 * * <en/> Whether the label rotates with the contour. Only effective when closeToPath is true * @defaultValue true */ autoRotate?: boolean; /** * <zh/> x 轴偏移量 * * <en/> Label x-axis offset * @defaultValue 0 */ offsetX?: number; /** * <zh/> y 轴偏移量 * * <en/> Label y-axis offset * @defaultValue 0 */ offsetY?: number; /** * <zh/> 文本的最大宽度,超出会自动省略 * * <en/> The maximum width of the text, which will be automatically ellipsis if exceeded */ maxWidth?: number; } export interface ContourStyleProps extends PathStyleProps, Prefix<'label', ContourLabelStyleProps> { /** * <zh/> 是否显示标签 * * <en/> Whether to display the label * @defaultValue true */ label?: boolean; } type ParsedContourStyleProps = Required<ContourStyleProps>; type ContourOptions = DisplayObjectConfig<ContourStyleProps>; export class Contour extends BaseShape<ContourStyleProps> { static defaultStyleProps: Partial<ContourStyleProps> = { label: true, labelPlacement: 'bottom', labelCloseToPath: true, labelAutoRotate: true, labelOffsetX: 0, labelOffsetY: 0, }; constructor(options: ContourOptions) { super(mergeOptions({ style: Contour.defaultStyleProps }, options)); } protected getLabelStyle(attributes: ParsedContourStyleProps): LabelStyleProps | false { if (!attributes.label || !attributes.d || attributes.d.length === 0) return false; const { maxWidth, offsetX, offsetY, autoRotate, placement, closeToPath, ...labelStyle } = subStyleProps< Required<ContourLabelStyleProps> >(this.getGraphicStyle(attributes), 'label'); const key = this.shapeMap.key; const keyBounds = key?.getRenderBounds(); return Object.assign( getPolygonTextStyleByPlacement(keyBounds, placement, offsetX, offsetY, closeToPath, attributes.d, autoRotate), { wordWrapWidth: getWordWrapWidthByBox(keyBounds, maxWidth) }, labelStyle, ); } protected getKeyStyle(attributes: ParsedContourStyleProps): PathStyleProps { return this.getGraphicStyle(attributes); } public render(attributes: ParsedContourStyleProps, container: Group): void { this.upsert('key', Path, this.getKeyStyle(attributes), container); this.upsert('label', Label, this.getLabelStyle(attributes), container); } }