EXPORT_GUIDE.md 11 KB

🖼️ Mermaid-Go SVG导出指南

📋 概述

mermaid-go 现在支持将解析的图表结构导出为高质量的SVG格式图片。这个功能让你可以:

  • 📊 将Mermaid图表转换为矢量图形
  • 🎨 支持SVG格式(矢量图形,无损缩放)
  • ⚙️ 自定义尺寸和主题
  • 🛠️ 提供编程接口和命令行工具

🚀 快速开始

基本用法

package main

import (
    "mermaid-go/pkg/parser"
    "mermaid-go/pkg/exporter"
)

func main() {
    // 解析Mermaid图表
    input := `pie showData
        title Market Share
        "Company A" : 45
        "Company B" : 30
        "Others" : 25`
    
    parser := parser.NewMermaidParser()
    diagram, _ := parser.Parse(input)
    
    // 导出为SVG
    exporter := exporter.NewDiagramExporter()
    options := &exporter.ExportOptions{
        Format: exporter.FormatSVG,
        Width:  800,
        Height: 600,
        Theme:  "default",
    }
    
    err := exporter.ExportToFile(diagram, "chart.png", options)
    if err != nil {
        panic(err)
    }
}

命令行工具

# 基本导出
go run cmd/mermaid-export/main.go -input diagram.mmd -output chart.svg

# 自定义尺寸
go run cmd/mermaid-export/main.go \
    -input diagram.mmd \
    -width 1200 \
    -height 800 \
    -output chart.svg

# 自定义主题
go run cmd/mermaid-export/main.go \
    -input diagram.mmd \
    -theme dark \
    -output chart.svg

📊 支持的图表类型

图表类型 SVG支持 质量 说明
Pie Chart ✅ 完整 ⭐⭐⭐⭐⭐ 基于mermaid.js实现,高质量渲染
Organization Chart ✅ 完整 ⭐⭐⭐⭐⭐ 层次结构清晰,支持多层级
Sequence Diagram ✅ 基础 ⭐⭐⭐⭐ 参与者和消息流
Gantt Chart ✅ 基础 ⭐⭐⭐⭐ 项目时间线和任务
Flowchart ✅ 基础 ⭐⭐⭐ 基本节点和连接
Class Diagram ⚠️ 占位符 ⭐⭐ 开发中
State Diagram ⚠️ 占位符 ⭐⭐ 开发中
ER Diagram ⚠️ 占位符 ⭐⭐ 开发中
Timeline ⚠️ 占位符 ⭐⭐ 开发中
User Journey ⚠️ 占位符 ⭐⭐ 开发中
Architecture ⚠️ 占位符 ⭐⭐ 开发中
BPMN ⚠️ 占位符 ⭐⭐ 开发中

🎨 导出选项

ExportOptions 结构

type ExportOptions struct {
    Format ExportFormat  // 输出格式: FormatPNG, FormatSVG, FormatJPEG
    Width  int          // 宽度(像素)
    Height int          // 高度(像素)
    DPI    int          // DPI(仅PNG)
    Theme  string       // 主题(仅SVG)
}

预设选项

// 默认选项
options := exporter.DefaultExportOptions()

// 高分辨率PNG
options := &exporter.ExportOptions{
    Format: exporter.FormatPNG,
    Width:  1600,
    Height: 1200,
    DPI:    300,
}

// 大尺寸SVG
options := &exporter.ExportOptions{
    Format: exporter.FormatSVG,
    Width:  1200,
    Height: 900,
    Theme:  "default",
}

🛠️ API 参考

DiagramExporter

// 创建导出器
exporter := exporter.NewDiagramExporter()

// 导出到字节数组
data, err := exporter.Export(diagram, options)

// 导出到文件
err := exporter.ExportToFile(diagram, "output.png", options)

// 导出到Writer
err := exporter.ExportToWriter(diagram, writer, options)

// 检查支持的格式
formats := exporter.GetSupportedFormats()
diagramTypes := exporter.GetSupportedDiagramTypes()

// 检查兼容性
isSupported := exporter.IsFormatSupported(exporter.FormatPNG)
isDiagramSupported := exporter.IsDiagramTypeSupported(ast.DiagramTypePie)

SVGExporter

// 创建SVG导出器
svgExporter := exporter.NewSVGExporter()

// 设置选项
svgExporter.SetSize(800, 600).SetTheme("default")

// 导出SVG
svgContent, err := svgExporter.ExportToSVG(diagram)

PNGExporter

// 创建PNG导出器
pngExporter := exporter.NewPNGExporter()

// 设置选项
pngExporter.SetSize(800, 600).SetDPI(96)

// 导出PNG
pngData, err := pngExporter.ExportToPNG(diagram)

📝 使用示例

示例1:批量导出

func exportAllDiagrams() {
    diagrams := map[string]string{
        "pie": `pie showData
            title Sales Data
            "Q1" : 25
            "Q2" : 30
            "Q3" : 25
            "Q4" : 20`,
        "org": `organization
            title Team Structure
            CEO --> CTO
            CEO --> CFO
            CTO --> DevManager`,
    }
    
    parser := parser.NewMermaidParser()
    exporter := exporter.NewDiagramExporter()
    
    for name, input := range diagrams {
        diagram, _ := parser.Parse(input)
        
        // PNG导出
        pngOptions := &exporter.ExportOptions{
            Format: exporter.FormatPNG,
            Width:  800,
            Height: 600,
        }
        exporter.ExportToFile(diagram, name+".png", pngOptions)
        
        // SVG导出
        svgOptions := &exporter.ExportOptions{
            Format: exporter.FormatSVG,
            Width:  800,
            Height: 600,
        }
        exporter.ExportToFile(diagram, name+".svg", svgOptions)
    }
}

示例2:Web服务集成

func diagramHandler(w http.ResponseWriter, r *http.Request) {
    // 从请求获取Mermaid代码
    mermaidCode := r.FormValue("diagram")
    format := r.FormValue("format") // png 或 svg
    
    // 解析图表
    parser := parser.NewMermaidParser()
    diagram, err := parser.Parse(mermaidCode)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    // 导出
    exporter := exporter.NewDiagramExporter()
    var exportFormat exporter.ExportFormat
    var contentType string
    
    if format == "svg" {
        exportFormat = exporter.FormatSVG
        contentType = "image/svg+xml"
    } else {
        exportFormat = exporter.FormatPNG
        contentType = "image/png"
    }
    
    options := &exporter.ExportOptions{
        Format: exportFormat,
        Width:  800,
        Height: 600,
    }
    
    data, err := exporter.Export(diagram, options)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    w.Header().Set("Content-Type", contentType)
    w.Write(data)
}

示例3:不同尺寸导出

func exportMultipleSizes(diagram ast.Diagram, baseName string) {
    exporter := exporter.NewDiagramExporter()
    
    sizes := []struct{
        name string
        width, height int
        dpi int
    }{
        {"thumbnail", 200, 150, 72},
        {"medium", 800, 600, 96},
        {"large", 1600, 1200, 150},
        {"print", 2400, 1800, 300},
    }
    
    for _, size := range sizes {
        options := &exporter.ExportOptions{
            Format: exporter.FormatPNG,
            Width:  size.width,
            Height: size.height,
            DPI:    size.dpi,
        }
        
        filename := fmt.Sprintf("%s_%s.png", baseName, size.name)
        exporter.ExportToFile(diagram, filename, options)
    }
}

🔧 高级功能

外部工具集成

对于更高质量的输出,可以使用 AdvancedExporter

// 创建高级导出器
advancedExporter := exporter.NewAdvancedExporter()

// 检查可用的转换工具
converters := advancedExporter.GetAvailableConverters()
fmt.Printf("Available converters: %v\n", converters)

// 使用外部工具导出
err := advancedExporter.ExportWithExternalTool(diagram, "output.png", options)

// 获取安装指南
guide := advancedExporter.InstallationGuide()
fmt.Println(guide["Inkscape"])

推荐的外部工具

  1. Inkscape - 最佳SVG到PNG转换质量

    # macOS
    brew install inkscape
       
    # Ubuntu/Debian
    sudo apt-get install inkscape
    
  2. ImageMagick - 通用图像处理

    # macOS
    brew install imagemagick
       
    # Ubuntu/Debian
    sudo apt-get install imagemagick
    
  3. rsvg-convert - 轻量级SVG转换

    # macOS
    brew install librsvg
       
    # Ubuntu/Debian
    sudo apt-get install librsvg2-bin
    

🎯 最佳实践

1. 选择合适的格式

  • SVG: 矢量图形,适合网页显示和打印
  • PNG: 位图,适合嵌入文档和演示
  • 高DPI PNG: 适合高分辨率显示和打印

2. 尺寸建议

// 网页显示
options := &exporter.ExportOptions{
    Width: 800, Height: 600, DPI: 96,
}

// 演示文稿
options := &exporter.ExportOptions{
    Width: 1200, Height: 900, DPI: 150,
}

// 打印质量
options := &exporter.ExportOptions{
    Width: 2400, Height: 1800, DPI: 300,
}

3. 性能优化

// 批量导出时重用导出器
exporter := exporter.NewDiagramExporter()

// 预设选项避免重复创建
webOptions := &exporter.ExportOptions{
    Format: exporter.FormatPNG,
    Width: 800, Height: 600, DPI: 96,
}

// 并发导出(注意线程安全)
var wg sync.WaitGroup
for _, diagram := range diagrams {
    wg.Add(1)
    go func(d ast.Diagram, name string) {
        defer wg.Done()
        exporter.ExportToFile(d, name+".png", webOptions)
    }(diagram, name)
}
wg.Wait()

🐛 故障排除

常见问题

  1. 导出失败

    // 检查图表类型支持
    if !exporter.IsDiagramTypeSupported(diagram.Type()) {
       log.Printf("Diagram type %s may have limited support", diagram.Type())
    }
       
    // 检查格式支持
    if !exporter.IsFormatSupported(options.Format) {
       return fmt.Errorf("Format %s not supported", options.Format)
    }
    
  2. 图片质量问题

    • 增加DPI设置
    • 使用更大的尺寸
    • 考虑使用SVG格式
    • 尝试外部工具转换
  3. 内存使用过高

    • 减少图片尺寸
    • 批量处理时控制并发数
    • 及时释放大图片资源

调试技巧

// 启用详细日志
import "log"

// 检查导出能力
log.Printf("Supported formats: %v", exporter.GetSupportedFormats())
log.Printf("Supported diagrams: %v", exporter.GetSupportedDiagramTypes())

// 验证图表
if err := diagram.Validate(); err != nil {
    log.Printf("Diagram validation warning: %v", err)
}

// 检查文件大小
if info, err := os.Stat(outputFile); err == nil {
    log.Printf("Output file size: %d bytes", info.Size())
}

🔮 未来计划

短期改进

  • 完善所有图表类型的渲染质量
  • 添加更多主题支持
  • 优化PNG渲染算法
  • 添加JPEG格式支持

长期目标

  • 集成专业字体渲染
  • 支持动画SVG导出
  • 添加PDF格式支持
  • 云端渲染服务集成

导出功能现在已经完全集成到mermaid-go中,为你的图表可视化需求提供了强大的支持! 🎉