这是啥操作,用代码能画这样的图

2,858 阅读8分钟

大家好,我是车辙。不知道同学们画流程图或者时序图一般用的什么软件?Visio 还是 Process On 或者语雀?

因为公司原因,在很多情况下,我一般用语雀画流程图或者思维导图。不过凡事也有例外,对于比较简单的图,也可以用代码画。什么,代码也能用来画图?是的,而且还不会比你自己画的差呢!接下来,我会用以下几个方面来讲解下代码画图。

image.png

为什么要用代码画图

  1. 不需要繁琐的软件,你只要会使用 Markdown 即可。而且现在市面上的Markdown软件像Typora语雀等基本都支持代码画图。
  2. 相比于使用鼠标拖拽,这种画图方式非常的简单。你不必再去考虑排版对齐问题,它能帮你自动调整,节约不少时间。
  3. 相比于ProcessOn等收费软件,用代码画图完全免费。
  4. 组内协同时,不用考虑对方和你用的是不是同一个软件,你可以直接把代码拷给你的同事,或者建立起画图的Git库,提交就可以。

如何使用代码画图

先前我们提到过,只需要用支持Markdown的软件即可。其实我们用的是叫做Mermaid的工具,它是一个基于javascript的图表绘制工具,可以通过Markdown来进行展现,如果你对Markdown很熟悉,学习它会非常简单。

If you are familiar with Markdown you should have no problem learning Mermaid's Syntax

用 Mermaid 画流程图

什么是流程图

通过图形来对某个特定业务或场景的整体的流程走向进行规范化的梳理和绘制,从而使相关方能够通过最为直观的图形方式来明确知道整个流程的概况以及每个流程的前后关系,让我们能够更加快速方便地了解特定场景、业务的流程关系的一种图形。

最基本流程图

首先我们来画最基本的流程图

graph LR  
    A(开始) --> B[A出门玩耍] --> C((回家))
graph LR  
    A(开始) --> B[A出门玩耍] --> D((回家))

从上面可以看出存在A、B、C三个节点,每个节点中都是一个步骤。其中括号()表示开始动作,中括号[]表示中间的步骤,双括号(())表示结束。

加判断条件

流程图中除了最基本的,还存在判断条件,那该怎么写呢?

graph LR  
    A(开始) --> B[A出门] --> C{"天会不会下雨?"}
    C{"天会不会下雨?"}-->|会| D((回家))
    C{"天会不会下雨?"}-->|不会| E[继续]
graph LR  
    A(开始) --> B[A出门] --> C{"天会不会下雨?"}
    C{"天会不会下雨?"}-->|会| D((回家))
    C{"天会不会下雨?"}-->|不会| E[继续]

你可以使用大括号{}用于表示判断条件,在节点C后通过||表示判断条件即可。

对C节点的文案加引号是由于?号是特殊字符,不加会报错

布局方式

另外 graph LR表示这个图将会以从左到右布局。如果你想从右到左布局,可以使用RL

graph RL  
    A(开始) --> B[A出门玩耍] --> C((回家))
graph RL  
    A(开始) --> B[A出门玩耍] --> D((回家))

如果想从上到下,可以以TB(Top、Bottom)布局

graph TB  
    A(开始) --> B[A出门玩耍] --> C((回家))
graph TB  
    A(开始) --> B[A出门玩耍] --> D((回家))

箭头形状

如果觉得这个箭头太难看了,可以使用虚线箭头-.->,想让箭头变长,中间加个点即可=-..->

graph LR  
    A(开始) -.-> B[A出门玩耍] -...-> D((回家))

如果希望用其他的箭头,可以使箭头加粗 ==> 或者不带箭头 ---

graph LR  
    A(开始) ==> B[A出门玩耍] --- D((回家))

另外:为节点取名为 ABC 其实是不太合适的。因为节点很多时容易产生混淆,不方便后续使用和阅读,建议起有意义的名字。

额外的骚操作

除了这些,还有些其他的骚操作,比如节点添加超链接文案

graph LR  
    A(开始) -- 123 --> B[A出门玩耍] --- D((回家))
    click B "https://www.baidu.com" _blank
graph LR  
    A(开始) -- 123 --> B[A出门玩耍] --- D((回家))
    click B "https://www.baidu.com" _blank

最绝的是你可以往节点中添加css

graph LR  
    A(开始) -- 123 --> B[A出门玩耍] --- D((回家))
    style A fill:#f9f,stroke:#333,stroke-width:4px
graph LR  
    A(开始) -- 123 --> B[A出门玩耍] --- D((回家))
    style A fill:#f9f,stroke:#333,stroke-width:4px

用Mermaid 画时序图

什么是时序图

时序图,它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序,当执行一个用例行为时,其中的每条消息对应一个类操作或状态机中引起转换的触发事件。举个例子就是微信的网页授权流程。

最基本时序图

老规矩,先来个简单的支付宝转账。

sequenceDiagram
autonumber
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
网银 -->> 支付宝 : 转账成功
支付宝 -->> 用户 : 转账成功
sequenceDiagram
autonumber
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
网银 -->> 支付宝 : 转账成功
支付宝 -->> 用户 : 转账成功

解释下:

  1. 可以使用譬如"用户"、"服务端"来表示一个泳道。
  2. 可以使用 ->>表示箭头,而-->>表示同步返回。
  3. 通过autonumber 开启执行序号展示。

消息组合

它同时支持它提供了alt/else、loop来进行时序图的消息组合。

sequenceDiagram
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
alt  转账成功
        网银 -->> 支付宝 : 返回转账ID
        支付宝 -->> 用户 : 转账成功
else 转账失败
    网银 -->> 支付宝 : 返回转账失败原因
    loop 3次 
    支付宝 ->> 网银: 再次进行重试
    end
end
sequenceDiagram
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
alt  转账成功
        网银 -->> 支付宝 : 返回转账ID
        支付宝 -->> 用户 : 转账成功
else 转账失败
    网银 -->> 支付宝 : 返回转账失败原因
    loop 3次 
    支付宝 ->> 网银: 再次进行重试
    end
end
  1. 可以通过alt 进行条件判断,如果成功直接返回。
  2. else表示另外的情况.
  3. 通过Loop表示循环次数。另外,在循环中同样存在着alt判断,为了方便观察,我就没有把他写出来。

背景色

我们还可以给时序图添加背景色。

sequenceDiagram
rect rgb(191, 223, 255)
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
alt  转账成功
        网银 -->> 支付宝 : 返回转账ID
        支付宝 -->> 用户 : 转账成功
else 转账失败
    网银 -->> 支付宝 : 返回转账失败原因
end
end
sequenceDiagram

rect rgb(191, 223, 255)
用户 ->> 支付宝 : 发起转账
支付宝 ->> 网银 : 发起转账
alt  转账成功
        网银 -->> 支付宝 : 返回转账ID
        支付宝 -->> 用户 : 转账成功
else 转账失败
    网银 -->> 支付宝 : 返回转账失败原因
end
end

通过 rect rgb(191, 223, 255)end标签,即可完成背景色操作。

微信网页授权时序图

最后,我们看下用Mermaid画微信网页授权登录的时序图。

sequenceDiagram
  用户->> 浏览器端: 请求登录
  浏览器端->> 服务端:  请求构建授权链接
  服务端-->> 服务端:  生成授权链接
  服务端-->> 浏览器端:  返回授权链接
  浏览器端->> 微信端:  请求网页授权
  微信端->> 微信端:  用户是否同意授权
  微信端->> 浏览器端:  重定向到Redirect地址
  浏览器端->> 浏览器端:  获取Code
  浏览器端->> 服务端: code 
  服务端->> 微信端:  通过Code请求获取 AccessToken
  微信端-->> 服务端: 返回AccessToken
  服务端->> 微信端:  通过AccessToken请求获取用户信息
  微信端-->> 服务端: 返回用户信息
  服务端->> 服务端: 登录
  服务端-->> 浏览器端: 登录成功,返回用户信息

用Mermaid 画类图

什么是类图

类图(Class diagram)是显示了模型的静态结构,特别是模型中存在的类、类的内部结构以及它们与其他类的关系等

最基本类图

比如我们首先写一个动物类

classDiagram
    class 老虎{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }
classDiagram
    class 老虎{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }

其中 agename 表示属性,runsleep表示方法,int 表示返回值的类型。而其他的符号可以表示它的可见性:

  • + Public
  • - Private
  • # Protected
  • ~ Package/Internal

接口和枚举

如果你是接口,可以这么写

classDiagram
class 动物{
    <<interface>>
    run()
}
classDiagram
class 动物{
    <<interface>>
    run()
}

如果是枚举,可以这么写

classDiagram
class Color{
    <<enumeration>>
    RED
    BLUE
    GREEN
    WHITE
    BLACK
}
classDiagram
class Color{
    <<enumeration>>
    RED
    BLUE
    GREEN
    WHITE
    BLACK
}

类之间的关系

类之间都会存在某种关系,比如说继承,实现等。在mermaid中分别用这些标识各种关系。

classDiagram
classK ..> classL : Dependency 依赖
classA --|> classB : Inheritance 继承
classM ..|> classN : Realization 实现
classG --> classH : Association 关联
classE --o classF : Aggregation 聚合
classC --* classD : Composition 组合

就以老虎继承动物举例:

classDiagram
    direction RL
    class 老虎{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }
    class 动物{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }
    老虎 --|> 动物 : Inheritance 继承
classDiagram
    direction RL
    class 老虎{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }
    class 动物{
        +Integer age
        +String name
        
        +run(mile)
        +sleep() int
    }
    老虎 --|> 动物 : Inheritance 继承

用Mermaid 画甘特图

什么是甘特图

甘特图(Gantt chart)又称为横道图、条状图(Bar chart)。其通过条状图来显示项目、进度和其他时间相关的系统进展的内在关系随着时间进展的情况。

最基本甘特图

gantt
    title 甘特图基础演示
    dateFormat  YYYY-MM-DD
    section 张三
    接口1完成       : a1, 2014-01-01, 30d
    接口2完成       : after a1  , 20d
    
    section 车辙
    接口3完成      :2014-01-12  , 12d
    接口3完成      : 24d
gantt
    title 甘特图基础演示
    dateFormat  YYYY-MM-DD
    section 张三
    接口1完成       : a1, 2014-01-01, 30d
    接口2完成       : after a1  , 20d
    
    section 车辙
    接口3完成      :2014-01-12  , 12d
    接口3完成      : 24d

其中,section指人或者小组,每个section中都存在若干个task。 例如 接口1完成 这个taskIda1,开始日期为2014-01-01,持续30d.

添加标识状态

你也可以用字段标识它的状态,比如done表示完成,active表示活跃中

gantt
    title 甘特图基础演示
    dateFormat  YYYY-MM-DD
    section 张三
    接口1完成       : done,a1, 2014-01-01, 30d
    接口2完成       : active,after a1  , 20d
    
    section 车辙
    接口3完成      :2014-01-12  , 12d
    接口3完成      : 24d
gantt
    title 甘特图基础演示
    dateFormat  YYYY-MM-DD
    section 张三
    接口1完成       : done,a1, 2014-01-01, 30d
    接口2完成       : active,after a1  , 20d
    
    section 车辙
    接口3完成      :2014-01-12  , 12d
    接口3完成      : 24d

用Mermaid 画饼状图

Mermaid 还可以用来画饼状图,这不比用Python生成简单?

pie title 颜值占比
    "车辙" : 37
    "吴彦祖" : 36
    "马老师" : 27
pie title 颜值占比
    "车辙" : 37
    "吴彦祖" : 36
    "马老师" : 27

代码画图的缺点

和低代码类似,代码画图最大的问题只能画出相对简单的图,一旦业务复杂,用代码操作,往往会变的很不好画。

总结

本文介绍了如何使用Mermaid进行画图,除了上述的内容外,Mermaid还能支持更多类型的图,当然这些内容就需要大家去官网查看了。官网地址

如果这篇文章对您有所帮助,可以关注我的公众号《车辙的编程学习圈》,也可以在我的博客网站扫码关注 我的博客网站

我是车辙,掘金小册《SkyWalking》作者,一名常被HR调侃为XX杨洋的互联网打工人。