Mermaid 桑基图 #

桑基图(Sankey Diagram)是一种用于展示流量数据的可视化图表,特别适合展示能量、物料、资金等在系统内的流动情况。

基本概念 #

桑基图由以下几个部分组成:

  • 节点(Nodes):表示流动的起点、中间点或终点
  • 流(Flows):表示从一个节点到另一个节点的流量
  • 流量值(Value):表示流动的数量或大小

实现方式 #

Mermaid目前没有专门的桑基图语法,但可以使用流程图(Flowchart)来模拟实现简单的桑基图效果:

1. 简单流量图 #

mermaid
graph TD
  A[来源1] -->|50| C[目标1]
  A -->|30| D[目标2]
  B[来源2] -->|40| C
  B -->|60| D
  C -->|80| E[最终目标]
  D -->|90| E

2. 多级流量图 #

mermaid
graph TD
  subgraph 一级来源
    A[来源A] -->|50| B[中间节点1]
    C[来源B] -->|30| B
    D[来源C] -->|40| E[中间节点2]
    F[来源D] -->|60| E
  end
  
  subgraph 二级节点
    B -->|80| G[目标1]
    B -->|30| H[目标2]
    E -->|70| G
    E -->|50| H
  end
  
  subgraph 最终目标
    G -->|150| I[最终目标1]
    H -->|80| J[最终目标2]
  end

高级模拟 #

1. 能量流动图 #

mermaid
graph TD
  A[能源生产] -->|200| B[电力]
  A -->|150| C[热能]
  A -->|100| D[燃料]
  
  B -->|120| E[工业用电]
  B -->|50| F[居民用电]
  B -->|30| G[商业用电]
  
  C -->|90| H[工业供热]
  C -->|60| I[居民供暖]
  
  D -->|70| J[工业燃料]
  D -->|30| K[交通燃料]
  
  E -->|100| L[产品制造]
  E -->|20| M[废物处理]
  
  F -->|40| N[生活消费]
  F -->|10| O[家庭废物]
  
  G -->|25| P[商业运营]
  G -->|5| Q[商业废物]

2. 网站流量图 #

mermaid
graph TD
  subgraph 流量来源
    A[搜索引擎] -->|400| B[首页]
    C[社交媒体] -->|250| B
    D[直接访问] -->|150| B
    E[外部链接] -->|200| B
  end
  
  subgraph 页面访问
    B -->|300| F[产品页]
    B -->|200| G[博客页]
    B -->|150| H[关于我们]
    B -->|100| I[联系我们]
    B -->|250| J[退出]
  end
  
  subgraph 后续操作
    F -->|150| K[加入购物车]
    F -->|100| L[查看评价]
    F -->|50| J
    
    G -->|80| M[阅读更多]
    G -->|70| N[订阅]
    G -->|50| J
    
    H -->|80| O[了解团队]
    H -->|70| J
    
    I -->|60| P[提交表单]
    I -->|40| J
    
    K -->|80| Q[结算]
    K -->|70| J
    
    Q -->|50| R[完成购买]
    Q -->|30| J
  end

最佳实践 #

  1. 清晰的节点命名:使用简洁明了的节点名称
  2. 合理的流量值:确保流量值的准确性和可读性
  3. 适当的层级:避免层级过多导致图表复杂
  4. 颜色区分:使用不同颜色区分不同的流量来源或类型
  5. 清晰的标签:为节点和流量添加清晰的标签

应用场景 #

  1. 能源分析:展示能源的生产、转换和消耗
  2. 供应链分析:展示物料在供应链中的流动
  3. 网站分析:展示用户在网站中的浏览路径
  4. 财务分析:展示资金的来源和去向
  5. 人口流动:展示人口在不同地区之间的流动
  6. 环境分析:展示污染物的来源和分布

专业桑基图工具 #

由于Mermaid目前不支持原生桑基图,以下是一些专门的桑基图工具:

  1. D3.js:使用JavaScript库创建交互式桑基图
  2. Tableau:专业的数据可视化工具,支持桑基图
  3. Power BI:Microsoft的数据分析工具,支持桑基图
  4. SankeyMATIC:在线桑基图生成工具
  5. RAWGraphs:开源的数据可视化工具,支持桑基图

D3.js桑基图示例 #

如果需要专业的桑基图,可以使用D3.js实现:

html
<!DOCTYPE html>
<html>
<head>
    <title>Sankey Diagram</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://unpkg.com/d3-sankey@0.12.3/dist/d3-sankey.min.js"></script>
    <style>
        .node rect {
            fill-opacity: .9;
            shape-rendering: crispEdges;
        }
        .node text {
            pointer-events: none;
            dominant-baseline: central;
        }
        .link {
            fill: none;
            stroke: #000;
            stroke-opacity: .2;
        }
        .link:hover {
            stroke-opacity: .5;
        }
    </style>
</head>
<body>
    <svg width="960" height="500"></svg>
    <script>
        const svg = d3.select("svg"),
              width = +svg.attr("width"),
              height = +svg.attr("height");

        const margin = {top: 10, right: 10, bottom: 10, left: 10};

        const sankey = d3.sankey()
            .nodeWidth(15)
            .nodePadding(10)
            .extent([[margin.left, margin.top], [width - margin.right, height - margin.bottom]]);

        const data = {
            nodes: [
                {name: "来源1"},
                {name: "来源2"},
                {name: "中间1"},
                {name: "中间2"},
                {name: "目标1"},
                {name: "目标2"}
            ],
            links: [
                {source: 0, target: 2, value: 50},
                {source: 0, target: 3, value: 30},
                {source: 1, target: 2, value: 40},
                {source: 1, target: 3, value: 60},
                {source: 2, target: 4, value: 80},
                {source: 3, target: 5, value: 90}
            ]
        };

        const {nodes, links} = sankey({nodes: data.nodes, links: data.links});

        const g = svg.append("g");

        const link = g.append("g")
            .selectAll("path")
            .data(links)
            .join("path")
            .attr("d", d3.sankeyLinkHorizontal())
            .attr("stroke", "#999")
            .attr("stroke-opacity", 0.6)
            .attr("stroke-width", d => d.width);

        const node = g.append("g")
            .selectAll("g")
            .data(nodes)
            .join("g")
            .attr("transform", d => `translate(${d.x0},${d.y0})`);

        node.append("rect")
            .attr("height", d => d.y1 - d.y0)
            .attr("width", sankey.nodeWidth())
            .attr("fill", "#69b3a2")
            .attr("stroke", "#000");

        node.append("text")
            .attr("x", -6)
            .attr("y", d => (d.y1 - d.y0) / 2)
            .attr("dy", "0.35em")
            .attr("text-anchor", "end")
            .attr("font-size", "12px")
            .text(d => d.name);
    </script>
</body>
</html>

总结 #

虽然Mermaid目前不支持原生的桑基图,但可以使用流程图模拟简单的流量图效果。对于更专业和复杂的桑基图,建议使用专门的数据可视化工具如D3.js、Tableau或Power BI。

随着Mermaid的不断发展,未来可能会添加原生的桑基图支持。在此之前,可以使用上述模拟方法或专业工具来创建桑基图。

最后更新:2026-02-08