Zum Hauptinhalt springen
clawam tools
Werkzeuge Dokumente Daoark EN Startseite Startseite / Bildwerkzeuge › Startseite manifest.json "']/g, function(c) { return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; }); } // 解析层级文本 function parseTree(text) { var lines = text.split('\n').filter(function(l) { return l.length > 0; }); var root = { name: '', level: -1, children: [] }; var stack = [root]; for (var i = 0; i < lines.length; i++) { var line = lines[i].replace(/\t/g, ' '); var m = line.match(/^(\s*)(.*)$/); var indent = m[1].length / 2; // 每 2 空格一级 var content = m[2].trim(); if (!content) continue; var node = { name: content, level: Math.round(indent), children: [] }; // 找到父级 while (stack.length > 1 && stack[stack.length - 1].level >= node.level) stack.pop(); stack[stack.length - 1].children.push(node); stack.push(node); } return root.children[0] || null; } // 递归计算每个节点子树高度(节点数) function subtreeSize(node) { if (node.children.length === 0) return 1; var s = 1; for (var i = 0; i < node.children.length; i++) s += subtreeSize(node.children[i]); return s; } // 布局:返回每个节点 x, y function layout(node, x0, y0, dir) { // 简化布局:右向,根在 (x0, y0),子节点向右 var positions = {}; // id -> {x, y} var lines = []; // 连线 var curY = y0; var colors = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#06b6d4', '#84cc16']; var nodeCounter = 0; function dfs(n, depth, isRoot) { var id = 'n' + (nodeCounter++); var px, py; if (isRoot) { px = x0; py = y0; } else if (dir === 'right') { px = x0 + depth * 200; py = n._y; // 由父节点计算 } else if (dir === 'down') { px = n._x; py = y0 + depth * 80; } else { // both: 根在中央,子节点左右交替 if (depth === 0) { px = x0; py = y0; } else if (depth % 2 === 1) { px = x0 + Math.ceil(depth / 2) * 200; py = n._y; } else { px = x0 - Math.ceil(depth / 2) * 200; py = n._y; } } positions[id] = { x: px, y: py, name: n.name, depth: depth, color: colors[Math.min(depth, colors.length - 1)] }; if (n._parent) lines.push({ from: positions[n._parent], to: positions[id] }); var childY = py - (subtreeSize(n) - 1) * 25; for (var i = 0; i < n.children.length; i++) { var c = n.children[i]; c._y = childY + subtreeSize(c) * 25 / 2; c._x = px; c._parent = id; var cid = dfs(c, depth + 1, false); childY += subtreeSize(c) * 50; } return id; } node._parent = null; dfs(node, 0, true); return { positions: positions, lines: lines }; } function render(node, dir) { if (!node) return ''; var size = subtreeSize(node); var W, H; if (dir === 'right') { W = 100 + size * 200; H = size * 60; } else if (dir === 'down') { W = size * 200; H = size * 80; } else { W = size * 400; H = size * 60; } var cx = W / 2, cy = H / 2; var lay = layout(node, cx, cy, dir); var keys = Object.keys(lay.positions); var svg = ''; // 连线 for (var i = 0; i < lay.lines.length; i++) { var l = lay.lines[i]; svg += ''; } // 节点 for (var j = 0; j < keys.length; j++) { var p = lay.positions[keys[j]]; var w = 100 + p.name.length * 12, h = 40; if (w > 240) w = 240; var x = p.x - w / 2, y = p.y - h / 2; svg += ''; svg += '' + escape(p.name) + ''; } svg += ''; return svg; } var currentSVG = ''; function doProcess() { try { var text = getVal('text-a'); if (!text) { showError('请输入'); return; } var dir = getVal('direction'); var root = parseTree(text); if (!root) { showError('无有效数据'); return; } currentSVG = render(root, dir); showResult(currentSVG, '思维导图,' + dir + ' 布局,根: ' + root.name); } catch (e) { showError('生成失败: ' + (e.message || e)); } } $('btn-main').addEventListener('click', function(e) { e.preventDefault(); doProcess(); }); $('btn-download').addEventListener('click', function() { if (!currentSVG) return; var blob = new Blob([currentSVG], { type: 'image/svg+xml' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'mindmap.svg'; a.click(); URL.revokeObjectURL(url); }); $('btn-clear').addEventListener('click', function() { var inputs = document.querySelectorAll('input,textarea,select'); for (var i = 0; i < inputs.length; i++) { if (inputs[i].tagName === 'SELECT') inputs[i].selectedIndex = 0; else inputs[i].value = inputs[i].defaultValue; } var ra = $('result-area'); ra.hidden = true; ra.style.display = 'none'; var em = $('error-msg'); em.hidden = true; em.style.display = 'none'; $('btn-download').style.display = 'none'; }); })();