Typora supports Mermaid for drawing, including flowcharts.

There are not many scenarios in which flowcharts are used in daily life, and pseudocode is preferred in the process of writing code. When I recently read Volume 1 of The Art of Computer Programming, I was presented with a flowchart. Somehow, I suddenly felt that flowchart was indispensable. Perhaps the flowchart is better paired with pseudocode.

These are the reasons I forced out for writing this article.

About the mermaid

One of Mermaid’s many code drawing tools. I first came across Plantuml. At that time, I searched for this tool in order to submit software documents for class drawing, but I did not want to hand animate. Plantuml, as the name suggests, is primarily a UML diagram with fewer supported diagrams, more dependencies, and more steps to configure.

Mermaid is not as fully UML supported as Plantuml, but basic graphics can be drawn, and thanks to the development of a large front end, it is just a “simple”.js file that can be imported and exported for use in a browser, under Markdown, an HTML-compliant markup language, and really flow.

It supports simple process flowcharts, which is simple because the entire process is too complex. If you can’t use it, leave the complicated stuff alone. Mermaid is more than enough.

Install the mermaid

Refer to the installation tutorial.

The main reason I came into contact with Mermaid was that Typora itself supported the use of Mermaid. My solution was to complete the editing in Typora, then export the HTML, and then publish to a platform that supported Markdown. Some sites support Mermaid themselves.

A simple flow chart is drawn as follows:

Graph LR A([start]) --> B[/ edit article /] B --> C{Content complete? {is} C -- - > | | D editor again? Whether} C -- - > | | B D - > whether | | Save Save [Save] - > {E export? } D - > | | B E - > whether | | End ([End]) E - > is | | ExportHTML ExportHTML [/ export HTML /] -- > Publish [post] Publish - > End

Markdown uses Mermaid

Using Mermaid in Typora is easy, just import the code:

​```mermaid
​```

However, we need to use flowchart. We can refer to the document, introduce flowchart and directly use flowchart or graph keyword, and specify the drawing direction of the flowchart explicitly. TD or TB means drawing from top to bottom, and LR means drawing from left to right. (that is, the upper and lower initials). However, the styles that flowchart and graph can use are different. Flowchart is relatively smooth with respect to arrows, and can use a variety of arrow styles, while graph has a relatively rigid style. We can try a simple process:

' ' 'mermaid graph LR START([START]) END([END]) START --> A --> isRight{True? } isRight - > is | | END isRight - > whether | | A ` ` `

The above code is as follows:

Graph LR START([START]) END([END]) START --> A --> isRight{Graph LR START([START]) END([END]) START --> A --> isRight{ } isRight - > is | | END isRight - > | | A

We replace GRAPH with Flowchart as shown below:

Flowchart LR START([START]) END([END]) START --> A --> isRight{True? } isRight - > is | | END isRight - > | | A

The only difference so far is the style, and the documentation indicates that the FlowChart is in a Beta state. The documentation only lists more arrow support and subflowchart support. That’s not what we should be focusing on, so using that keyword is a matter of personal preference. Although FlowChart has a strong recognition in text, Graph draws a clearer image. There is also code highlighting in Typora, and the functions provided by FlowChat are not used, so Graph is used as the keyword in the future.

Flowchart Basis

The main function of a flowchart is to describe the process of something more visually than words.

Using code to build a flowchart is more like pseudocode to show the logic in real time, and of course makes it easier for people who are not familiar with the code to understand the basic idea of the code. Drawing flow charts and clarifying your own logic is the main thing.

There is a norm for human communication, and there is a norm for flow charts.

Flowchart symbol

The code for the regular symbols and Mermaid is listed here.

Mermaid does not specify what the symbol signifies, but the shape of the symbol.

1. The process

To perform or process something.

The notation for the process in Mermaid is simple, just brackets [], as shown below:

Graph LR A[Flow 1] B[Flow 2] A --> B

The effect is as follows:

Graph LR A[Flow 1] B[Flow 2] A --> B

In Mermaid, the process is a basic node, with rectangles and rounded rectangles (represented by ()), which are similar in shape and have no specific requirements, but [] is easier to type, so there is little need for ().

2. Start or end

In the documentation, all start or end symbols are directly replaced by a process, with no specific requirements given. However, in the flowchart specification, the beginning and end should have a separate shape from the flow. Using ([]) in Mermaid, you can draw a graph that is different from the process, as follows:

Graph LR START([START]) END([END]) START --> END

The results are as follows:

Graph LR START([START]) END([END]) START --> END

In the documentation, it is called A stadium-shaped node, which resembles A stadium in shape. The beginning and end of only one, in the initial definition, the subsequent can be directly used.

In particular, do not use lowercase at the end of the definitionendOtherwise the inverted flowchart drawing may be interrupted

3. Determine the

The decision is uniform, and Mermaid is represented with {}. As follows:

Graph LR START([START]) END([END]) Flow } isTrue - > is | | END isTrue - > whether | | Flow START -- > Flow - > isTrue

The effect is as follows:

Graph LR START([START]) END([END]) Flow } isTrue - > is | | END isTrue - > whether | | Flow START -- > Flow - > isTrue

As the code shows, we define isTrue as a check box that says “True?” And right after the process of how to deal with simple, directly before the next process to use | yes/no |.

4. The child process

As the name suggests, it is a collection of processes whose main function is to simplify the flow chart. The internal process can be shown as an attachment to another flow chart. Similar to A subroutine, A node in A subroutine shape in Mermaid.

The code is as follows:

Graph LR ID [[Subflow]]

The effect is as follows:

Graph LR ID [[Subflow]]

That is, two brackets are used to denote [[]].

Database of 5.

Represents a storage location, belonging to an extension.

The code is as follows:

Graph LR DB[(database)]

The effect is as follows:

Graph LR DB[(database)]

The symbol is [()].

6. In-page references

Interface, which represents the interface between two flowcharts.

Its purpose is:

  1. Link to the next page;
  2. Avoid streamline crossing;
  3. Avoid too long streamline;

The code is as follows:

Graph LR OUT((interface))

The effect is as follows:

Graph LR OUT((interface))

The symbol is (()).

7. Input/output

Inputs or outputs should be different from the flow.

The code is as follows:

Graph LR input[/ input /]

The effect is as follows:

Graph LR input[/ input /]

There is also an inverted parallelogram in Mermaid, which has the opposite sign to the above, [\\], with the effect:

Graph LR input[\ input \]

But we usually use the first one.

8. (Additional) Arrow style

Flowcharts seem to only have solid arrows, other arrows are rare, but Mermaid provides a number of styles of arrows.

The code is as follows:

Graph LR - linear | | B -- -- -- -- - | A length of straight line length is - symbol definition - 3-5 | B0 A - > | straight arrow B1 A -- - > | | long straight arrow | A = = = | | thick line of B2 B3 A = = > | coarse arrow line | B4 A -. - | | dotted line B5 A -. - > | dotted arrow | B6

The effect is as follows:

Graph LR - linear | | B -- -- -- -- - | A length of straight line length is - symbol definition - 3-5 | B0 A - > | straight arrow B1 A -- - > | | long straight arrow | A = = = | | thick line of B2 B3 A = = > | coarse arrow line | B4 A -. - | | dotted line B5 A -. - > | dotted arrow | B6

You can use it according to your own needs.

Of course, Mermaid also offers many other shapes, including trapezoids and more. Please refer to the documentation for these.

Next, let’s draw the basic structure of the flowchart.

The basic structure of a flowchart

Flowcharts have three basic structures: a sequential structure, a selection structure, and a loop structure, and so do programs. In the flowchart drawing specification, there are provisions on the drawing method of these structures, and the use of Mermaid to draw the graph seems not so standard.

1. Sequential structure

Sequential structure is the execution of the program in sequence, from top to bottom/left to right, one by one. The most basic structure.

The code is as follows:

Graph LR START([START]) END([END]) START --> A A --> B B --> C C --> END

The effect is as follows:

Graph LR START([START]) END([END]) START --> A A --> B B --> C C --> END

2. Choose structure

Selection, i.e. branch, i.e. if-else structure:

Conditions of graph TD isTrueA isTrueB condition of {A} {B} isTrueC conditions C} {A ([to]) -- - > isTrueA isTrueA - > is | | A1 (step 1) isTrueA - > | | A2 [2] A1 -- > AE ([over]) A2 - > AE ([to]) -- - > B isTrueB isTrueB - > is | | BE ([over]) isTrueB -- > whether | | B1 (step 3) B1 - > BE C ([to]) -- - > IsTrueC isTrueC - > | | is C1 [4] isTrueC - > whether | | CE ([over]) C1 - > CE

The effect is as follows:

Conditions of graph TD isTrueA isTrueB condition of {A} {B} isTrueC conditions C} {A ([to]) -- - > isTrueA isTrueA - > is | | A1 (step 1) isTrueA - > | | A2 [2] A1 -- > AE ([over]) A2 - > AE ([to]) -- - > B isTrueB isTrueB - > is | | BE ([over]) isTrueB -- > whether | | B1 (step 3) B1 - > BE C ([to]) -- - > IsTrueC isTrueC - > | | is C1 [4] isTrueC - > whether | | CE ([over]) C1 - > CE

So you can see that even though we’re writing the code in order, condition B and condition C we can see that there are steps on the right, and if there are steps on both sides, we draw them in order. Because “whether” is in accordance with the words | | embedded, drawing, the default behavior in accordance with the program executed.

3. Loop structure

As the name suggests, under certain conditions, it will perform repeated actions.

Loops have when and until types, which can be thought of as while and do while(! Conditions).

Code:

Graph TD isTrue1{when type judgment? } isTrue2{until type judgment? } A ([to]) - > isTrue1 isTrue1 - > | | is A1 steps [1] -- > isTrue1 isTrue1 - > whether | | AE ([over]) B ([to]) -- - > B1 [2] B1 - > isTrue2 IsTrue2 - > | | BE ([end]) isTrue2 - > | | B1

Effect:

Graph TD isTrue1{when type judgment? } isTrue2{until type judgment? } A ([to]) - > isTrue1 isTrue1 - > | | is A1 steps [1] -- > isTrue1 isTrue1 - > whether | | AE ([over]) B ([to]) -- - > B1 [2] B1 - > isTrue2 IsTrue2 - > | | BE ([end]) isTrue2 - > | | B1

This is all, regardless of what drawing specifications…

case

A couple of classic examples.

1. Guess the number

The number is random.

  1. Input the number n
  2. Determine the size, indicating whether it is large or small
  3. Guessing correctly prompts you to continue
  4. Do not continue to exit, continue to regeneratenumber, repeat steps 1-4
Graph TD START([START]) END([END]) %% input_n[/ input number n/] %% define the judgment condition n_eq_number? { n == number? } n_lt_number? { n < number? } continue? {continue? } %% ALERT_gt[/] ALERT_eq[/ /] alert_t [/ /] alert_t [/ / /] alert_t [/ / / /] START --> gen_number --> input_n input_n --> n_eq_number? n_eq_number? -- > is | | ALERT_eq - > the continue? n_eq_number? -- > whether | | n_lt_number? n_lt_number? -- > is | | ALERT_lt n_lt_number? -- > whether | | ALERT_gt n_lt_number? --> input_n continue? -- > is | | gen_number continue? -- - > | | END
Graph TD START([START]) END([END]) %% input_n[/ input number n/] %% define the judgment condition n_eq_number? { n == number? } n_lt_number? { n < number? } continue? {continue? } %% ALERT_gt[/] ALERT_eq[/ /] alert_t [/ /] alert_t [/ / /] alert_t [/ / / /] START --> gen_number --> input_n input_n --> n_eq_number? n_eq_number? -- > is | | ALERT_eq - > the continue? n_eq_number? -- > whether | | n_lt_number? n_lt_number? -- > is | | ALERT_lt n_lt_number? -- > whether | | ALERT_gt n_lt_number? --> input_n continue? -- > is | | gen_number continue? -- - > | | END

The logic needs to be optimized.

2. Login logic

1. Register

Graph TD START([START]) END([END]) input[] START --> input --> pw_pair? {Is the password formatted? } pw_pair? -- > whether | | input pw_pair? -- > is | | user_pair? {Is the account formatted? } user_pair? -- > is | | get_code [access authentication code] user_pair? Whether - > | | input get_code - > input_code [/ / input validation code] input_code - > code_pair? {Is the verification code correct? } code_pair? - > is | | success [registration] success - - | | storage database [(user database)] code_pair? Whether - > | | record verification code wrong number - > try_more? {Too many attempts? } try_more? - > is | | will_END [restricted access authentication code number, prohibiting the registration] - > END try_more? -- > whether | | en_time? {Do you get CAPTCHAs every 60s? } en_time? -- > is | | get_code en_time? Whether - > | | wait_time [waiting for 60 s] -- > get_code success - > END
Graph TD START([START]) END([END]) input[] START --> input --> pw_pair? {Is the password formatted? } pw_pair? -- > whether | | input pw_pair? -- > is | | user_pair? {Is the account formatted? } user_pair? -- > is | | get_code [access authentication code] user_pair? Whether - > | | input get_code - > input_code [/ / input validation code] input_code - > code_pair? {Is the verification code correct? } code_pair? - > is | | success [registration] success - - | | storage database [(user database)] code_pair? Whether - > | | record verification code wrong number - > try_more? {Too many attempts? } try_more? - > is | | will_END [restricted access authentication code number, prohibiting the registration] - > END try_more? -- > whether | | en_time? {Do you get CAPTCHAs every 60s? } en_time? -- > is | | get_code en_time? Whether - > | | wait_time [waiting for 60 s] -- > get_code success - > END

2. Login

Graph TD subgraph db [DB] db_user[(DB)] db_login[(DB)] end START([DB]) end ([DB]) input[/ DB] START -- -> Input input --> get_code --> input_code[/ input code /] input_code --> code_pair? {Is the verification code correct? } code_pair? -- > is | | pw_pair [] from the database matching the account password pw_pair - - | search | db_user pw_pair - > pw_pair? {Accounts and passwords match? } pw_pair? - > is | | success [login] success success - - | | storage db_login pw_pair? -- > whether | | input code_pair? Whether - > | | record verification code wrong number - > try_more? {Too many attempts? } try_more? - > is | | will_END [limiting access to authentication code number, ban login] - > END try_more? -- > whether | | en_time? {Do you get CAPTCHAs every 60s? } en_time? -- > is | | get_code en_time? Whether - > | | wait_time [waiting for 60 s] -- > get_code success - > END
Graph TD subgraph db [DB] db_user[(DB)] db_login[(DB)] end START([DB]) end ([DB]) input[/ DB] START -- -> Input input --> get_code --> input_code[/ input code /] input_code --> code_pair? {Is the verification code correct? } code_pair? -- > is | | pw_pair [] from the database matching the account password pw_pair - - | search | db_user pw_pair - > pw_pair? {Accounts and passwords match? } pw_pair? - > is | | success [login] success success - - | | storage db_login pw_pair? -- > whether | | input code_pair? Whether - > | | record verification code wrong number - > try_more? {Too many attempts? } try_more? - > is | | will_END [limiting access to authentication code number, ban login] - > END try_more? -- > whether | | en_time? {Do you get CAPTCHAs every 60s? } en_time? -- > is | | get_code en_time? Whether - > | | wait_time [waiting for 60 s] -- > get_code success - > END

In the relatively complex logic, the overall drawing is a little messy.

summary

Flowcharts are not suitable for overly complex logic and can be somewhat underexpressive for complex logic. I drew the login interface several times in the previous chapter, including a graph showing login, login, logout and other functions (using Subgraph). When the drawing was complete, although the pseudocode was easy to understand, the image was very complex.

Flowcharts are better for representing logical relationships, describing a function of a program (process-oriented) than state changes. This leads to a state flow diagram.

Object – oriented class diagrams need UML to describe them.

Currently flowcharts can be used to describe a simple single function, others need to be summarized later. A full application wouldn’t be that simple.