/** * @author: yanxianliang * @date: 2025-07-02 09:30 * @desc: BaseGraph 类型文件定义 * * Copyright (c) 2025 by yanxianliang, All Rights Reserved. */ import type { NodeProps, ReactFlowProps } from "@xyflow/react/dist/esm/types"; import React, { ComponentType } from "react"; import { Edge, InternalNode, MarkerType, Node, NodeOrigin, PanelPosition } from "@xyflow/react"; import { NodeHandleBounds } from "@xyflow/system/dist/esm/types/nodes"; import { TooltipPlacement, TooltipProps } from "antd/es/tooltip"; import { EdgeLookup, NodeLookup } from "@xyflow/system"; import { MarkDefinition } from "./components/MarkerDefinitions/types"; import { NodeRoleType } from "./constants"; import { ScrollbarPluginOptions } from "./plugins/scrollbar/types"; type RequireSpecific = Omit & { [P in K]-?: T[P]; }; export type NodeComponentProps = Record> = RequireSpecific>, 'width' | 'height' | 'type'>; export type NodeTypeComponent = Record> = ComponentType>> & { measureHandles?: (data: Node) => NodeHandleBounds; defaultSize?: { width: number | ((node: Node, theme: BaseThemeConfig) => number); height: number | ((data: Node, theme: BaseThemeConfig) => number); }; }; export interface BaseThemeConfig { /** * @description 字体大小配置 * @default 14 */ fontSize?: number; /** * @description 字体家族配置 * @default "Arial, helvetica, sans-serif" */ fontFamily?: string; /** * @description 主题色 * @default "#5F95FF" */ primaryColor?: string; /** * @description 折叠按钮形状 * @default 'rect' */ collapseButtonShape?: 'rect' | 'circle'; } export type LayoutConfig = { nodeTypes: Record; originNodes: NodeType[]; originEdges: EdgeType[]; theme: BaseThemeConfig; onlyRenderVisibleElements: boolean; nodeLookup: NodeLookup; edgeLookup: EdgeLookup; nodeOrigin: NodeOrigin; }; export type LayoutFunction = (config: LayoutConfig) => ({ nodes: NodeType[]; edges: EdgeType[]; }); export type MindMapLayoutConfig = { hGap?: number; vGap?: number; markerType?: MarkerType; }; export type NodeDefinition = Record> = { type: string; hideInLegend?: boolean; hideInSider?: boolean; group?: string; order?: number; label?: string; icon?: string; color?: string; deletable?: boolean; nodeRoleType?: NodeRoleType; allowNodeTypes?: string[]; forbiddenNodeTypes?: string[]; /** * 部分节点不允许在全局中使用,仅允许在子流程中使用 */ allowInGroupTypes?: string[]; forbiddenInGroupTypes?: string[]; allowContentSelection?: boolean; component: NodeTypeComponent; measureHandles?: (data: Node) => NodeHandleBounds; defaultSize?: { width: number | ((node: Node, theme: BaseThemeConfig) => number); height: number | ((data: Node, theme: BaseThemeConfig) => number); }; [key: string]: any; }; export interface IBaseGraphProps extends Omit, 'nodeTypes' | 'width' | 'height'> { /** * @description graph 宽度 */ width?: string | number; /** * @description graph 高度 */ height?: string | number; /** * @description 背景颜色 */ background?: string; /** * @description 主题配置 */ theme?: BaseThemeConfig; nodeTypes?: Array>; /** * @description 是否显示控制器 * @default true */ showControls?: boolean; controlsPosition?: PanelPosition; controlsOrientation?: 'horizontal' | 'vertical'; showMiniMap?: boolean; getMiniMapNodeColor?: (node: Node) => string; showFullscreen?: boolean; /** * @description 是否显示布局优化操作 */ showForceLayout?: boolean; showInteractive?: boolean; showFitView?: boolean; showZoom?: boolean; /** * @description 是否显示图例 * @default false */ showLegend?: boolean; /** * @description 是否自动居中 * @default false */ autoCenter?: boolean; rootStyle?: React.CSSProperties; layout?: LayoutFunction; /** * @description 是否强制布局 * @default !!layout */ forceLayout?: boolean; markers?: MarkDefinition[]; plugins?: { scroller?: false | ScrollbarPluginOptions; }; /** * @description 是否开启 service worker 模式,当为数字时,检测当前的节点数量,节点数量大于配置阈值时启用 serviceWorker模式,否则直接在 js中执行;当为true时强制使用 service worker 执行计算逻辑。false时默认关闭 * @default false */ readOnly?: boolean; onZoomIn?: () => void; /** Called in addition the default zoom behavior when the zoom out button is clicked. */ onZoomOut?: () => void; /** * Called when the fit view button is clicked. When this is not provided, the viewport will be * adjusted so that all nodes are visible. */ onFitView?: () => void; /** Called when the interactive (lock) button is clicked. */ onInteractiveChange?: (interactiveStatus: boolean) => void; } export interface IBaseGraphStateWithOmitProps extends IBaseGraphProps { omitProps?: string[]; } export type TooltipState = { placement?: TooltipPlacement; title?: React.ReactNode; target?: HTMLElement; color?: TooltipProps['color']; }; export type PopoverState = { placement?: TooltipPlacement; title?: React.ReactNode; rootClassName?: string; content?: React.ReactNode; target?: HTMLElement; }; export type CollapseButtonProps = { position?: 'left' | 'right'; loading?: boolean; collapsed?: boolean; count: number; onCollapse?: (collapsed: boolean) => void; direction?: 'vertical' | 'horizontal'; }; export interface TreeNode { id: string; type: string; collapsed?: boolean; childCount?: number; children?: Array; } export interface BaseNodeData { id: string; type: string; } export type NodeRenderProps = NodeProps & { data: any; type: any; }; export type PopupTriggerEventType = { onMouseEnter?: (event: React.MouseEvent) => void; onMouseLeave?: (event: React.MouseEvent) => void; onPointerEnter?: (event: React.MouseEvent) => void; onPointerLeave?: (event: React.MouseEvent) => void; }; export {};