import type { IRenderer } from '@antv/g'; import { Canvas as GCanvas } from '@antv/g'; import { Renderer } from '@antv/g-canvas'; import { Canvas } from '../../runtime/canvas'; import type { Placement } from '../../types'; import { parsePlacement } from '../../utils/placement'; import { createPluginContainer } from './dom'; interface Options { /** 插件宽度 | Plugin width */ width: number; /** 插件高度 | Plugin height */ height: number; /** 渲染器 | Render */ renderer?: IRenderer; /** 插件放置位置 | Plugin placement */ placement: Placement; /** 插件类名 | Plugin class name */ className: string; /** 指定插件放置容器 | Specify the plugin placement container */ container?: string | HTMLElement; /** 容器样式 | Container style */ containerStyle?: Partial; /** G6 画布 | G6 canvas */ graphCanvas: Canvas; } /** * 创建插件画布 * * Create a plugin canvas * @param options - 配置项 | options * @returns [容器, 画布] | [container, canvas] */ export function createPluginCanvas(options: Options): [HTMLElement, GCanvas] { const { width, height, renderer } = options; const $container = getContainer(options); const canvas = new GCanvas({ width, height, container: $container, renderer: renderer || new Renderer(), }); return [$container, canvas]; } /** * 获取容器 * * Get container * @param options - 配置项 | options * @returns 容器 | container */ function getContainer(options: Options) { const { container, className, graphCanvas } = options; if (container) { return typeof container === 'string' ? document.getElementById(container)! : container; } const $container = createPluginContainer(className, false); const { width, height, containerStyle } = options; const [x, y] = computePosition(options); Object.assign($container.style, { position: 'absolute', left: x + 'px', top: y + 'px', width: width + 'px', height: height + 'px', ...containerStyle, }); graphCanvas.getContainer()?.appendChild($container); return $container; } /** * 计算容器位置 * * Compute the position of the container * @param options - 配置项 | options * @returns 位置 | position */ function computePosition(options: Options) { const { width, height, placement, graphCanvas } = options; const [W, H] = graphCanvas.getSize(); const [xRatio, yRatio] = parsePlacement(placement); return [xRatio * (W - width), yRatio * (H - height)]; }