From e4ffabd5ab34ec5a5ddecc19a77a2ca55b9fd1e0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:10:16 +0000 Subject: [PATCH 1/8] Initial plan From 7509b6e027cf675e998d0287513cc114bc60ab47 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:17:20 +0000 Subject: [PATCH 2/8] Add MindMap component to ai directory with functional API pattern Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- package.json | 1 + src/ai/index.ts | 2 + src/ai/playground/index.html | 21 +++++ src/ai/playground/main.ts | 93 ++++++++++++++++++ src/ai/playground/package.json | 4 +- src/ai/types/index.ts | 16 ++++ src/ai/util/graph.ts | 45 +++++++++ src/ai/vis/mind-map/README.md | 161 ++++++++++++++++++++++++++++++++ src/ai/vis/mind-map/index.ts | 166 +++++++++++++++++++++++++++++++++ 9 files changed, 508 insertions(+), 1 deletion(-) create mode 100644 src/ai/types/index.ts create mode 100644 src/ai/util/graph.ts create mode 100644 src/ai/vis/mind-map/README.md create mode 100644 src/ai/vis/mind-map/index.ts diff --git a/package.json b/package.json index 5e99bbc4..bc3a53cc 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@zumer/snapdom": "^1.9.14", "copy-text-to-clipboard": "^3.2.2", "lodash": "^4.17.21", + "preact": "^10.28.2", "rc-resize-observer": "^1.4.3", "react-error-boundary": "^6.0.0", "react-markdown": "^9.1.0", diff --git a/src/ai/index.ts b/src/ai/index.ts index facb2820..841e5b18 100644 --- a/src/ai/index.ts +++ b/src/ai/index.ts @@ -39,3 +39,5 @@ export type { } from './vis/waterfall'; export { WordCloud } from './vis/word-cloud'; export type { WordCloudConfig, WordCloudDataItem, WordCloudOptions } from './vis/word-cloud'; +export { MindMap } from './vis/mind-map'; +export type { MindMapConfig, MindMapData, MindMapOptions } from './vis/mind-map'; diff --git a/src/ai/playground/index.html b/src/ai/playground/index.html index 39ec8c4c..503d673c 100644 --- a/src/ai/playground/index.html +++ b/src/ai/playground/index.html @@ -623,6 +623,27 @@

Custom Styles

+ +
+

MindMap (思维导图)

+
+
+

Basic MindMap - Project Plan

+
+
+ +
+

Academy Theme - Typhoon Formation Factors

+
+
+ +
+

AI Applications

+
+
+
+
+ diff --git a/src/ai/playground/main.ts b/src/ai/playground/main.ts index fca1f0db..7d1d61e1 100644 --- a/src/ai/playground/main.ts +++ b/src/ai/playground/main.ts @@ -16,6 +16,7 @@ import { Venn } from '../vis/venn/index'; import { Violin } from '../vis/violin/index'; import { Waterfall } from '../vis/waterfall/index'; import { WordCloud } from '../vis/word-cloud/index'; +import { MindMap } from '../vis/mind-map/index'; // Sample data const data = [ @@ -1951,3 +1952,95 @@ radarCustom.render({ lineWidth: 3, }, }); + +// MindMap Examples +// Example 1: Basic MindMap +const mindMapBasic = MindMap({ + container: document.getElementById('mind-map-basic')!, + width: 800, + height: 500, +}); + +mindMapBasic.render({ + type: 'mind-map', + data: { + name: '项目计划', + children: [ + { + name: '研究阶段', + children: [{ name: '市场调研' }, { name: '技术可行性分析' }], + }, + { + name: '设计阶段', + children: [{ name: '产品功能确定' }, { name: 'UI 设计' }], + }, + { + name: '开发阶段', + children: [{ name: '编写代码' }, { name: '单元测试' }], + }, + { + name: '测试阶段', + children: [{ name: '功能测试' }, { name: '性能测试' }], + }, + ], + }, +}); + +// Example 2: MindMap with Academy Theme +const mindMapAcademy = MindMap({ + container: document.getElementById('mind-map-academy')!, + width: 800, + height: 500, +}); + +mindMapAcademy.render({ + type: 'mind-map', + data: { + name: '台风形成的因素', + children: [ + { + name: '气象条件', + children: [ + { name: '温暖的海水' }, + { name: '气压分布' }, + { name: '湿度水平' }, + { name: '风的切变' }, + ], + }, + { + name: '地理环境', + children: [ + { name: '大陆架的形状与深度' }, + { name: '海洋暖流的分布' }, + { name: '热带地区的气候特征' }, + { name: '岛屿的影响' }, + ], + }, + ], + }, + theme: 'academy', +}); + +// Example 3: MindMap - AI Applications +const mindMapAI = MindMap({ + container: document.getElementById('mind-map-ai')!, + width: 800, + height: 500, +}); + +mindMapAI.render({ + type: 'mind-map', + data: { + name: '人工智能应用', + children: [ + { name: '智能家居' }, + { name: '自动驾驶' }, + { + name: '医疗保健', + children: [{ name: '精准医疗' }, { name: '诊断辅助' }], + }, + { name: '金融服务' }, + ], + }, +}); + diff --git a/src/ai/playground/package.json b/src/ai/playground/package.json index 82fc36cc..ffc2b86b 100644 --- a/src/ai/playground/package.json +++ b/src/ai/playground/package.json @@ -9,8 +9,10 @@ "preview": "vite preview" }, "dependencies": { + "@ant-design/graphs": "^2.1.1", "@antv/g2": "^5.4.1", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "preact": "^10.28.2" }, "devDependencies": { "@types/lodash": "^4.17.0", diff --git a/src/ai/types/index.ts b/src/ai/types/index.ts new file mode 100644 index 00000000..c8140291 --- /dev/null +++ b/src/ai/types/index.ts @@ -0,0 +1,16 @@ +/** + * Tree graph data structure + */ +export interface TreeGraphData { + name: string; + description?: string; // For OrganizationChart + children?: TreeGraphData[]; +} + +/** + * Network graph data structure + */ +export interface GraphData { + nodes: { name: string }[]; + edges: { source: string; target: string; name?: string }[]; +} diff --git a/src/ai/util/graph.ts b/src/ai/util/graph.ts new file mode 100644 index 00000000..5f807b42 --- /dev/null +++ b/src/ai/util/graph.ts @@ -0,0 +1,45 @@ +// Import G6 utilities from @ant-design/graphs +import { G6 } from '@ant-design/graphs'; +import type { TreeGraphData, GraphData } from '../types'; + +const { treeToGraphData } = G6; + +/** + * Transform tree data from vis format to G6 format + */ +export function visTreeData2GraphData(data: TreeGraphData) { + return treeToGraphData(data as unknown as G6.TreeData, { + getNodeData: (datum, depth) => { + datum.id = datum.name; + datum.depth = depth; + if (!datum.children) return datum as G6.NodeData; + const { children, ...restDatum } = datum; + return { + ...restDatum, + children: children.map((child) => child.name), + } as G6.NodeData; + }, + getEdgeData: (source, target) => + ({ + source: source.name, + target: target.name, + }) as G6.EdgeData, + }); +} + +/** + * Transform graph data from vis format to G6 format + */ +export function visGraphData2GraphData(data: GraphData) { + return { + nodes: data.nodes.map((node) => ({ + id: node.name, + style: { labelText: node.name }, + })), + edges: data.edges.map((edge) => ({ + source: edge.source, + target: edge.target, + style: { labelText: edge.name }, + })), + }; +} diff --git a/src/ai/vis/mind-map/README.md b/src/ai/vis/mind-map/README.md new file mode 100644 index 00000000..ec658389 --- /dev/null +++ b/src/ai/vis/mind-map/README.md @@ -0,0 +1,161 @@ +# MindMap + +A mind map for hierarchical information organization, built with @ant-design/graphs. + +## Usage + +```ts +import { MindMap } from '@antv/gpt-vis/ai'; + +const mindMap = MindMap({ + container: '#container', + width: 600, + height: 400, +}); + +mindMap.render({ + type: 'mind-map', + data: { + name: '项目计划', + children: [ + { + name: '研究阶段', + children: [{ name: '市场调研' }, { name: '技术可行性分析' }], + }, + { + name: '设计阶段', + children: [{ name: '产品功能确定' }, { name: 'UI 设计' }], + }, + { + name: '开发阶段', + children: [{ name: '编写代码' }, { name: '单元测试' }], + }, + { + name: '测试阶段', + children: [{ name: '功能测试' }, { name: '性能测试' }], + }, + ], + }, +}); + +mindMap.destroy(); +``` + +## Configuration + +### Constructor Options (MindMapOptions) + +| Property | Type | Default | Description | +| --------- | --------------------- | ------- | ----------------------------- | +| container | string \| HTMLElement | - | Container element or selector | +| width | number | 640 | Chart width in pixels | +| height | number | 480 | Chart height in pixels | + +### Render Config (MindMapConfig) + +| Property | Type | Default | Description | +| -------- | --------- | ----------- | -------------------------- | +| type | string | 'mind-map' | Component type identifier | +| data | object | - | Mind map data | +| theme | string | 'default' | Color theme | + +**Theme Options:** +- `'default'` - Default color scheme +- `'academy'` - Academy color scheme + +### Data Structure + +```ts +type MindMapData = { + name: string; + children?: MindMapData[]; +}; +``` + +**Fields:** +- `name` (required): Node name displayed in the mind map +- `children` (optional): Array of child nodes, creating a hierarchical tree structure + +## Examples + +### Basic Example + +```ts +mindMap.render({ + type: 'mind-map', + data: { + name: '人工智能应用', + children: [ + { name: '智能家居' }, + { name: '自动驾驶' }, + { + name: '医疗保健', + children: [{ name: '精准医疗' }, { name: '诊断辅助' }], + }, + { name: '金融服务' }, + ], + }, +}); +``` + +### With Academy Theme + +```ts +mindMap.render({ + type: 'mind-map', + data: { + name: '台风形成的因素', + children: [ + { + name: '气象条件', + children: [ + { name: '温暖的海水' }, + { name: '气压分布' }, + { name: '湿度水平' }, + { name: '风的切变' }, + ], + }, + { + name: '地理环境', + children: [ + { name: '大陆架的形状与深度' }, + { name: '海洋暖流的分布' }, + { name: '热带地区的气候特征' }, + { name: '岛屿的影响' }, + ], + }, + ], + }, + theme: 'academy', +}); +``` + +## Features + +- **Interactive Navigation**: Supports drag-canvas for panning around the mind map +- **Collapse/Expand**: Click on nodes to collapse or expand their children +- **Automatic Layout**: Uses boxed layout that distributes nodes on both sides of the root +- **Zoom Controls**: Zoom range from 0.1x to 5x +- **Auto Fit**: Automatically fits the entire graph into the view +- **Color-Coded Branches**: Each main branch has a distinct color for easy identification + +## Methods + +- `render(config: MindMapConfig): void` - Render or update the mind map +- `destroy(): void` - Destroy the mind map instance and clean up resources + +## Use Cases + +Mind maps are ideal for: +- Project planning and task breakdown +- Knowledge organization and note-taking +- Brainstorming and idea mapping +- Hierarchical information presentation +- Content structuring + +## Not Suitable For + +- Continuous narratives or stories +- Pure numerical or statistical data +- Unstructured or themeless information +- Precise operational steps or instructions diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts new file mode 100644 index 00000000..903842b3 --- /dev/null +++ b/src/ai/vis/mind-map/index.ts @@ -0,0 +1,166 @@ +import type { G6, MindMapOptions } from '@ant-design/graphs'; +import { MindMap as ADCMindMap } from '@ant-design/graphs'; +import { h, render as preactRender } from 'preact'; +import { visTreeData2GraphData } from '../../util/graph'; + +/** + * MindMap data type (tree structure) + */ +export type MindMapData = { + name: string; + children?: MindMapData[]; +}; + +/** + * MindMap initialization options + */ +export interface MindMapOptions { + container: string | HTMLElement; + width?: number; + height?: number; +} + +/** + * MindMap configuration for rendering + */ +export interface MindMapConfig { + type?: 'mind-map'; + data: MindMapData; + theme?: 'default' | 'academy'; +} + +/** + * MindMap instance with render and destroy methods + */ +export interface MindMapInstance { + render: (config: MindMapConfig) => void; + destroy: () => void; +} + +// Theme color mappings +const THEME_COLORS = { + default: [ + '#1783FF', + '#00C9C9', + '#F0884D', + '#D580FF', + '#7863FF', + '#60C42D', + '#BD8F24', + '#FF80CA', + '#2491B3', + '#17C76F', + ], + academy: [ + '#6B74E4', + '#4BBDE3', + '#F7C348', + '#EF7C69', + '#85CB56', + '#D284E5', + '#F09452', + '#A9AABC', + '#52C41A', + '#5B8FF9', + ], +}; + +/** + * MindMap using @ant-design/graphs. + * + * @example + * ```ts + * const mindMap = MindMap({ + * container: '#container', + * width: 600, + * height: 400, + * }); + * + * mindMap.render({ + * type: 'mind-map', + * data: { + * name: '项目计划', + * children: [ + * { name: '研究阶段' }, + * { name: '设计阶段' }, + * { name: '开发阶段' }, + * ], + * }, + * }); + * + * mindMap.destroy(); + * ``` + */ +export const MindMap = ( + options: MindMapOptions, +): MindMapInstance => { + const container = + typeof options.container === 'string' + ? document.querySelector(options.container) + : options.container; + + if (!container) { + throw new Error('Container not found'); + } + + const width = options.width || 640; + const height = options.height || 480; + + const render = (config: MindMapConfig): void => { + const { data, theme = 'default' } = config; + + // Transform data from vis format to G6 format + const graphData = visTreeData2GraphData(data); + + // Configure the mind map based on the existing React component + const graphConfig: MindMapOptions = { + data: graphData, + width, + height, + type: 'boxed', + autoFit: 'view', + autoResize: true, + padding: 2, + zoomRange: [0.1, 5], + zoom: 1, + node: { animation: { translate: false, update: false } }, + edge: { animation: { translate: false, update: false } }, + transforms: (prev: any[]) => [ + ...prev.filter( + (transform) => + (transform as G6.BaseTransformOptions).type !== + 'collapse-expand-react-node', + ), + { + ...(prev.find( + (transform: G6.CustomBehaviorOption) => + (transform as G6.BaseTransformOptions).type === + 'collapse-expand-react-node', + ) as G6.BaseTransformOptions), + enable: true, + }, + { + ...(prev.find( + (transform) => (transform as any).key === 'assign-color-by-branch', + ) || ({} as any)), + type: 'assign-color-by-branch', + colors: THEME_COLORS[theme], + }, + ], + behaviors: ['drag-canvas'], + }; + + // Render using preact + preactRender(h(ADCMindMap, graphConfig), container as HTMLElement); + }; + + const destroy = (): void => { + // Clean up by rendering null + preactRender(null, container as HTMLElement); + }; + + return { + render, + destroy, + }; +}; From 3fbe0c5de8a5a809c71c2dd5c9b98ff0cddd488e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:26:26 +0000 Subject: [PATCH 3/8] Fix type naming conflict in MindMap component Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- src/ai/vis/mind-map/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts index 903842b3..316278a1 100644 --- a/src/ai/vis/mind-map/index.ts +++ b/src/ai/vis/mind-map/index.ts @@ -1,4 +1,4 @@ -import type { G6, MindMapOptions } from '@ant-design/graphs'; +import type { G6, MindMapOptions as ADCMindMapOptions } from '@ant-design/graphs'; import { MindMap as ADCMindMap } from '@ant-design/graphs'; import { h, render as preactRender } from 'preact'; import { visTreeData2GraphData } from '../../util/graph'; @@ -113,7 +113,7 @@ export const MindMap = ( const graphData = visTreeData2GraphData(data); // Configure the mind map based on the existing React component - const graphConfig: MindMapOptions = { + const graphConfig: ADCMindMapOptions = { data: graphData, width, height, From 751b08e306e5819dc018febb4cbde4408a69798d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:30:26 +0000 Subject: [PATCH 4/8] Fix MindMap rendering by using React instead of Preact Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- src/ai/index.ts | 4 ++-- src/ai/playground/main.ts | 3 +-- src/ai/util/graph.ts | 2 +- src/ai/vis/mind-map/README.md | 13 +++++++----- src/ai/vis/mind-map/index.ts | 37 ++++++++++++++++++++--------------- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/ai/index.ts b/src/ai/index.ts index 841e5b18..b8517783 100644 --- a/src/ai/index.ts +++ b/src/ai/index.ts @@ -18,6 +18,8 @@ export { Line } from './vis/line'; export type { LineConfig, LineDataItem, LineOptions } from './vis/line'; export { Liquid } from './vis/liquid'; export type { LiquidConfig, LiquidOptions } from './vis/liquid'; +export { MindMap } from './vis/mind-map'; +export type { MindMapConfig, MindMapData, MindMapOptions } from './vis/mind-map'; export { Radar } from './vis/radar'; export type { RadarConfig, RadarDataItem, RadarOptions } from './vis/radar'; export { Sankey } from './vis/sankey'; @@ -39,5 +41,3 @@ export type { } from './vis/waterfall'; export { WordCloud } from './vis/word-cloud'; export type { WordCloudConfig, WordCloudDataItem, WordCloudOptions } from './vis/word-cloud'; -export { MindMap } from './vis/mind-map'; -export type { MindMapConfig, MindMapData, MindMapOptions } from './vis/mind-map'; diff --git a/src/ai/playground/main.ts b/src/ai/playground/main.ts index 7d1d61e1..745c5534 100644 --- a/src/ai/playground/main.ts +++ b/src/ai/playground/main.ts @@ -8,6 +8,7 @@ import { Funnel } from '../vis/funnel/index'; import { Histogram } from '../vis/histogram/index'; import { Line } from '../vis/line/index'; import { Liquid } from '../vis/liquid/index'; +import { MindMap } from '../vis/mind-map/index'; import { Radar } from '../vis/radar/index'; import { Sankey } from '../vis/sankey/index'; import { Scatter } from '../vis/scatter/index'; @@ -16,7 +17,6 @@ import { Venn } from '../vis/venn/index'; import { Violin } from '../vis/violin/index'; import { Waterfall } from '../vis/waterfall/index'; import { WordCloud } from '../vis/word-cloud/index'; -import { MindMap } from '../vis/mind-map/index'; // Sample data const data = [ @@ -2043,4 +2043,3 @@ mindMapAI.render({ ], }, }); - diff --git a/src/ai/util/graph.ts b/src/ai/util/graph.ts index 5f807b42..a262b70a 100644 --- a/src/ai/util/graph.ts +++ b/src/ai/util/graph.ts @@ -1,6 +1,6 @@ // Import G6 utilities from @ant-design/graphs import { G6 } from '@ant-design/graphs'; -import type { TreeGraphData, GraphData } from '../types'; +import type { GraphData, TreeGraphData } from '../types'; const { treeToGraphData } = G6; diff --git a/src/ai/vis/mind-map/README.md b/src/ai/vis/mind-map/README.md index ec658389..d2a42201 100644 --- a/src/ai/vis/mind-map/README.md +++ b/src/ai/vis/mind-map/README.md @@ -53,13 +53,14 @@ mindMap.destroy(); ### Render Config (MindMapConfig) -| Property | Type | Default | Description | -| -------- | --------- | ----------- | -------------------------- | -| type | string | 'mind-map' | Component type identifier | -| data | object | - | Mind map data | -| theme | string | 'default' | Color theme | +| Property | Type | Default | Description | +| -------- | ------ | ---------- | ------------------------- | +| type | string | 'mind-map' | Component type identifier | +| data | object | - | Mind map data | +| theme | string | 'default' | Color theme | **Theme Options:** + - `'default'` - Default color scheme - `'academy'` - Academy color scheme @@ -73,6 +74,7 @@ type MindMapData = { ``` **Fields:** + - `name` (required): Node name displayed in the mind map - `children` (optional): Array of child nodes, creating a hierarchical tree structure @@ -147,6 +149,7 @@ mindMap.render({ ## Use Cases Mind maps are ideal for: + - Project planning and task breakdown - Knowledge organization and note-taking - Brainstorming and idea mapping diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts index 316278a1..f17edd7f 100644 --- a/src/ai/vis/mind-map/index.ts +++ b/src/ai/vis/mind-map/index.ts @@ -1,6 +1,7 @@ -import type { G6, MindMapOptions as ADCMindMapOptions } from '@ant-design/graphs'; +import type { MindMapOptions as ADCMindMapOptions, G6 } from '@ant-design/graphs'; import { MindMap as ADCMindMap } from '@ant-design/graphs'; -import { h, render as preactRender } from 'preact'; +import React from 'react'; +import { createRoot, type Root } from 'react-dom/client'; import { visTreeData2GraphData } from '../../util/graph'; /** @@ -91,9 +92,7 @@ const THEME_COLORS = { * mindMap.destroy(); * ``` */ -export const MindMap = ( - options: MindMapOptions, -): MindMapInstance => { +export const MindMap = (options: MindMapOptions): MindMapInstance => { const container = typeof options.container === 'string' ? document.querySelector(options.container) @@ -105,6 +104,7 @@ export const MindMap = ( const width = options.width || 640; const height = options.height || 480; + let root: Root | null = null; const render = (config: MindMapConfig): void => { const { data, theme = 'default' } = config; @@ -128,21 +128,18 @@ export const MindMap = ( transforms: (prev: any[]) => [ ...prev.filter( (transform) => - (transform as G6.BaseTransformOptions).type !== - 'collapse-expand-react-node', + (transform as G6.BaseTransformOptions).type !== 'collapse-expand-react-node', ), { ...(prev.find( (transform: G6.CustomBehaviorOption) => - (transform as G6.BaseTransformOptions).type === - 'collapse-expand-react-node', + (transform as G6.BaseTransformOptions).type === 'collapse-expand-react-node', ) as G6.BaseTransformOptions), enable: true, }, { - ...(prev.find( - (transform) => (transform as any).key === 'assign-color-by-branch', - ) || ({} as any)), + ...(prev.find((transform) => (transform as any).key === 'assign-color-by-branch') || + ({} as any)), type: 'assign-color-by-branch', colors: THEME_COLORS[theme], }, @@ -150,13 +147,21 @@ export const MindMap = ( behaviors: ['drag-canvas'], }; - // Render using preact - preactRender(h(ADCMindMap, graphConfig), container as HTMLElement); + // Create root if it doesn't exist + if (!root) { + root = createRoot(container as HTMLElement); + } + + // Render using React + root.render(React.createElement(ADCMindMap, graphConfig)); }; const destroy = (): void => { - // Clean up by rendering null - preactRender(null, container as HTMLElement); + // Clean up by unmounting + if (root) { + root.unmount(); + root = null; + } }; return { From fb91de742dc315d2051d91d463ea84a807e4e0fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 06:38:01 +0000 Subject: [PATCH 5/8] Remove unused preact dependency Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- package.json | 1 - src/ai/playground/package.json | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index bc3a53cc..5e99bbc4 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "@zumer/snapdom": "^1.9.14", "copy-text-to-clipboard": "^3.2.2", "lodash": "^4.17.21", - "preact": "^10.28.2", "rc-resize-observer": "^1.4.3", "react-error-boundary": "^6.0.0", "react-markdown": "^9.1.0", diff --git a/src/ai/playground/package.json b/src/ai/playground/package.json index ffc2b86b..8a6a0e8a 100644 --- a/src/ai/playground/package.json +++ b/src/ai/playground/package.json @@ -11,8 +11,7 @@ "dependencies": { "@ant-design/graphs": "^2.1.1", "@antv/g2": "^5.4.1", - "lodash": "^4.17.21", - "preact": "^10.28.2" + "lodash": "^4.17.21" }, "devDependencies": { "@types/lodash": "^4.17.0", From 7058d2b0c5032641851b9fbe1359634131b9283e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 07:02:26 +0000 Subject: [PATCH 6/8] fix: use G6THEME_MAP for MindMap color configuration Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- src/ai/util/theme.ts | 15 +++++++++++++++ src/ai/vis/mind-map/index.ts | 32 ++------------------------------ 2 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/ai/util/theme.ts b/src/ai/util/theme.ts index e11480c3..4fe7fb59 100644 --- a/src/ai/util/theme.ts +++ b/src/ai/util/theme.ts @@ -44,3 +44,18 @@ export const getBackgroundColor = (theme: string): string => { return '#FFF'; } }; + +/** + * G6 theme map for graph components. + * Used by MindMap, OrganizationChart, IndentedTree, FishboneDiagram, etc. + */ +export const G6THEME_MAP: any = { + default: { + type: 'assign-color-by-branch', + colors: DEFAULT_COLOR_PALETTE, + }, + academy: { + type: 'assign-color-by-branch', + colors: ACADEMY_COLOR_PALETTE, + }, +}; diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts index f17edd7f..46b56530 100644 --- a/src/ai/vis/mind-map/index.ts +++ b/src/ai/vis/mind-map/index.ts @@ -3,6 +3,7 @@ import { MindMap as ADCMindMap } from '@ant-design/graphs'; import React from 'react'; import { createRoot, type Root } from 'react-dom/client'; import { visTreeData2GraphData } from '../../util/graph'; +import { G6THEME_MAP } from '../../util/theme'; /** * MindMap data type (tree structure) @@ -38,34 +39,6 @@ export interface MindMapInstance { destroy: () => void; } -// Theme color mappings -const THEME_COLORS = { - default: [ - '#1783FF', - '#00C9C9', - '#F0884D', - '#D580FF', - '#7863FF', - '#60C42D', - '#BD8F24', - '#FF80CA', - '#2491B3', - '#17C76F', - ], - academy: [ - '#6B74E4', - '#4BBDE3', - '#F7C348', - '#EF7C69', - '#85CB56', - '#D284E5', - '#F09452', - '#A9AABC', - '#52C41A', - '#5B8FF9', - ], -}; - /** * MindMap using @ant-design/graphs. * @@ -140,8 +113,7 @@ export const MindMap = (options: MindMapOptions): MindMapInstance => { { ...(prev.find((transform) => (transform as any).key === 'assign-color-by-branch') || ({} as any)), - type: 'assign-color-by-branch', - colors: THEME_COLORS[theme], + ...G6THEME_MAP[theme], }, ], behaviors: ['drag-canvas'], From e1a22fbd616a5352d9aac9aa58948e9b91f832c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 07:39:29 +0000 Subject: [PATCH 7/8] refactor: switch MindMap from React to Preact for smaller bundle size Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- package.json | 1 + src/ai/playground/package.json | 1 + src/ai/playground/vite.config.js | 2 ++ src/ai/vis/mind-map/index.ts | 24 +++++++----------------- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 5e99bbc4..bc3a53cc 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "@zumer/snapdom": "^1.9.14", "copy-text-to-clipboard": "^3.2.2", "lodash": "^4.17.21", + "preact": "^10.28.2", "rc-resize-observer": "^1.4.3", "react-error-boundary": "^6.0.0", "react-markdown": "^9.1.0", diff --git a/src/ai/playground/package.json b/src/ai/playground/package.json index 8a6a0e8a..7c9fd6e8 100644 --- a/src/ai/playground/package.json +++ b/src/ai/playground/package.json @@ -14,6 +14,7 @@ "lodash": "^4.17.21" }, "devDependencies": { + "@preact/preset-vite": "^2.10.3", "@types/lodash": "^4.17.0", "typescript": "^5.0.0", "vite": "^5.0.0" diff --git a/src/ai/playground/vite.config.js b/src/ai/playground/vite.config.js index ff01ab8d..80d19a8e 100644 --- a/src/ai/playground/vite.config.js +++ b/src/ai/playground/vite.config.js @@ -1,7 +1,9 @@ +import preact from '@preact/preset-vite'; import { resolve } from 'path'; import { defineConfig } from 'vite'; export default defineConfig({ + plugins: [preact()], root: './', resolve: { alias: { diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts index 46b56530..6cfb8598 100644 --- a/src/ai/vis/mind-map/index.ts +++ b/src/ai/vis/mind-map/index.ts @@ -1,7 +1,6 @@ import type { MindMapOptions as ADCMindMapOptions, G6 } from '@ant-design/graphs'; import { MindMap as ADCMindMap } from '@ant-design/graphs'; -import React from 'react'; -import { createRoot, type Root } from 'react-dom/client'; +import { createElement, render } from 'preact/compat'; import { visTreeData2GraphData } from '../../util/graph'; import { G6THEME_MAP } from '../../util/theme'; @@ -77,9 +76,8 @@ export const MindMap = (options: MindMapOptions): MindMapInstance => { const width = options.width || 640; const height = options.height || 480; - let root: Root | null = null; - const render = (config: MindMapConfig): void => { + const renderComponent = (config: MindMapConfig): void => { const { data, theme = 'default' } = config; // Transform data from vis format to G6 format @@ -119,25 +117,17 @@ export const MindMap = (options: MindMapOptions): MindMapInstance => { behaviors: ['drag-canvas'], }; - // Create root if it doesn't exist - if (!root) { - root = createRoot(container as HTMLElement); - } - - // Render using React - root.render(React.createElement(ADCMindMap, graphConfig)); + // Render using Preact compat (compatible with React components from @ant-design/graphs) + render(createElement(ADCMindMap, graphConfig), container as HTMLElement); }; const destroy = (): void => { - // Clean up by unmounting - if (root) { - root.unmount(); - root = null; - } + // Clean up by rendering null + render(null, container as HTMLElement); }; return { - render, + render: renderComponent, destroy, }; }; From c7394cfde96f9113fe2d88cc554201fbcdb8d160 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 07:55:27 +0000 Subject: [PATCH 8/8] feat: add zoom-canvas behavior to MindMap for zooming functionality Co-authored-by: hustcc <7856674+hustcc@users.noreply.github.com> --- src/ai/vis/mind-map/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ai/vis/mind-map/index.ts b/src/ai/vis/mind-map/index.ts index 6cfb8598..3ac58ed3 100644 --- a/src/ai/vis/mind-map/index.ts +++ b/src/ai/vis/mind-map/index.ts @@ -114,7 +114,7 @@ export const MindMap = (options: MindMapOptions): MindMapInstance => { ...G6THEME_MAP[theme], }, ], - behaviors: ['drag-canvas'], + behaviors: ['drag-canvas', 'zoom-canvas'], }; // Render using Preact compat (compatible with React components from @ant-design/graphs)