Oh MyUtils

Mermaid图表编辑器 - 在线创建流程图和图表

使用Mermaid.js实时预览创建流程图、时序图、ER图等20多种图表类型。导出为SVG/PNG — 100%客户端处理,数据不发送到服务器。

常见问题

什么是 Mermaid 图表编辑器?

Mermaid 图表编辑器是一个在线工具,让你可以使用 Mermaid.js(一种基于文本的图表语言)来创建图表。你无需拖放图形,只需编写简单的类 Markdown 语法(例如 graph TD; A-->B),编辑器就会实时将其渲染为可视化图表。Mermaid 支持超过 20 种图表类型,包括流程图、时序图、类图、ER 图、甘特图、思维导图等。

如何使用这个 Mermaid 图表编辑器?

从模板下拉菜单中选择一个图表模板(例如流程图或时序图),或从头开始编写 Mermaid 代码。在你输入时,预览面板会实时更新。如果存在语法错误,会出现红色的'Invalid'徽章。选择 Mermaid 主题(Default、Dark、Forest、Neutral)来更改视觉样式。满意后,点击下载 SVG 或下载 PNG 来导出你的图表。

我的图表数据安全吗?会有数据发送到服务器吗?

所有图表渲染都使用 mermaid.js JavaScript 库在你的浏览器中 100% 客户端执行。图表代码、渲染的图像和用户数据都不会传输到任何服务器。你的图表仅存在于浏览器的内存和 localStorage 中。这使得该工具可以安全地用于专有架构图、内部数据库架构和机密文档。

Mermaid 支持哪些图表类型?

Mermaid.js 支持超过 20 种图表类型:流程图(流程处理)、时序图(参与者交互)、类图(面向对象结构)、状态图(状态机)、ER 图(数据库架构)、甘特图(项目时间线)、饼图(比例数据)、思维导图(想法层级)、Git 图(分支可视化)、时间线(按时间排列的事件),以及更多类型包括 C4、桑基图、XY 图表、看板和架构图。

如何将图表导出为图片?

点击下载 SVG 获取可缩放矢量图形,在任何尺寸下都保持清晰——非常适合文档使用。点击下载 PNG 获取光栅图像,可选择缩放比例(1x、视网膜屏 2x、打印 3x)和透明或白色背景。你还可以点击复制 SVG 将 SVG 标记复制到剪贴板,以便粘贴到 Figma 等设计工具中。

我可以与他人分享我的图表吗?

可以。图表代码和主题会编码在页面 URL 中。只需从浏览器地址栏复制 URL 并分享即可。当其他人打开链接时,他们会看到你的完整图表,并可以进一步编辑。不涉及任何服务器存储——图表数据直接嵌入在 URL 中。非常大的图表可能会超出 URL 长度限制,在这种情况下,你可以通过复制代码来分享 Mermaid 代码。

什么是 Mermaid 主题?

Mermaid.js 包含四个内置主题:Default(蓝色/紫色色调)、Dark(演示文稿用的深色背景)、Forest(绿色色调,自然感)和 Neutral(灰度,专业风格)。主题会影响图表中的节点颜色、线条样式和背景。应用的 UI 主题(深色/浅色模式)与 Mermaid 图表主题是独立的。

编辑器会自动保存我的工作吗?

会的。你的图表代码会在输入时自动保存到浏览器的 localStorage 中。当你重新访问页面时,上次的图表会自动恢复。请注意 localStorage 是浏览器特定的——切换浏览器或清除浏览器数据将删除已保存的图表。要长期保存,请导出你的图表或复制可分享的 URL。

代码示例

// Mermaid Diagram Rendering and Export in JavaScript (Browser)

/**
 * Initialize mermaid.js with configuration
 */
async function initMermaid(theme = 'default') {
  const mermaid = await import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs');
  mermaid.default.initialize({
    startOnLoad: false,
    theme: theme,  // 'default', 'dark', 'forest', 'neutral'
    securityLevel: 'strict',
  });
  return mermaid.default;
}

/**
 * Render Mermaid code to SVG string
 */
async function renderMermaid(mermaidInstance, code, elementId = 'mermaid-output') {
  try {
    const { svg } = await mermaidInstance.render(elementId, code);
    return { svg, error: null };
  } catch (error) {
    return { svg: null, error: error.message };
  }
}

/**
 * Export SVG string as downloadable .svg file
 */
function downloadSvg(svgContent, filename = 'diagram.svg') {
  const blob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
}

/**
 * Convert SVG to PNG and download
 */
async function downloadPng(svgContent, scale = 2, filename = 'diagram.png') {
  return new Promise((resolve, reject) => {
    const svgBlob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' });
    const url = URL.createObjectURL(svgBlob);
    const img = new Image();

    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.naturalWidth * scale;
      canvas.height = img.naturalHeight * scale;
      const ctx = canvas.getContext('2d');

      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.scale(scale, scale);
      ctx.drawImage(img, 0, 0);

      canvas.toBlob((blob) => {
        const pngUrl = URL.createObjectURL(blob);
        const anchor = document.createElement('a');
        anchor.href = pngUrl;
        anchor.download = filename;
        anchor.click();
        URL.revokeObjectURL(pngUrl);
        URL.revokeObjectURL(url);
        resolve();
      }, 'image/png');
    };

    img.onerror = reject;
    img.src = url;
  });
}

/**
 * Encode diagram state for URL sharing
 */
function encodeDiagramState(code, theme) {
  const state = JSON.stringify({ code, theme });
  return btoa(unescape(encodeURIComponent(state)));
}

function decodeDiagramState(encoded) {
  try {
    const json = decodeURIComponent(escape(atob(encoded)));
    return JSON.parse(json);
  } catch {
    return null;
  }
}

// Example usage
(async () => {
  const mermaid = await initMermaid('default');

  const code = `
graph TD
    A[Start] --> B{Is it working?}
    B -->|Yes| C[Great!]
    B -->|No| D[Debug]
    D --> B
  `;

  const { svg, error } = await renderMermaid(mermaid, code);

  if (error) {
    console.error('Render error:', error);
    return;
  }

  console.log('SVG rendered successfully');

  // Download as SVG
  downloadSvg(svg, 'flowchart.svg');

  // Download as PNG at 2x resolution
  await downloadPng(svg, 2, 'flowchart.png');

  // Create shareable URL
  const encoded = encodeDiagramState(code, 'default');
  console.log(`Share URL: https://ohmyutils.com/en/mermaid-diagram-editor?state=${encoded}`);
})();

相关工具