Skip to content
This repository was archived by the owner on Apr 11, 2025. It is now read-only.

Commit 7040807

Browse files
committed
✨ feat: 添加节点折叠效果
1 parent 3edeaa4 commit 7040807

13 files changed

Lines changed: 144 additions & 54 deletions

File tree

docs/components/biz/examples/Mindflow/Basic.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,37 @@ const data: GraphData<MindflowData> = {
66
{
77
id: 'node1',
88
data: {
9-
text: '这是一个 问题 节点',
9+
title: '这是一个 问题 节点',
1010
type: 'question',
1111
},
1212
},
1313
{
1414
id: 'node2',
1515
data: {
16-
text: '这是一个 思路 节点',
16+
title: '这是一个 思路 节点',
1717
type: 'idea',
1818
},
1919
},
2020
{
2121
id: 'node3',
2222
data: {
23-
text: '这是一个未定节点',
23+
title: '这是一个未定节点',
2424
},
2525
},
2626
{
2727
id: 'node4',
2828
data: {
29-
text: '这是一个 行动点 节点',
29+
title: '这是一个 行动点 节点',
3030
type: 'action',
3131
},
3232
},
3333
{
3434
id: 'node5',
3535
data: {
36-
text:
37-
'这是一个超长文本节点: 永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修稧(禊)事也。',
36+
title:
37+
'这是一个可折叠的节点: 永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修稧(禊)事也。',
38+
description:
39+
' 永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修稧(禊)事也。',
3840
type: 'action',
3941
},
4042
},

docs/components/biz/examples/Mindflow/Connect.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@ const data: GraphData<MindflowData> = {
66
{
77
id: 'node1',
88
data: {
9-
text: '这是一个 问题 节点',
9+
title: '这是一个 问题 节点',
1010
type: 'question',
1111
},
1212
},
1313
{
1414
id: 'node2',
1515
data: {
16-
text: '这是一个 思路 节点',
16+
title: '这是一个 思路 节点',
1717
type: 'idea',
1818
},
1919
},
2020
{
2121
id: 'node3',
2222
data: {
23-
text: '这是一个未定节点',
23+
title: '这是一个未定节点',
2424
},
2525
},
2626
{
2727
id: 'node4',
2828
data: {
29-
text:
29+
title:
3030
'这是一个超长文本节点: 永和九年,岁在癸丑,暮春之初,会于会稽山阴之兰亭,修稧(禊)事也。',
3131
type: 'action',
3232
},

packages/mindflow/src/components/MindNode/index.tsx

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import type { FC } from 'react';
2-
import React from 'react';
3-
import { PlusOutlined, MinusOutlined } from '@ant-design/icons';
2+
import React, { useState } from 'react';
3+
import {
4+
PlusOutlined,
5+
MinusOutlined,
6+
CaretUpOutlined,
7+
CaretDownOutlined,
8+
} from '@ant-design/icons';
49
import chorma from 'chroma-js';
510
import type { ReactShape } from '@antv/x6-react-shape';
11+
import cls from 'classnames';
612

713
import { mapColorToHex, mapTypeToColor } from '../../utils';
8-
914
import type { NodeData } from '../../types';
1015

1116
import './style.less';
@@ -16,9 +21,14 @@ interface BaseNodeProps {
1621

1722
const MindNode: FC<BaseNodeProps> = ({ node }) => {
1823
const data = node.getData<NodeData>();
19-
const { type, collapsed, hasChildren } = data;
24+
25+
const { type, collapsed, leaf = true, title, description } = data;
2026
const baseColor = chorma(mapColorToHex(mapTypeToColor(type)));
2127

28+
const [unfold, setUnfold] = useState(false);
29+
30+
const cantFold = !description;
31+
2232
return (
2333
<div
2434
className="mind-node-container"
@@ -28,9 +38,34 @@ const MindNode: FC<BaseNodeProps> = ({ node }) => {
2838
borderLeftColor: baseColor.hex(),
2939
}}
3040
>
31-
<div className="mind-node-title">{data.text}</div>
41+
<div className="mind-node-header">
42+
{cantFold ? null : (
43+
<span
44+
className="mind-node-arrow"
45+
onClick={() => {
46+
setUnfold(!unfold);
47+
}}
48+
>
49+
{unfold ? <CaretUpOutlined /> : <CaretDownOutlined />}
50+
</span>
51+
)}
52+
53+
<div
54+
className={cls(
55+
'mind-node-title',
56+
unfold ? 'mind-node-title-expand' : '',
57+
)}
58+
>
59+
{title}
60+
</div>
61+
</div>
62+
{unfold ? (
63+
<div>
64+
<div className="mind-node-desc">{description}</div>
65+
</div>
66+
) : null}
3267

33-
{hasChildren ? (
68+
{leaf ? null : (
3469
<div
3570
className="mind-node-collapse"
3671
style={{ borderColor: baseColor.hex() }}
@@ -47,7 +82,7 @@ const MindNode: FC<BaseNodeProps> = ({ node }) => {
4782
/>
4883
)}
4984
</div>
50-
) : null}
85+
)}
5186
</div>
5287
);
5388
};

packages/mindflow/src/components/MindNode/style.less

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
1+
@import '../../themes/theme';
2+
13
.mind-node {
24
&-container {
35
position: relative;
46
padding: 8px;
7+
padding-left: 4px;
58
border: 1px solid transparent;
69
border-left-width: 4px;
710
border-radius: 4px;
811
}
12+
&-header {
13+
display: flex;
14+
}
15+
16+
&-arrow {
17+
color: @text-color-secondary;
18+
cursor: pointer;
19+
}
920

1021
&-title {
11-
display: -webkit-box;
12-
overflow: hidden;
13-
text-overflow: ellipsis;
14-
-webkit-box-orient: vertical;
15-
-webkit-line-clamp: 2; // 以此类推,3行4行直接该数字就好啦
22+
margin-left: 4px;
23+
overflow: hidden; //超出的隐藏
24+
white-space: nowrap; //强制一行显示
25+
text-overflow: ellipsis; //省略号
26+
&-expand {
27+
display: -webkit-box;
28+
white-space: normal;
29+
-webkit-box-orient: vertical;
30+
-webkit-line-clamp: 2; // 以此类推,3行4行直接该数字就好啦
31+
}
32+
}
33+
34+
&-desc {
35+
margin-top: 4px;
36+
margin-left: 4px;
37+
color: @text-color-secondary;
38+
font-size: 12px;
1639
}
1740

1841
&-collapse {
@@ -28,6 +51,7 @@
2851
border: 1px solid transparent;
2952
border-radius: 20px;
3053
transform: translateY(-50%);
54+
cursor: pointer;
3155

3256
&-icon {
3357
font-size: 13px;

packages/mindflow/src/definition/defaultConfig.tsx renamed to packages/mindflow/src/definition/edge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Shape.Edge.config({
99
strokeWidth: 1,
1010
targetMarker: {
1111
tagName: 'path',
12-
d: 'Z',
12+
d: 'M0 0 Z',
1313
},
1414
},
1515
},

packages/mindflow/src/definition/graphOpts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Options } from '@antv/x6/lib/graph/options';
22
import { minimapOpts } from './minimapOpts';
33
import { port } from './port';
4+
import './edge';
45

56
/**
67
* 生成图的配置项

packages/mindflow/src/definition/register.tsx

Lines changed: 0 additions & 17 deletions
This file was deleted.

packages/mindflow/src/hooks/useGraph.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { useEffect, useRef, useState } from 'react';
22
import { Graph } from '@antv/x6';
33
import { graphOpts } from '../definition/graphOpts';
4-
import '../definition/register';
54
import { layout, preprocessData } from '../utils';
5+
import { useGraphRegister } from './useRegister';
66

77
export const useGraph = (data) => {
88
const container = useRef();
99
const minimapContainer = useRef();
1010
const [graph, setGraph] = useState<Graph>(null);
1111

12+
useGraphRegister();
13+
1214
useEffect(() => {
1315
if (!container.current) return;
1416

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import '@antv/x6-react-shape';
2+
import React from 'react';
3+
import { Graph } from '@antv/x6';
4+
import { useEffect } from 'react';
5+
import { MindNode } from '../components';
6+
7+
declare global {
8+
interface Window {
9+
__IS_REGISTERED_MIND_NODE__: boolean;
10+
}
11+
}
12+
13+
export const useGraphRegister = () => {
14+
useEffect(() => {
15+
if (!window.__IS_REGISTERED_MIND_NODE__) {
16+
// 注册返回 React 组件的函数
17+
Graph.registerReactComponent('mind-node', <MindNode />);
18+
window.__IS_REGISTERED_MIND_NODE__ = true;
19+
}
20+
return () => {
21+
Graph.unregisterReactComponent('mind-node');
22+
window.__IS_REGISTERED_MIND_NODE__ = false;
23+
};
24+
}, []);
25+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@text-color: rgba(0, 0, 0, 0.85);
2+
@text-color-secondary: rgba(0, 0, 0, 0.5);

0 commit comments

Comments
 (0)