UNPKG

@antv/g6

Version:

A Graph Visualization Framework in JavaScript

84 lines (70 loc) 2.66 kB
import type { TransformArray } from '@antv/g'; import { rad2deg } from '@antv/g'; import type { RuntimeContext } from '../runtime/types'; import type { NodeData } from '../spec'; import { idOf } from '../utils/id'; import { positionOf } from '../utils/position'; import { parseSize } from '../utils/size'; import { rad, subtract } from '../utils/vector'; import type { BaseTransformOptions } from './base-transform'; import { BaseTransform } from './base-transform'; /** * <zh/> 根据径向布局自动调整节点标签样式的配置项 * * <en/> Options for automatically adjusting the style of node labels according to the radial layout */ export interface PlaceRadialLabelsOptions extends BaseTransformOptions { /** * <zh/> 偏移量 * * <en/> Offset */ offset?: number; } /** * <zh/> 根据径向布局自动调整节点标签样式,包括位置和旋转角度 * * <en/> Automatically adjust the style of node labels according to the radial layout, including position and rotation angle */ export class PlaceRadialLabels extends BaseTransform<PlaceRadialLabelsOptions> { static defaultOptions: Partial<PlaceRadialLabelsOptions> = { offset: 5, }; constructor(context: RuntimeContext, options: PlaceRadialLabelsOptions) { super(context, Object.assign({}, PlaceRadialLabels.defaultOptions, options)); } private get ref(): NodeData { return this.context.model.getRootsData()[0]; } public afterLayout() { const refPoint = positionOf(this.ref); const { graph, model } = this.context; const data = model.getData(); data.nodes?.forEach((datum) => { if (idOf(datum) === idOf(this.ref)) return; const radian = rad(subtract(positionOf(datum), refPoint)); const isLeft = Math.abs(radian) > Math.PI / 2; const isLeaf = !datum.children || datum.children.length === 0; const nodeId = idOf(datum); const node = this.context.element?.getElement(nodeId); if (!node || !node.isVisible()) return; const nodeHalfWidth = parseSize(graph.getElementRenderStyle(nodeId).size)[0] / 2; const offset = (isLeaf ? 1 : -1) * (nodeHalfWidth + this.options.offset); const labelTransform: TransformArray = [ ['translate', offset * Math.cos(radian), offset * Math.sin(radian)], ['rotate', isLeft ? rad2deg(radian) + 180 : rad2deg(radian)], ]; model.updateNodeData([ { id: idOf(datum), style: { labelTextAlign: isLeft === isLeaf ? 'right' : 'left', labelTextBaseline: 'middle', labelTransform, }, }, ]); }); graph.draw(); } }