Skip to content

Commit 54f6a8c

Browse files
Merge pull request #9 from SeasonsChange422/master
refactor(MindMapTree): 优化思维导图布局和文本截断逻辑
2 parents 7ef9f17 + 2823b02 commit 54f6a8c

2 files changed

Lines changed: 103 additions & 29 deletions

File tree

prompto-lab-ui/.gitignore

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,64 @@
1-
# Logs
2-
logs
3-
*.log
1+
# Dependencies
2+
node_modules/
43
npm-debug.log*
54
yarn-debug.log*
65
yarn-error.log*
76
pnpm-debug.log*
8-
lerna-debug.log*
97

10-
node_modules
8+
# Production builds
9+
dist/
10+
build/
11+
12+
# Environment variables
13+
.env
14+
.env.local
15+
.env.development.local
16+
.env.test.local
17+
.env.production.local
18+
19+
# IDE and editor files
20+
.vscode/
21+
.idea/
22+
*.swp
23+
*.swo
24+
*~
25+
26+
# OS generated files
1127
.DS_Store
12-
dist
13-
dist-ssr
14-
coverage
15-
*.local
16-
17-
/cypress/videos/
18-
/cypress/screenshots/
19-
20-
# Editor directories and files
21-
.vscode/*
22-
!.vscode/extensions.json
23-
.idea
24-
*.suo
25-
*.ntvs*
26-
*.njsproj
27-
*.sln
28-
*.sw?
28+
.DS_Store?
29+
._*
30+
.Spotlight-V100
31+
.Trashes
32+
ehthumbs.db
33+
Thumbs.db
34+
35+
# Logs
36+
logs
37+
*.log
38+
39+
# Runtime data
40+
pids
41+
*.pid
42+
*.seed
43+
*.pid.lock
44+
45+
# Coverage directory used by tools like istanbul
46+
coverage/
47+
*.lcov
2948

49+
# TypeScript cache
3050
*.tsbuildinfo
51+
52+
# Optional npm cache directory
53+
.npm
54+
55+
# Optional eslint cache
56+
.eslintcache
57+
58+
# Webpack bundle analyzer
59+
bundle-analyzer-report.html
60+
61+
# Temporary folders
62+
tmp/
63+
temp/
64+
pnpm-lock.yaml

prompto-lab-ui/src/components/MindMapTree.vue

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,24 +178,54 @@ const layoutNodes = computed(() => {
178178
const nodes: LayoutNode[] = []
179179
const nodeWidth = 200 // 增加节点宽度
180180
const nodeHeight = 45 // 稍微增加节点高度
181-
const levelGap = Math.max(250, containerWidth.value / 6) // 动态调整层级间距
181+
const levelGap = Math.min(280, Math.max(220, containerWidth.value / 8)) // 限制最大层级间距,使布局更紧凑
182182
const siblingGap = 70 // 增加兄弟节点间距
183+
const truncateText = (text: string, maxWidth: number) => {
184+
// 基于节点宽度和字体大小计算最大字符数
185+
// 节点宽度200px,减去图标35px和右侧边距20px,可用宽度约145px
186+
// 字体大小13px,平均字符宽度约8px(中文)或6px(英文)
187+
const availableWidth = maxWidth - 55 // 减去图标和边距
188+
const avgCharWidth = /[\u4e00-\u9fa5]/.test(text) ? 8 : 6 // 中文字符更宽
189+
const maxChars = Math.floor(availableWidth / avgCharWidth)
183190
191+
if (text.length <= maxChars) {
192+
return text
193+
}
194+
195+
// 优先在标点符号处截断
196+
const punctuation = /[。!?;,、]/
197+
let truncateIndex = maxChars - 4 // 为省略号留空间
198+
199+
// 向前查找最近的标点符号
200+
for (let i = truncateIndex; i >= Math.max(0, truncateIndex - 10); i--) {
201+
if (punctuation.test(text[i])) {
202+
truncateIndex = i + 1
203+
break
204+
}
205+
}
206+
207+
// 避免在单词中间截断(英文)
208+
if (!/[\u4e00-\u9fa5]/.test(text)) {
209+
while (truncateIndex > 0 && text[truncateIndex] !== ' ' && text[truncateIndex - 1] !== ' ') {
210+
truncateIndex--
211+
}
212+
}
213+
214+
return text.substring(0, truncateIndex).trim() + '...'
215+
}
184216
// 计算每个节点的位置
185217
const calculateLayout = (nodeId: string, level: number, siblingIndex: number, parentX?: number, parentY?: number) => {
186218
const node = props.conversationTree.get(nodeId)
187219
if (!node) return
188220
189-
const truncatedText = node.content.length > 25
190-
? node.content.substring(0, 25) + '...'
191-
: node.content
221+
const truncatedText = truncateText(node.content, nodeWidth)
192222
193223
let x: number
194224
let y: number
195225
196226
if (level === 0) {
197-
// 根节点居中
198-
x = svgWidth.value / 2 - nodeWidth / 2
227+
// 根节点位置优化 - 不完全居中,留出更多右侧空间
228+
x = Math.min(100, svgWidth.value / 6)
199229
y = 60
200230
} else {
201231
// 子节点布局
@@ -343,7 +373,7 @@ onUnmounted(() => {
343373
border-left: 1px solid rgba(212, 175, 55, 0.2);
344374
overflow: hidden;
345375
position: relative;
346-
min-width: 1200px;
376+
/* min-width: 1200px; */
347377
width: 100%; /* 确保占满父容器 */
348378
}
349379
@@ -547,8 +577,18 @@ onUnmounted(() => {
547577
font-family: 'Inter', 'SF Pro Display', sans-serif;
548578
font-weight: 500;
549579
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
580+
/* 添加文字渲染优化 */
581+
text-rendering: optimizeLegibility;
582+
-webkit-font-smoothing: antialiased;
583+
/* 确保文字不会溢出节点 */
584+
dominant-baseline: middle;
550585
}
551586
587+
/* 添加省略号样式优化 */
588+
.node-text::after {
589+
content: '';
590+
/* 可以通过伪元素添加更好的省略号效果 */
591+
}
552592
.node-group:hover .node-text {
553593
font-weight: 600;
554594
fill: #ffffff;

0 commit comments

Comments
 (0)