<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ evaristo.c - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ evaristo.c - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:24:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/ec001/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Become an Analytical Programmer – Solve the "Rock, Paper, Scissors" Game 5 Ways Using JavaScript & Mermaid.js ]]>
                </title>
                <description>
                    <![CDATA[ Over the past year, I’ve explored tools and practices that help developers build an analytical mindset. One recurring theme is how experienced programmers often describe understanding code as forming a mental picture – a conceptual map of the program... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-become-an-analytical-programmer-compare-five-projects/</link>
                <guid isPermaLink="false">6822006162f6347293451e07</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ evaristo.c ]]>
                </dc:creator>
                <pubDate>Mon, 12 May 2025 14:06:25 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746812725602/cd4a5bc4-71f2-4678-8f5d-5571d9cc38e8.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Over the past year, I’ve explored tools and practices that help developers build an analytical mindset. One recurring theme is how experienced programmers often describe understanding code as forming a mental picture – a conceptual map of the program’s flow.</p>
<p>When it comes to software development, finding ways to visualize these mental models is a common thread. Many developers describe sketching workflows or imagining them mentally to reason through code. And in my own experience working with senior developers and software architects, this visualization habit is extremely common.</p>
<p>A 2013 Quora post captures this well:</p>
<blockquote>
<p>“A top coder sees a program graphically (…) A data structure as a hierarchy of relationships, a program as a network of data pipes… The first and only time he reduces pictures to words is when he writes code.” —Rober Wagner</p>
</blockquote>
<p>So it appears that developing our ability to recognize patterns in code could help us to develop our expertise. But programming is rarely that straightforward – there are often multiple ways to solve the same problem. It also reflects a developer’s personal habits, experiences, and styles. So which patterns matter, then?</p>
<p>Imagine you assign the same task to five developers: build a small game using HTML, CSS, and JavaScript. Each solution should follow the same functional rules. What are the chances their code will look the same?</p>
<p>You’d expect that their implementations might differ, but the underlying <strong>mental workflow</strong> – the internal logic they follow – might be remarkably similar. If you can reconstruct this mental flow from each codebase, you can create a shared referential point for comparison. Once this conceptual diagram is in place, you can “overlay” it on each codebase to identify where they diverge in structure, logic, or abstraction.</p>
<p>Ever since I started coding, spotting “patterns” while comparing other people’s code has fascinated me. I’ve found the process of comparing code not only educational but also enjoyable.</p>
<p>Up until now, I’ve approached it mostly by intuition – but I’ve always felt the need for a more structured method. This article explores a more systematic approach to code comparison, reflecting on what works well and what can be improved.</p>
<h3 id="heading-how-to-read-this-article"><strong>How to Read this Article</strong></h3>
<p>This article is intentionally extensive. Instead of just showing the end result, I’ll walk you through the methodology so you can recreate or adapt it for your own code comparisons.</p>
<p>That said, there are different ways you might approach this article, depending on your interests:</p>
<ul>
<li><p><strong>Just curious about the idea?</strong> The core argument is already laid out in the introduction. Maybe read the conclusion too, and that might be enough for your needs.</p>
</li>
<li><p><strong>Looking to improve your portfolio?</strong> Skim through the analyses. If you're working on a game project, you’ll find comparisons of five JavaScript implementations of Rock, Paper, Scissors. These may give you practical ideas for your own code.</p>
</li>
<li><p><strong>Interested in code analysis?</strong> Read the whole thing. This article goes deeper into why analyzing code is valuable and presents a practical methodology – including tools – you can apply.</p>
</li>
</ul>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-visual-tools-for-code-comparison">Visual Tools for Code Comparison</a>: In this part, we’ll talk about diagrams and focus on the one we’ll use for this project – the use case-driven system block diagram.</p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-we-are-going-to-do">What we are going to do</a>: here, we reveal the focus of our analysis, what we expect to do, what we will consider when making the diagrams, and a short intro to the tool we will use for this, Mermaid.js.</p>
</li>
<li><p><a class="post-section-overview" href="#heading-five-code-examples-of-rock-paper-scissors">Five Code Examples of Rock, Paper, Scissors</a>: Next, we’ll assess the JavaScript code of five CodePen projects, starting from the simplest one and finishing with the most complex one. At each assessment, we’ll make a comparison against the preceding projects.</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-cpc-rock-paper-scissors-by-amit-a-project-with-fireworks-animations">“CPC Rock Paper Scissors” by Amit: A project with fireworks animations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rock-paper-scissors-game-using-native-drag-amp-drop-by-hmz-c-a-project-using-the-html-drag-element">“Rock paper scissors game using native drag &amp; drop” by Hmz C: A project using the HTML Drag element</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rock-paper-scissors-by-brad-traversy-a-project-with-a-modal-and-a-reset">“Rock Paper Scissors” by Brad Traversy: A project with a modal and a reset</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rock-paper-scissors-oop-by-damian-a-project-written-in-oop">“Rock Paper Scissors OOP” by Damian: A project written in OOP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-recurrent-neural-network-rock-paper-scissors-by-andrew-worcerster-a-project-implementing-ai">“Recurrent Neural Network - Rock, Paper, Scissors” by Andrew Worcerster: A project implementing AI</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ol>
<p>Now, let’s dive in!</p>
<h2 id="heading-visual-tools-for-code-comparison"><strong>Visual Tools for Code Comparison</strong></h2>
<p>There are many tools and approaches for code analysis, and although there are more and more “automatic” ways of doing it, <strong>flow diagrams</strong> are still incredibly useful. Unfortunately, while they’re widely used in programming education and analysis, their use for comparing different implementations is rarely discussed or illustrated in tutorials.</p>
<p>Still, the potential is clear. Flow diagrams capture structure and logic in a compact, readable form. They're heavily used in compiler design for analyzing control flow, optimizing logic, and identifying bugs.</p>
<p>When applied to comparative analysis, they can highlight differences in:</p>
<ul>
<li><p>Modularity and abstraction</p>
</li>
<li><p>Execution flow</p>
</li>
<li><p>Separation of concerns or unnecessary complexity</p>
</li>
</ul>
<p>But not all diagram types are equally effective for this purpose. Traditional flowcharts often dive too deep into the nitty-gritty, repeating low-level logic like if-else branches already visible in the source. While helpful for understanding a single script, they may obscure broader design patterns when comparing multiple implementations.</p>
<p>When comparing codebases, a better option is to focus on code structure: how functions, modules, and scopes relate and interact. For that, <strong>system block diagrams</strong> are a better fit.</p>
<h3 id="heading-why-use-system-block-diagrams"><strong>Why Use System Block Diagrams?</strong></h3>
<p>System block diagrams visualize a program at a higher level. They use labeled blocks to represent major components (functions, classes, modules) and arrows to show how data or control flows between them. This lets you focus on architecture: which part does what, and how do they work together?</p>
<p>Used for code comparison, placing two system block diagrams side by side immediately highlights structural and design differences. You can see at a glance how one solution favors modularity, another embeds logic in fewer blocks, or which one better separates concerns.</p>
<p>Still, system block diagrams can be drawn in different ways – some emphasizing structure, others workflow. Is there a format that combines both?</p>
<h3 id="heading-the-use-case-driven-system-block-diagram"><strong>The Use Case-Driven System Block Diagram</strong></h3>
<p>A strong candidate is the <strong>use case-driven system block diagram</strong>. <a target="_blank" href="https://www.clear.rice.edu/comp310/JavaResources/systemblockdiagrams.html">An example</a> of this variant is suggested as part of the resources for a computer science curriculum (“Advanced Object-Oriented Programming and Design” COMP310) of Rice University.</p>
<p>Unlike use case diagrams (which focus only on actors and goals), use case-driven system block diagrams are more implementation-focused. They still show modules and data flow, but through the lens of system functionality and user-driven logic.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746025297569/da5599e5-838a-4c90-bbf8-ddcaba58e36f.jpeg" alt="An example of Use Case-Driven System Block Diagram, by computer science students at Rice University" class="image--center mx-auto" width="1736" height="1327" loading="lazy"></p>
<p>Interestingly, the example above effectively exemplifies its usage for <strong>evaluating existing architectures</strong>. This confirms the suitability of this type of diagram for comparisons between codebases. Simply draw one diagram per implementation, striving to find their same functional goal. Then, compare their workflows and structures side by side. You’ll quickly spot which solution is more modular, more efficient, or easier to maintain.</p>
<h2 id="heading-what-we-are-going-to-do"><strong>What We Are Going to Do</strong></h2>
<p>To elaborate upon the suitability of this methodology for code analysis, we’ll apply the fundamentals of use case-driven system block diagram methodology to analyze five JavaScript projects’ code – each created by a different developer – implementing the Rock, Paper, Scissors game on <a target="_blank" href="https://codepen.io/">CodePen</a>.</p>
<p>The Rock, Paper, Scissors (RPS) game is a simple two-player challenge where each participant simultaneously shows either a “rock”, a “paper”, or “scissors” depicted by one of their hands, usually after a countdown. Then they apply the following rule to decide the “winner”:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746025625482/59c24cc3-d1e8-455b-8387-67733487e58d.jpeg" alt="Rules of the Rock Paper Scissors game, Wikipedia" class="image--center mx-auto" width="1438" height="1375" loading="lazy"></p>
<ul>
<li><p>Rock beats scissors</p>
</li>
<li><p>Scissors beats paper</p>
</li>
<li><p>Paper beats rock</p>
</li>
</ul>
<p>If both players choose the same option, it’s a tie.</p>
<p>In most programming versions, the player faces off against the computer, which makes random (or pseudo-random) choices. It’s a favorite beginner’s project because it’s easy to understand and fun to build.</p>
<h3 id="heading-the-code-examples">The Code Examples</h3>
<p>We are going to compare the (vanilla) JavaScript code for the following 5 projects, ordered by complexity:</p>
<ol>
<li><p><strong>“CPC Rock Paper Scissors”</strong> by Amit (@ghaste in CodePen)</p>
</li>
<li><p><strong>“Rock Paper Scissor game using native drag &amp; drop”</strong> by Hmz C (@HmZ2 in CodePen)</p>
</li>
<li><p><strong>“Rock Paper Scissors“</strong> by Brad Traversy (@bradtraversy in CodePen)</p>
</li>
<li><p><strong>“Rock Paper Scissors OOP“</strong> by Damian (@CvtS in CodePen)</p>
</li>
<li><p><strong>“Recurrent Neural Network - Rock, Paper, Scissors“</strong> by Andrew Worscerter (@amwmedia in CodePen)</p>
</li>
</ol>
<p>In order to keep the article shorter, the full code won’t be provided here, except for some exceptional cases. You are encouraged to visit the corresponding projects in CodePen to have a look at the code alongside the analysis. Because the authors can update or even delete the code in CodePen at any time, I’ll also add links to Gists with the code I analyzed at the time I wrote the article.  </p>
<p>Follow this link: <a target="_blank" href="https://gist.github.com/evaristoc/81dc9f508aa54c355f3f89b08a2450d5">https://gist.github.com/evaristoc/81dc9f508aa54c355f3f89b08a2450d5</a> if you want to find the copy of the JavaScript codes used for this article.</p>
<h4 id="heading-how-to-choose-your-projects">How to Choose Your Projects</h4>
<p>To find the projects, I searched CodePen for any pen about “Rock Paper Scissors”. Then I checked out the edits of some of them, and chose the ones I found the most interesting. I made a point to choose ones with varying complexities.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746808534102/acd2dba9-05d4-454d-8bb8-f4ee51dff304.jpeg" alt="Querying CodePen in search for the projects" class="image--center mx-auto" width="1875" height="875" loading="lazy"></p>
<h3 id="heading-the-scope"><strong>The Scope</strong></h3>
<p>First of all, our goal here isn’t to judge the quality of the codebases. Instead, it’s to demonstrate how we can use this diagram-based methodology to compare them.</p>
<p>CodePen projects often include quick demos, experiments, or even AI-generated snippets. Some developers might be more interested in the HTML/CSS of the project. But while they don’t always follow best practices, that’s what makes this exercise interesting – the diversity of approaches reveals valuable contrasts worth analyzing.</p>
<h3 id="heading-the-methodology"><strong>The Methodology</strong></h3>
<p>For the comparison, we’re using a methodology inspired by Rice University’s COMP310 course, which suggests the following high-level steps for constructing use case-driven system block diagrams:</p>
<ol>
<li><p><strong>Add all system use cases</strong> to a single diagram. These use cases will be similar to “steps in a workflow”.</p>
</li>
<li><p><strong>Group related cases</strong> within conceptually – or functionally – related operations.</p>
</li>
<li><p><strong>Encapsulate groups</strong> into modules (or blocks) based on roles and responsibilities. Start drawing the relationships (note: what we should understand for encapsulation here shouldn’t be confused with other definitions like the one given in OOP).</p>
</li>
<li><p><strong>Decouple operations</strong> as much as possible – refine scope and minimize interconnections.</p>
</li>
</ol>
<p>In order to allow the comparison between code examples, we will try to find cases (or steps), modules, and relations that are consistently similar between each code example, independently of the “architecture”.</p>
<p>Although UML compliance is encouraged in the original course, we’ll take a lighter approach – preserving the intent and structure without strictly following every UML rule.</p>
<h3 id="heading-how-well-build-the-diagrams">How We’ll Build the Diagrams</h3>
<p>The Rice course focuses more on <strong>what</strong> the diagram should show, but not so much on <strong>how</strong> to actually build it. For that, I refer to a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-flowcharts-with-mermaid/">previous article</a> where I broke down the diagram creation process. Here’s how the two approaches align:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Step</strong> (from earlier article)</td><td><strong>Corresponds to</strong> (Rice methodology)</td></tr>
</thead>
<tbody>
<tr>
<td>Define a scope</td><td>Identify the goal and context for your diagram</td></tr>
<tr>
<td>Find the start and end of the workflow</td><td>Identify use cases (actually, a general scanning of the workflow)</td></tr>
<tr>
<td>Identify deep-dive vs. generalized sections</td><td>Identify groups of cases. Prepare for modular encapsulation</td></tr>
<tr>
<td>Iterative refining and generalization</td><td>Applied throughout to improve module clarity and decoupling</td></tr>
<tr>
<td>Enhance and extend</td><td>Equivalent to fine-tuning and breaking dependencies</td></tr>
</tbody>
</table>
</div><p>Feel free to revisit that article if you want a more detailed walkthrough of these steps.</p>
<h3 id="heading-our-tool-mermaidjs">Our Tool: Mermaid.js</h3>
<p>To create the diagrams, we’ll use <a target="_blank" href="https://mermaid.js.org/"><strong>Mermaid.js</strong></a>, a JavaScript library that converts text into diagrams. It’s Markdown-compatible, which makes it especially handy for online projects, blog posts, and documentation.</p>
<p>The main reason I chose Mermaid.js is that diagrams are easily editable, so we can:</p>
<ul>
<li><p>Focus on defining relationships instead of worrying about layout</p>
</li>
<li><p>Easily iterate and update as we discover more structure in the code</p>
</li>
<li><p>Allows code reusability</p>
</li>
</ul>
<p>Mermaid.js is also highly configurable, allowing a certain level of customization. It was also made for the web, so it’s compatible with JavaScript, CSS and Markdown. But it’s not a perfect tool, and its use poses challenges both because of the limitations of the tool itself and even because of the limitations of using visual diagrams for code analysis.</p>
<p>If you aren’t familiar with using Mermaid.js, I wrote <a target="_blank" href="https://www.freecodecamp.org/news/use-mermaid-javascript-library-to-create-flowcharts/">an extensive tutorial</a> about the tool, along with its pros and cons. Although I will refrain from talking in-depth about Mermaid.js here, I will make use of some other tricks that were not included in previous articles.</p>
<p>Be aware that to keep consistency in sizing and titling all resulting diagrams were subjected to post-treatment, which also included color filtering to improve contrast.</p>
<h2 id="heading-five-code-examples-of-rock-paper-scissors">Five Code Examples of Rock, Paper, Scissors</h2>
<h3 id="heading-1-cpc-rock-paper-scissors-by-amit-a-project-with-fireworks-animations">1. “CPC Rock Paper Scissors” by Amit: A project with fireworks animations</h3>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/ghaste/embed/XWLxQEw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Amit is a prolific CodePen user who has been uploading about 2-3 projects per week since as early as 2021. Their most recent projects (year 2025) have increased in complexity and quality while maintaining the high productivity rate.</p>
<p>But in Sept 2024, Amit made a simple (JavaScript) version of the Rock, Paper, Scissors game. This code is a lightweight, user-friendly implementation with fun visual elements like result display, animations, and visual feedback for wins and losses.</p>
<p>Key features of this project are:</p>
<ul>
<li><p>It provides a complete Rock, Paper, Scissors game with a visual spinning effect when the computer is selecting its choice.</p>
</li>
<li><p>The game has animated fireworks to celebrate wins and changes the background color to red for losses.</p>
</li>
<li><p>The game keeps the interface interactive and fun through the use of emoji, quick animations, and visual feedback for the player’s performance.</p>
</li>
</ul>
<h3 id="heading-analysis-of-the-project">Analysis of the Project</h3>
<h4 id="heading-quickly-discovering-of-the-start-and-end-of-the-workflow">Quickly discovering of the start and end of the workflow</h4>
<p>The code of this pen runs immediately once it’s called. Several variables are initialized (the <code>animationContainer</code>, the <code>choices</code>, the <code>emojiMap</code>, and so on).  </p>
<p>Amit also made three separate functions for each item (that is, “rock”, “paper” and “scissors”). Each of them will be added as a <strong>click event</strong> to the interface (the HTML) and they all run the same function after clicking (<code>playGame</code>) each with a different argument based on what the user clicked.</p>
<p>After the interface is cleared, some variables are initialized, and the click event is added to the different emoji. The interface will wait for click interactions from the user, which will trigger the <code>playGame</code> function.</p>
<p>Let’s make a quick diagram showing this high level of generalization:</p>
<pre><code class="lang-mermaid">---
title: “CPC Rock Paper Scissors” by Amit - Simple SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph clickEventListener[Click Event]
    eventHandler@{shape: fr-rect, label: "event handler\n(*&lt;u&gt;playGame&lt;/u&gt;*)"}
end
end
init --&gt; |"(1) initialize values&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handler:**playGame**)"|interface
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface
end
style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746177298317/0b9f4609-9810-4ba5-8d8f-6e0869080fdb.jpeg" alt="Simple SB-Diagram of the RPS game by Amit" class="image--center mx-auto" width="501" height="725" loading="lazy"></p>
<h4 id="heading-the-playgame-event-handler">The <code>playGame</code> Event Handler</h4>
<p>Let’s take a closer look at the <code>playGame</code> function:</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">playGame</span>(<span class="hljs-params">playerChoice</span>) </span>{
    <span class="hljs-keyword">const</span> computerChoice = choices[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * choices.length)];
    <span class="hljs-keyword">const</span> animationDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"animation"</span>);
    <span class="hljs-keyword">const</span> resultDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"result"</span>);

    <span class="hljs-built_in">clearInterval</span>(animationInterval);
    <span class="hljs-keyword">let</span> currentIndex = <span class="hljs-number">0</span>;

    animationInterval = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      animationDiv.textContent = emojiMap[choices[currentIndex]];
      currentIndex = (currentIndex + <span class="hljs-number">1</span>) % choices.length;
    }, <span class="hljs-number">100</span>);

    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">clearInterval</span>(animationInterval);
      animationDiv.textContent = emojiMap[computerChoice];
      displayResult(playerChoice, computerChoice);
    }, <span class="hljs-number">1500</span>);
  }
</code></pre>
<p>It seems that there is a lot going on only in this function that could be assumed as separated functionalities. Although not explicit, there are different sections in it:</p>
<ul>
<li><p>one dedicated to calculating the computer’s choice</p>
</li>
<li><p>then a <code>setInterval</code> to handle an animation</p>
</li>
<li><p>then a <code>setTimeout</code> to clear the previous animation and run the <code>displayResult</code> function</p>
</li>
</ul>
<h4 id="heading-refinement">Refinement</h4>
<p>The first functionality operation that’s easy to identify within the whole code, and that could be set apart, is the one in charge of displaying the results: the <code>displayResult</code> func.</p>
<p>But we need to clarify the relationships in our diagram. The <code>displayResult</code> function is not coming after the event handler but is called from the event handler itself. We could argue that the event handler <em>uses</em> the <code>displayResult</code> function. Let’s clarify these definitions on the diagram, and also add a legend:</p>
<pre><code class="lang-mermaid">---
title: “CPC Rock Paper Scissors” by Amit - SB Diagram Refinement 01
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph clickEventListener[Click Event]
    eventHandler@{shape: fr-rect, label: "event handler\n(*&lt;u&gt;playGame&lt;/u&gt;*)"}
end
displayFunc@{shape: fr-rect, label: "display func\n(*&lt;u&gt;displayResult&lt;/u&gt;*)"} -.-o eventHandler
end
init -.-o |"(1) initialize values&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handler:**playGame**)"|interface@{shape: curv-trap, label: "interface display"}
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface

subgraph legend
      direction LR
      start1[ ] --&gt;|"next step"| stop1[ ]
      style start1 height:0px;
      style stop1 height:0px;
      start2[ ] -.-o|"assignation"| stop2[ ]
      style start2 height:0px;
      style stop2 height:0px; 
end

end

interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746177264415/e826d8e8-bddb-4f9e-9f86-8454f4671ac1.jpeg" alt="First Refinement of SB-Diagram of the RPS game by Amit" class="image--center mx-auto" width="534" height="1004" loading="lazy"></p>
<p>Similarly, the <code>displayResult</code> function uses two functions dedicated to the animations: <code>triggerFireworks</code> and <code>triggerLossBackground</code>. All the functions are declared on the <em>main scope</em>.</p>
<pre><code class="lang-mermaid">---
title: “CPC Rock Paper Scissors” by Amit - SB Diagram Refinement 02
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
data@{shape: lean-r, label: "&lt;span style="color:#f1ce32"&gt;constants&lt;/span&gt;"} --&gt; eventHandler
init
subgraph clickEventListener[Click Event]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;playGame&lt;/code&gt;&lt;br/&gt;event handler"}
end
    displayFunc@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;displayResult&lt;/code&gt;&lt;br/&gt;display func"} -.-o |"(3) the event handler calls the display function"| eventHandler
    display01@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;triggerFireworks&lt;/code&gt;&lt;br/&gt;animation"} -.-o displayFunc
    display02@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;triggerLossBackground&lt;/code&gt;&lt;br/&gt;animation"} -.-o displayFunc
end
init -.-o |"(1) initialize values&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handler:&lt;code style="color:orange;"&gt;playGame&lt;/code&gt;)"|interface@{shape: curv-trap, label: "interface display"}
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
eventHandler --&gt; |"(4) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746177244326/42474333-e6c5-499e-ba95-86541ebd525b.jpeg" alt="Second Refinement of SB-Diagram of the RPS game by Amit" class="image--center mx-auto" width="537" height="925" loading="lazy"></p>
<h4 id="heading-imperative-programming">Imperative Programming</h4>
<p>This code is very much imperative. Here’s a definition of imperative programming from Wikipedia:</p>
<blockquote>
<p>Imperative programming focuses on describing <em>how</em> a program operates step by step (generally order of the steps being determined in source code by the placement of statements one below the other), rather than on high-level descriptions of its expected results</p>
</blockquote>
<p>Finding that the project follows an imperative paradigm is helpful as it provides some general idea of what we can expect in terms of how the code is organized and the type of logic we might use. We can expect that the computation logic will follow a certain workflow.</p>
<h4 id="heading-finalizing-the-diagram">Finalizing the diagram</h4>
<p>Now that we have uncovered the most explicit modules and their relationships, we can work on identifying sections of the code that might be considered separated functional/operational units. These separate units can be defined as “use cases” and will become the steps of the workflow.</p>
<p>As a way of enhancing the diagram, I have differentiated between steps and process blocks to prevent confusion between “modules” and “cases”.</p>
<pre><code class="lang-mermaid">---
title: “CPC Rock Paper Scissors” by Amit - Final SB Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
choices ~~~ stop
subgraph main
init
data@{shape: lean-r, label: "&lt;span style="color:#f1ce32"&gt;constants&lt;/span&gt;"} --&gt; eventHandler
subgraph clickEventListener[Click Event]
    subgraph eventHandler["&lt;code style="color:orange"&gt;playGame&lt;/code&gt;&lt;br/&gt;event handler"]
       subgraph step03[step03 - result handling and presentation]
        delay01
        delay02
        delay01 ~~~ nonode01[ ]
        style nonode01 fill:none,stroke:none;
       end
       step01@{label: "step01 - compute computer choice"} --&gt; step02@{label: "step02 - prepare display"}
       step02 --&gt; delay01@{shape: delay, label: setInterval}
       delay01 --&gt; delay02@{shape: delay, label: setTimeout}
    end
end
    subgraph displayFunc["&lt;code style="color:orange"&gt;displayResult&lt;/code&gt;&lt;br/&gt;display func"]
       step04@{label: "step01 - compute winner"} --&gt; step05@{label: "step02 - show results"}
    end
    displayFunc -.-o |"(3) the event handler calls the display function"| delay02
    display01@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;triggerFireworks&lt;/code&gt;&lt;br/&gt;animation"} -.-o step05
    display02@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;triggerLossBackground&lt;/code&gt;&lt;br/&gt;animation"} -.-o step05
end
init -.-o |"(1) initialize values&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handler:&lt;code style="color:orange;"&gt;playGame&lt;/code&gt;)"|interface@{shape: curv-trap, label: "interface display"}
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
step05 --&gt; |"(4) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      stepLegend["----step----"]
      style stepLegend fill:#474949, stroke: #CCC, color:#CCC
      end
end
end

interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,displayFunc subProc
classDef step fill:#474949, stroke: #CCC, color:#CCC
class step01,step02,step03,step04,step05,step06 step
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746178100298/bf5f7240-b125-4780-aaf8-fdbbdd911390.jpeg" alt="Final SB Diagram of the RPS game by Amit" class="image--center mx-auto" width="477" height="990" loading="lazy"></p>
<p>Let’s summarize what’s happening here:</p>
<ul>
<li><p>In this project, a function acting as an event handler contains most of the project logic and it assumes full execution responsibility over some of the steps of the workflow.</p>
</li>
<li><p>Once the event handler is triggered, the choice of the user is passed to it and the same function calculates the choice of the computer.</p>
</li>
<li><p>That calculation is followed by part of the preparation of the interface, then an animation managed by an <code>Interval</code> – followed by a nested <code>Timeout</code> JavaScript method.</p>
</li>
<li><p>The Timeout method has the <code>displayResult</code> function as a callback function. This function will take the responsibility of the remaining steps.</p>
</li>
<li><p>It is inside the <code>displayResult</code> where the calculation of the winner takes place. The same function controls the rest of the display of results with different displays delegated to two other functions based on who wins the game.</p>
</li>
</ul>
<h3 id="heading-2-rock-paper-scissors-game-using-native-drag-amp-drop-by-hmz-c-a-project-using-the-html-drag-element">2. “Rock paper scissors game using native drag &amp; drop” by Hmz C: A project using the HTML Drag element</h3>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/HmZ2/embed/yLPGpg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Hmz C has not been so active as Amit, with just 7 projects in CodePen across 10 years since 2014. The pen we are going to analyze is his very first contribution to CodePen. The project appears to be a demo of the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API">HTML Drag and Drop API</a> that came with HTML5 by the time of its release. The game provides a clean and interactive experience of "Rock, Paper, Scissors" using intuitive drag-and-drop gestures, visual effects, and live score updates. It focuses on user experience and interactivity.</p>
<p>Key features of this project are:</p>
<ul>
<li><p>The drag and drop interaction, with simple but clean animations.</p>
</li>
<li><p>The scoring is central to this application. Both user and computer scores are updated and displayed in real-time.</p>
</li>
<li><p>The game provides a very clean, easy-to-understand interface without looking static.</p>
</li>
</ul>
<h3 id="heading-analysis-of-the-project-1">Analysis of the Project</h3>
<h4 id="heading-quickly-discovering-of-the-start-and-end-of-the-workflow-1">Quickly discovering of the start and end of the workflow</h4>
<p>By inspecting the code, you will be able to realize that this code follows a similar general pattern as the code we previously examined:</p>
<ul>
<li><p>Variables and states are initialized immediately when the project is accessed.</p>
</li>
<li><p>Similarly, an event handler is added to elements in the interface, but this time they won’t respond to click events but to <strong>drag and drop</strong> events.</p>
</li>
<li><p>That event handler is the one that starts and coordinates the workflow.</p>
</li>
<li><p>The workflow ends by showing results on the interface.</p>
</li>
</ul>
<p>Given the similarities between this project and the previous at this level of analysis, I reused the script I created for the previous chart and modified it accordingly.</p>
<pre><code class="lang-mermaid">---
title: “Rock paper scissors game using native drag &amp; drop” by Hmz C - Simple SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph dropEventListener[Drop Event Listener]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"}
end
end
init -.-o |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers for: &lt;code style='color:#f1ce32;'&gt;dragstart dragenter dragleave dragover drop&lt;/code&gt;)"|interface
dropEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded, label: dragged choice} --&gt; |"(2) user drag a choice to an area: either paper, rock or scissors"| dropEventListener
dropEventListener --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
        variable["variable"]
        style variable width:135px, fill:none, stroke:none, color:#f1ce32
        subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746315569277/60685986-16dd-4cb0-8290-252ed69114bf.jpeg" alt="Simple SB-Diagram of the RPS game by Hmz C" class="image--center mx-auto" width="710" height="942" loading="lazy"></p>
<h4 id="heading-iife">IIFE</h4>
<p>This project is the only one that uses an IIFE (Immediately Invoked Function Expression) pattern to register the drag and drop listeners. It is inside that IIFE (<code>user</code>) where the <strong>drop listener</strong> is also declared.</p>
<pre><code class="lang-javascript">(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">user</span>(<span class="hljs-params"></span>) </span>{

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; hand.length; i++) {
        hand[i].ondragstart = dragStart;
    }

    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">dragStart</span>(<span class="hljs-params"></span>) </span>{
        userChoice = <span class="hljs-built_in">this</span>.getAttribute(<span class="hljs-string">"data-hand"</span>);
    }

    userArea.addEventListener(<span class="hljs-string">'dragenter'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
        e.preventDefault();
        <span class="hljs-built_in">this</span>.style.borderColor = <span class="hljs-string">"red"</span>;
        user_icon.style.visibility = <span class="hljs-string">"hidden"</span>;
    });

    userArea.addEventListener(<span class="hljs-string">'dragleave'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
        e.preventDefault();
        <span class="hljs-built_in">this</span>.style.borderColor = <span class="hljs-string">"#dedede"</span>;
        user_icon.style.visibility = <span class="hljs-string">"initial"</span>;
    });

    userArea.addEventListener(<span class="hljs-string">'dragover'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
        e.preventDefault();
    });

    userArea.addEventListener(<span class="hljs-string">'drop'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
        e.preventDefault();
        computerChoice = cpu();
        user_icon.classList.remove(<span class="hljs-string">"fa-spin"</span>);
        user_icon.className = <span class="hljs-string">"fa fa-hand-"</span> + userChoice + <span class="hljs-string">"-o fa-2x fa-fw"</span>;
        computer_icon.className = <span class="hljs-string">"fa fa-hand-"</span> + computerChoice + <span class="hljs-string">"-o fa-2x fa-fw"</span>;
        <span class="hljs-built_in">this</span>.style.borderColor = <span class="hljs-string">"#dedede"</span>;
        user_icon.style.visibility = <span class="hljs-string">"initial"</span>;
        whowins(computerChoice, userChoice);
    });
})();
</code></pre>
<p>This project was completed before the release of ES6 in 2015. One of the uses of the pattern is to keep the variables and functions within the IIFE isolated from the global scope. Although the IIFE is still a valid syntax, in modern JavaScript most of the functional operations where the IIFE pattern is applicable can now be implemented with the use of special keywords, special operations, and standards.</p>
<h4 id="heading-refinement-1">Refinement</h4>
<p>Apart of the event handler, there are two other functions – the <code>cpu</code> function and the <code>whowins</code> function – that will take care of other aspects of the functionality. Those functions are declared in the global scope.</p>
<pre><code class="lang-mermaid">---
title: “Rock paper scissors game using native drag &amp; drop” by Hmz C - SB-Diagram Refinement
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph dropEventListener[Drop Event Listener]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"}
end
cpu@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;cpu&lt;/code&gt;&lt;br/&gt;computer choice calc"} -.-o eventHandler
whowins@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;whowins&lt;/code&gt;&lt;br/&gt;winner calc / update / display func"} -.-o eventHandler
changeColor@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;changeColor&lt;/code&gt;&lt;br/&gt;animation func"} -.-o whowins
end
init -.-o |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers for: &lt;code style='color:#f1ce32;'&gt;dragstart dragenter dragleave dragover drop&lt;/code&gt;)"|interface
dropEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded, label: dragged choice} --&gt; |"(2) user drag a choice to an area: either paper, rock or scissors"| dropEventListener
dropEventListener --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
        variable["variable"]
        style variable width:135px, fill:none, stroke:none, color:#f1ce32
        subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746315095906/70866854-a624-48b5-89ea-4dcb5d7f5eeb.jpeg" alt="Refinement of SB Diagram of the RPS game by Hmz C" class="image--center mx-auto" width="752" height="941" loading="lazy"></p>
<p>Now that we have an overview of how the declared functions are related, let’s identify the functional operations they are taking care of and have a better idea of the full workflow.</p>
<h4 id="heading-finalizing-the-diagram-and-comparison-to-previous-project">Finalizing the diagram and comparison to previous project</h4>
<p>After inspecting the code and making several iterations over the previous diagram, I came up with the following final result. Reusing parts of the script I made for the previous project helped me reduce the number of iterations.</p>
<pre><code class="lang-mermaid">---
title: “Rock paper scissors game using native drag &amp; drop” by Hmz C - Final SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph __
subgraph main
init
data@{shape: lean-r, label: "&lt;code style='color:#f1ce32;'&gt;userScore computerScore&lt;/code&gt; variables"} -.-o whowins
step05 --&gt; data
subgraph dropEventListener[Drop Event Listener]
    subgraph eventHandler["&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"]
        step01@{label: "step01 - compute\ncomputer choice"} --&gt; step02@{label: "step02 - prepare\ndisplay"}
        step02 --&gt; step03@{label: "step03 - result handling\nand presentation"}
    end
end
cpu@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;cpu&lt;/code&gt;&lt;br/&gt;computer choice calc"} -.-o step01
subgraph whowins["&lt;code style="color:orange"&gt;whowins&lt;/code&gt;&lt;br/&gt;winner calc / update / display func"]
    step04@{label: "step01 - calculate winner"} --&gt;
    step05@{label: "step02 - update stored data"} --&gt;
    step06@{label: "step03 - update interface"}
end
whowins -.-o step03
changeColor@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;changeColor&lt;/code&gt;&lt;br/&gt;animation func"} -.-o step06
end
init -.-o |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers for: &lt;code style='color:#f1ce32;'&gt;dragstart dragenter dragleave dragover drop&lt;/code&gt;)"|interface
dropEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded, label: dragged choice} --&gt; |"(2) user drag a choice to an area: either paper, rock or scissors"| dropEventListener
step06 --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      stepLegend["----step----"]
      style stepLegend fill:#474949, stroke: #CCC, color:#CCC
      end
end

interface ~~~ legend
end

style start fill:black
style stop fill:black, fill-stroke:white
classDef clTopr fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,whowins clTopr
classDef step fill:#474949, stroke: #CCC, color:#CCC
class step01,step02,step03,step04,step05,step06 step
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746314611833/a54d5c7a-bd10-4a74-aea2-37176e14908b.jpeg" alt="Final SB Diagram of the RPS game by Hmz C" class="image--center mx-auto" width="693" height="932" loading="lazy"></p>
<p>Notice the strong similarities between this project and the previous one:</p>
<ul>
<li><p>The order of the steps</p>
</li>
<li><p>The imperative code structure</p>
</li>
<li><p>The event handler delegates the final steps to another function</p>
</li>
<li><p>That function (<code>whowins</code>) executes the calculation of the winner</p>
</li>
<li><p>That same function delegates the display of the results to a different function (<code>changeColor</code>)</p>
</li>
<li><p>There is a preference for using functions and variables declared in the global scope</p>
</li>
</ul>
<p>What is different in this project is:</p>
<ul>
<li><p>The event handler is declared as an anonymous callback function directly in the listener</p>
</li>
<li><p>This event handler delegates the execution of the calculation of choice of the computer to a different function, the <code>cpu</code> function.</p>
</li>
<li><p>There are no async functionalities in this project</p>
</li>
<li><p>Different from the previous project, this one has a slightly more advanced <strong>data handling</strong>. Data were stored in global variables (<code>userScore</code>, <code>computerScore</code>) that are updated just after the calculation of the winner.</p>
</li>
</ul>
<h3 id="heading-3-rock-paper-scissors-by-brad-traversy-a-project-with-a-modal-and-a-reset">3. “Rock Paper Scissors” by Brad Traversy: A project with a modal and a reset</h3>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/bradtraversy/embed/wLgPzr" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>If you started self-learning JavaScript at some point between 2015 and today (2025), you might have heard of this guy. <a target="_blank" href="https://www.linkedin.com/in/bradtraversy">Brad Traversy</a> is a legend among those learning to code and has also made his own learning program.</p>
<p>The number of resources produced by Brad is immense. His first contribution to CodePen dates back to 2017. His activity in CodePen has declined with the time, but he has been posting valuable resources nonetheless.</p>
<p>In 2019 he made this Rock Paper Scissors game. This code delivers a straightforward but engaging implementation with a dynamic user interface. The integration of a randomized computer choice, score tracking, and modal result display creates an interactive and visually appealing experience for users.</p>
<p>Key features of this project are:</p>
<ul>
<li><p><strong>Randomized opponent choice</strong>: The computer's move is randomized each round to simulate an unpredictable opponent.</p>
</li>
<li><p><strong>Dynamic modal display</strong>: A modal window shows round results for a polished, user-friendly experience.</p>
</li>
<li><p><strong>Re-starting the game</strong>.</p>
</li>
<li><p><strong>Score persistence across rounds</strong>: The scoreboard tracks scores until the game is manually reset, allowing for continuous gameplay.</p>
</li>
</ul>
<h3 id="heading-analysis-of-the-project-2">Analysis of the Project</h3>
<h4 id="heading-quickly-discovering-of-the-start-and-end-of-the-workflow-2">Quickly discovering of the start and end of the workflow</h4>
<p>Inspecting this other code reveals a definitive pattern in the way the game is set. Similarly to the previous projects, in this one:</p>
<ul>
<li><p>it initializes variables and states immediately after the project is accessed</p>
</li>
<li><p>it has event handlers added to the corresponding HTML elements in the interface</p>
</li>
<li><p>a function is usually associated to the event handler which is the one that coordinates the workflow – in this case the <code>play</code> function.</p>
</li>
<li><p>the workflow ends by showing results on the interface</p>
</li>
</ul>
<p>Also, this project in particular involves a second event handler with a function to close a modal used to show the results. A third event handler is added to restart the game.</p>
<p>Again, given the similarities between this project and the previous ones at this level of analysis, I reused the script I created and modified it accordingly.</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors” by B. Traversy - Simple SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph clickEventListener[Click Event]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;play&lt;/code&gt;&lt;br/&gt;event handler"}
end
end
init --&gt; |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers:&lt;code style="color:orange"&gt;playGame clearModal restartGame&lt;/code&gt;)"|interface
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface
end
style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746314052265/03bf54f2-a2a6-4a9b-91ec-7465082314db.jpeg" alt="Simple SB-Diagram of the RPS game by B. Traversy" class="image--center mx-auto" width="502" height="797" loading="lazy"></p>
<h4 id="heading-refinement-2">Refinement</h4>
<p>This project takes a step forward in designing an event handler, the <code>play</code> function. Its sole responsibility would be to delegate operations to other functions.</p>
<p>Three functions are called from this event handler:</p>
<ul>
<li><p><code>getComputerChoice</code></p>
</li>
<li><p><code>getWinner</code></p>
</li>
<li><p><code>showWinner</code></p>
</li>
</ul>
<p>Notice that again, all those functions are declared in the global scope – but this time, the <code>play</code> function is also in the same scope.</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors” by B. Traversy - SB-Diagram Refinement
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
getComp@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;getComputerChoice&lt;/code&gt;&lt;br/&gt;computer choice func"} -.-o eventHandler
getWinner@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;getWinner&lt;/code&gt;&lt;br/&gt;winner calc func"} -.-o eventHandler
displayFunc@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;showWinner&lt;/code&gt;&lt;br/&gt;display func"} -.-o eventHandler
init
subgraph clickEventListener[Click Event]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;play&lt;/code&gt;&lt;br/&gt;event handler"}
end
end
init -.-o |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers:&lt;code style="color:orange"&gt;playGame clearModal restartGame&lt;/code&gt;)"|interface@{shape: curv-trap, label: "interface display"}
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choicess@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746312146770/922d42c9-f993-4287-8e2c-53b5a4c9b17f.jpeg" alt="Refinement of the SB-Diagram of the RPS game by B. Traversy" class="image--center mx-auto" width="529" height="821" loading="lazy"></p>
<h4 id="heading-the-play-event-handler-as-a-controller"><em>The</em> <code>play</code> <em>event handler as a Controller</em></h4>
<p>In this project, the <code>play</code> function resembles more the idea of a <strong>controller</strong>. The tasks of this event handler are reduced to act as a delegator, something that we have not seen fully implemented in the previous projects.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Play game</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">play</span>(<span class="hljs-params">e</span>) </span>{
  restart.style.display = <span class="hljs-string">'inline-block'</span>;
  <span class="hljs-keyword">const</span> playerChoice = e.target.id;
  <span class="hljs-keyword">const</span> computerChoice = getComputerChoice();
  <span class="hljs-keyword">const</span> winner = getWinner(playerChoice, computerChoice);
  showWinner(winner, computerChoice);
}
</code></pre>
<p>The <strong>Controller Pattern</strong> is a common architectural pattern used in interactive applications to manage user input by directing it to other components for processing and coordination. The <code>play</code> controller will be the one coordinating the actions once the user calls the function from the interface.</p>
<h4 id="heading-modularity-and-separatation-of-concerns-soc"><em>Modularity and Separatation of Concerns (SoC)</em></h4>
<p>However, this one is very <strong>modular</strong>, following a structured procedural flow.</p>
<p>That modularity could be associated to achieving a better Separation of Concerns, or SoC. SoC involves designing code so each section of the code is handled by a different operational unit. Despite its size, this code shows attention to that principle in the form of functions.</p>
<h4 id="heading-procedural-programming"><em>Procedural Programming</em></h4>
<p><strong>Procedural programming</strong> is a form of imperative programming where procedures are delegated to functions. The way the project is designed is more in accordance to those practices.</p>
<h4 id="heading-finalizing-the-diagram-and-comparison-to-previous-projects">Finalizing the diagram and comparison to previous projects</h4>
<p>The functional operations of the functions called by the controller are more evident from the final diagram for this project:</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors” by B. Traversy - Final SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
data@{shape: lean-r, label: "&lt;code style='color:#f1ce32'&gt;scoreboard&lt;/code&gt; object"} -.-o displayFunc
step05 --&gt; data
subgraph clickEventListener[Click Event]
    subgraph eventHandler["&lt;code style="color:orange"&gt;play&lt;/code&gt;&lt;br/&gt;event handler"]
        step01@{label: "step01 - prepare display"} --&gt; step02@{label: "step02 - compute\ncomputer choice"}
        step02 --&gt; step03@{label: "step03 - compute winner"} --&gt; step04@{label: "step04 - result handling and presentation"}
    end
end
getComp@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;getComputerChoice&lt;/code&gt;&lt;br/&gt;computer choice func"} -.-o step02
getWinner@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;getWinner&lt;/code&gt;&lt;br/&gt;winner calc func"} -.-o step03
subgraph displayFunc["&lt;code style="color:orange"&gt;showWinner&lt;/code&gt;&lt;br/&gt;display func"]
    step05@{label: "stpp01 - update stored data"} --&gt; step06@{label: "step02 - show results\nin a modal"}
end
displayFunc -.-o step04
end
init -.-o |"(1) initialize values and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers:&lt;code style="color:orange"&gt;playGame clearModal restartGame&lt;/code&gt;)"|interface@{shape: curv-trap, label: "interface display"}
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
step06 --&gt; |"(3) animations, results"| interface
restartGame@{shape: rounded} --&gt; |"(4a) restart data"| data
restartGame --&gt; |"(4b) clean interface"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      stepLegend["----step----"]
      style stepLegend fill:#474949, stroke: #CCC, color:#CCC
      end
end
end

interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,displayFunc subProc
classDef step fill:#474949, stroke: #CCC, color:#CCC
class step01,step02,step03,step04,step05,step06 step
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746311699920/0c89b8c0-aa93-418f-858f-171006c4bacc.jpeg" alt="Final SB Diagram of the RPS game by B. Traversy" class="image--center mx-auto" width="618" height="900" loading="lazy"></p>
<p>Let’s point out the different steps carried out by the delegated functions:</p>
<ul>
<li><p>The <code>getComputerChoice</code> is in charge of calculating the computer’s choice.</p>
</li>
<li><p>Results are collected by the controller and passed to another function, <code>getWinner</code>, which is in charge of calculating the winner.</p>
</li>
<li><p>Then the results of the <code>getWinner</code> function are collected by the controller and passed to the next function, <code>showWinner</code>.</p>
</li>
<li><p>The <code>showWinner</code> function has a similar design as the one made by Hmz C for his project. It will have just one less responsibility, and will take only responsibilities for data handling of a slightly more complex data type for the capture and maintance of the current score (the <code>scoreboard</code> object), as well as displaying results.</p>
</li>
</ul>
<p>Despite of the differences in the way the code was designed, the order of the steps is very similar to the projects we have discussed before.</p>
<p>Other features different from the previous code examples are the existence of a modal for result presentation and a reset functionality. We are not discussing them as they fall outside of the scope of the analyses, which is the design of the Rock, Paper, Scissors game.</p>
<h3 id="heading-4-rock-paper-scissors-oop-by-damian-a-project-written-in-oop">4. “Rock Paper Scissors OOP” by Damian: A project written in OOP</h3>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/CvtS/embed/oNXqJoZ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Damian has 3 projects on CodePen, all of them made in 2020. One of them is this game. The JavaScript code implements another variation of the "Rock, Paper, Scissors" game but with a more object-oriented approach using classes to manage the game logic, player choices, and statistics.</p>
<p>This is a well-organized, object-oriented version of the "Rock, Paper, Scissors" game with a clean separation of concerns (result calculation, player/computer choice, and game statistics). The use of animations and UI interactions enhances the user experience.</p>
<p>Key features of this project are:</p>
<ul>
<li><p><strong>Object-oriented design</strong>: The code is structured into classes, making it modular, reusable, and easier to maintain.</p>
</li>
<li><p><strong>Interactive UI</strong>: It dynamically updates the player’s and computer’s choices using visual cues (CSS classes) and shows animations for draws.</p>
</li>
<li><p><strong>Statistics</strong>: The game tracks and updates the number of wins, draws, and losses, which are displayed in real-time.</p>
</li>
</ul>
<h3 id="heading-analysis-of-the-project-3">Analysis of the Project</h3>
<h4 id="heading-quickly-discovering-the-start-and-end-of-the-workflow">Quickly discovering the start and end of the workflow</h4>
<p>This code seems more complex than what we’ve previously examined. But a closer look suggests certain resemblance to the previous ones, at least at a high level of generalization:</p>
<ul>
<li><p>Again, variables and states are initialized once the project is accessed.</p>
</li>
<li><p>One of the variables that’s initialized when the project is accessed is an instance of a class, the <code>Game</code> class. The instance is called <code>newGame</code>.</p>
</li>
</ul>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors OOP” by Damian - Simple SB-Diagram 01
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
    gameInst@{shape: fr-rect, label: "Game instance"}
end
gameInst -.-o |"(1) instantiate classes, values, and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (events: &lt;code&gt;startGame&lt;/code&gt; method bound to &lt;code&gt;this&lt;/code&gt;)"|interface
gameInst --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; gameInst
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| gameInst
gameInst --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class gameInst inst
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746311035208/e9dee7a0-2428-4c08-bc41-37b81846ae34.jpeg" alt="First Simple SB-Diagram of the RPS game by Damian" class="image--center mx-auto" width="523" height="939" loading="lazy"></p>
<p>Again, we can see aspects of this workflow that coincide with what we found in the previous projects – but this time those similarities are more difficult to capture. As in the previous code, the <strong>controller pattern</strong> is prevalent in this code, but instead of being associated with an anonymous function or a global one, it is now a <strong>class’s module</strong>.</p>
<p>The instantiation of the class runs the constructor which includes the immediate assignment of click event handlers into the interface (just as with the other projects). They use a module of the class, the <code>startGame</code> module, as a callback function.</p>
<p>The (syntactic) approach that Damian chose adds additional complexities to the code in terms of scope definition. You can spot some of the complexities by realizing the need to use the JavaScript <code>bind</code> method in order to keep the <code>this</code> context of the module function the same as the one of the instance when assigned to the event.</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.optionsImg = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'.img'</span>);
    <span class="hljs-built_in">this</span>.optionsBtns = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'button'</span>);

    <span class="hljs-built_in">this</span>.optionsBtns.forEach(<span class="hljs-function"><span class="hljs-params">option</span> =&gt;</span> option.addEventListener(<span class="hljs-string">'click'</span>, 
                                                                <span class="hljs-built_in">this</span>.startGame.bind(<span class="hljs-built_in">this</span>) <span class="hljs-comment">//see the bind here</span>
                                                                )
                            )

    <span class="hljs-built_in">this</span>.youWins = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.results &gt; .you-win'</span>);
    <span class="hljs-built_in">this</span>.draw = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.results &gt; .draw'</span>);
    <span class="hljs-built_in">this</span>.PcWins = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'.results &gt; .pc-win'</span>);

    <span class="hljs-built_in">this</span>.stats = <span class="hljs-keyword">new</span> Stats(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);

    <span class="hljs-built_in">this</span>.render.call(<span class="hljs-built_in">this</span>, <span class="hljs-built_in">this</span>.stats.getStats());
  }
</code></pre>
<p>In order to represent that, I used a colored link, indicating that the game instance (through the constructor) is set to be the <code>this</code> context of the module.</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors OOP” by Damian - Simple SB-Diagram 02
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
    subgraph gameInst[&lt;code&gt;Game instance&lt;/code&gt;]
        gameConstrt@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;Game constructor&lt;/code&gt;"}
        startGame@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;startGame&lt;/code&gt;&lt;br/&gt;method / event handler"}
        gameConstrt -.-o startGame 
    end
end
gameConstrt -.-o |"(1) instantiate classes, values, and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (events: &lt;code style="color:orange;"&gt;startGame&lt;/code&gt; method bound to &lt;code&gt;this&lt;/code&gt;)"|interface
startGame --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; gameInst
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| startGame
gameInst --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
        start3[ ] -.-o|"context of"| stop3[ ]
        linkStyle 8 stroke:yellow, stroke-width:5px
        style start3 height:0px;
        style stop3 height:0px;
      end
      subgraph shapes
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,gameConstrt subProc
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class gameInst inst
linkStyle 0 stroke:yellow, stroke-width: 5px
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746310389266/a078bebe-dee4-47b1-a5e8-c164008878e9.jpeg" alt="Second Simple SB-Diagram of the RPS game by Damian" class="image--center mx-auto" width="526" height="940" loading="lazy"></p>
<h4 id="heading-refinement-3">Refinement</h4>
<p>By adding the evaluation of the classes, the flow diagram gets more detailed but also more complicated.</p>
<p>Damian defined 4 classes for this project: <code>Result</code>, which was just a static method, <code>Choice</code>, <code>Stats</code> and <code>Game</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Result</span> </span>{
  <span class="hljs-keyword">static</span> whoWin(yourChoice, PCchoice) {
    ...
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Choice</span> </span>{
  <span class="hljs-keyword">constructor</span>(yourChoice) {
    ...
  }

  getYourChoice = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.yourChoice;
  getPcChoice = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.PCchoice;

  drawPcChoice() {
    ...
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stats</span> </span>{
  <span class="hljs-keyword">constructor</span>(wins, draws, loses) {
    ...
  }
  getStats = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.status;

  refreshStats(result) {
    ...
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Game</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    ...
  }

  startGame(e) {
    ...
  }

  render(stats) {
    ...
  }
}

<span class="hljs-keyword">const</span> newGame = <span class="hljs-keyword">new</span> Game();
</code></pre>
<p>The best way to keep the diagram simpler is not to detail all the steps of the functionalities. But since I’m mentioning instances, I also felt the urgency to relate those to the corresponding class. I did it using a different line type and color.</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors OOP” by Damian - SB-Diagram Refinement
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
    subgraph gameInst[&lt;code&gt;Game instance&lt;/code&gt;]
        gameConstrt@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;Game constructor&lt;/code&gt;"}
        startGame@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;startGame&lt;/code&gt;&lt;br/&gt;method / event handler"}
        render@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;render&lt;/code&gt;\ndisplay method"}
        gameConstrt -.-o startGame
    end
    classGame@{shape: rounded, label: "Game class"} -.- gameInst
    classStat@{shape: rounded, label: "Stat class"} -.-o gameConstrt
    classResult@{shape: rounded, label: "Result class"} -.-o startGame
    classChoice@{shape: rounded, label: "Choice class"} -.-o startGame
    classStat -.-o render
end
gameConstrt -.-o |"(1) instantiate classes, values, and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (events: &lt;code style="color:orange;"&gt;startGame&lt;/code&gt; method bound to &lt;code&gt;this&lt;/code&gt;)"|interface
gameInst --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; gameInst
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| startGame
gameInst --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
        start3[ ] -.-o|"context of"| stop3[ ]
        linkStyle 13 stroke:yellow, stroke-width:5px
        style start3 height:0px;
        style stop3 height:0px;
        start4[ ] -.-|"instance of"| stop4[ ]
        linkStyle 14 stroke:skyblue, stroke-width:4px
        style start4 height:0px;
        style stop4 height:0px;
      end
      subgraph shapes
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      stepLegend["----step----"]
      style stepLegend fill:#474949, stroke: #CCC, color:#CCC
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef isaclass fill:grey
class classGame,classChoice,classResult,classStat isaclass
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,gameConstrt subProc
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class gameInst inst
linkStyle 0,5 stroke:yellow, stroke-width: 5px
linkStyle 1 stroke:skyblue, stroke-width:4px
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746308587568/b17961e2-8c97-4446-956c-85fe1a8b8630.jpeg" alt="b17961e2-8c97-4446-956c-85fe1a8b8630" class="image--center mx-auto" width="543" height="936" loading="lazy"></p>
<p>With the diagram above, I tried to highlight some exceptional aspects of the architecture of this code. At some point, a <code>Stats</code> class’s instance will be context for the <code>render</code> method of the <code>Game</code> class’s instance. I added connections between classes and the workflow to indicate that the classes were used on those steps of the workflow.</p>
<h4 id="heading-oop-encapsulation">OOP Encapsulation</h4>
<p>One way to improve the SoC of your project is through encapsulation. <strong>Encapsulation</strong> is a concept usually related to OOP and it’s about keeping data and the methods that work with that data bundled in the same class.</p>
<p>This project shows efforts to achieve encapsulation:</p>
<ul>
<li><p>The <code>Stats</code> instance it is the one that will store the data, and the methods are in accordance to its task:</p>
<pre><code class="lang-javascript">  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stats</span> </span>{
    <span class="hljs-keyword">constructor</span>(wins, draws, loses) {
      <span class="hljs-built_in">this</span>.status = {
        <span class="hljs-attr">wins</span>: wins,
        <span class="hljs-attr">draws</span>: draws,
        <span class="hljs-attr">loses</span>: loses,
      }
    }
    getStats = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.status;

    refreshStats(result) {
      <span class="hljs-keyword">switch</span> (result) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">"win"</span>:
          <span class="hljs-built_in">this</span>.status.wins++;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"draw"</span>:
          <span class="hljs-built_in">this</span>.status.draws++;
          <span class="hljs-keyword">break</span>;
        <span class="hljs-keyword">case</span> <span class="hljs-string">"lose"</span>:
          <span class="hljs-built_in">this</span>.status.loses++;
          <span class="hljs-keyword">break</span>;
      }
    }
  }
</code></pre>
</li>
<li><p>The <code>Choice</code> instance will be dedicated to the calculation of the choices, and so it contains methods that respond to that task:</p>
<pre><code class="lang-javascript">  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Choice</span> </span>{
    <span class="hljs-keyword">constructor</span>(yourChoice) {
      <span class="hljs-built_in">this</span>.yourChoice = yourChoice;
      <span class="hljs-built_in">this</span>.PCchoice = <span class="hljs-built_in">this</span>.drawPcChoice();
    }

    getYourChoice = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.yourChoice;
    getPcChoice = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.PCchoice;

    drawPcChoice() {
      <span class="hljs-keyword">const</span> options = [<span class="hljs-string">"rock"</span>, <span class="hljs-string">"paper"</span>, <span class="hljs-string">"scissors"</span>];

      <span class="hljs-keyword">return</span> options[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * options.length)];
    }
  }
</code></pre>
</li>
</ul>
<h4 id="heading-finalizing-the-diagram-and-comparison-to-previous-projects-1">Finalizing the diagram and comparison to previous projects</h4>
<p>For the final diagram of the project, I wanted to:</p>
<ul>
<li><p>Emphasize the importance of the <strong>methods</strong> in the classes by mentioning them in their corresponding class, and</p>
</li>
<li><p>Indicate the apparent importance of the <code>Stats</code> instance in the workflow.</p>
</li>
</ul>
<p>Here the final diagram of this project:</p>
<pre><code class="lang-mermaid">---
title: “Rock Paper Scissors OOP” by Damian - Final SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
    subgraph gameInst[&lt;code&gt;Game instance&lt;/code&gt;]
        subgraph gameConstrt["&lt;code style="color:orange;"&gt;Game constructor&lt;/code&gt;"]
            init@{shape: hex, label: "Initial Settings"} --&gt; statInst@{shape: fr-rect, label: "&lt;code&gt;Stat instance&lt;/code&gt;"}
        end
        subgraph eventHandler["&lt;code style="color:orange;"&gt;startGame&lt;/code&gt;&lt;br/&gt;method / event handler"]
            step01[step01 - animation] --&gt; step02[step02 - calculate computer choice]
            step02 --&gt; step03[step03 - prepare display]
            step03 --&gt; step04[step04 - calculate winner and update data]
            step04 --&gt; step05[step05 - show result]
        end
        gameConstrt -.-o eventHandler
        statInst -.-o |"use calc'd winner to update &lt;code style='color:#f1ce32'&gt;status&lt;/code&gt; running &lt;code style="color:orange;"&gt;refreshStats&lt;/code&gt;"| step04
        render@{shape: fr-rect, label: "&lt;code style="color:orange;"&gt;render&lt;/code&gt;\ndisplay method"}
    end
    classGame@{shape: rounded, label: "Game class&lt;br/&gt;---------------"} -.- gameInst
    classStat@{shape: rounded, label: "Stat class&lt;br/&gt;-----------------------&lt;br/&gt;+status (obj / data)&lt;br/&gt;-----------------------&lt;br/&gt;+refreshStats()&lt;br/&gt;+getStats(result)"} -.- statInst
    classResult@{shape: rounded, label: "Result class&lt;br/&gt;--------------------------&lt;br/&gt;+&lt;u&gt;whoWin(yourCh, pcCh)&lt;/u&gt;"} -.-o |"use Result &lt;code style='color:orange'&gt;static method&lt;/code&gt; to calculate winner"| step04
    classChoice@{shape: rounded, label: "Choice class&lt;br/&gt;--------------------&lt;br/&gt;+yourCh, pcCh&lt;br/&gt;--------------------&lt;br/&gt;+getYourChoice()&lt;br/&gt;+getPcChoice()&lt;br/&gt;+drawChoice()"} -.-o |use &lt;code style="color:#87f134;"&gt;Choice instance&lt;/code&gt; to draw PC choice| step02
    statInst -.-o render
    render -.-o |"take Stat's &lt;code style='color:#f1ce32'&gt;status&lt;/code&gt; and show &lt;code style='color:#f1ce32'&gt;yourCh&lt;/code&gt; / &lt;code style='color:#f1ce32'&gt;pcCh&lt;/code&gt;&lt;br/&gt;last score"| step05
end
gameConstrt -.-o |"(1) instantiate classes, values, and functions&lt;br&gt;clean interface&lt;br&gt;add event listeners (events: &lt;code style="color:orange;"&gt;startGame&lt;/code&gt; method bound to &lt;code&gt;this&lt;/code&gt;)"|interface
eventHandler --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init
choices@{shape: rounded} --&gt; |"(2) user choice: either paper, rock or scissors"| eventHandler
eventHandler --&gt; |"(3) animations, results"| interface@{shape: curv-trap, label: "interface display"}
subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
        start3[ ] --o|"context of"| stop3[ ]
        linkStyle 20 stroke:yellow, stroke-width:5px
        style start3 height:0px;
        style stop3 height:0px;
        start4[ ] -.-|"instance of"| stop4[ ]
        linkStyle 21 stroke:skyblue, stroke-width:4px
        style start4 height:0px;
        style stop4 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      stepLegend["----step----"]
      style stepLegend fill:#474949, stroke: #CCC, color:#CCC
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef isaclass fill:grey
class classGame,classChoice,classResult,classStat isaclass
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,gameConstrt subProc
classDef step fill:#474949, stroke: #CCC, color:#CCC
class init,step01,step02,step03,step04,step05 step
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class statInst,gameInst inst
linkStyle 5,11 stroke:yellow, stroke-width: 5px
linkStyle 7,8 stroke:skyblue, stroke-width:4px
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746308090111/246b7eae-5f72-4117-9c9a-62571873e112.jpeg" alt="Final SB Diagram of the RPS game by Damian" class="image--center mx-auto" width="490" height="1474" loading="lazy"></p>
<p>What makes this code similar to the previous ones is the following:</p>
<ul>
<li><p>The order of the steps is very similar</p>
</li>
<li><p>A initial step is taken to set variables to initial stages and register an event handler function to the corresponding click events</p>
</li>
<li><p>This project is also imperative in its design</p>
</li>
</ul>
<p>This project shares more similarities to the project by Brad Traversy.</p>
<ul>
<li><p>The design of the event handler is closer to a controller pattern</p>
</li>
<li><p>Therefore, modularity and SoC seem to be concepts that guided the design.</p>
</li>
<li><p>The processing of the operations are organized according to procedural programming.</p>
</li>
</ul>
<p>That’s where the similarities stop.</p>
<ul>
<li><p>The initialization of the game is through the instantiation of a class:</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> newGame = <span class="hljs-keyword">new</span> Game();
</code></pre>
<p>  Different to all the previous projects, the event handler / controller is now a method of the instantiated class. The method is then registered as event handler of the click events right from the constructor when the class is instantiated.</p>
</li>
<li><p>Modularity occurs through calling methods of instantiated classes, instead of (globally declared) functions.</p>
</li>
<li><p>By using the OOP paradigm, this project shows a higher level of SoC by adding encapsulation.</p>
</li>
<li><p>There are special cases in this code where it was required to bind to the appropriate this context. Examples are the binding of the <code>Game</code> class methods.</p>
</li>
</ul>
<h3 id="heading-5-recurrent-neural-network-rock-paper-scissors-by-andrew-worcerster-a-project-implementing-ai">5. “Recurrent Neural Network – Rock, Paper, Scissors” by Andrew Worcerster: A Project Implementing AI</h3>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/amwmedia/embed/maowdm" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Andrew Worcester hasn’t been a regular contributor to CodePen but has created about 50 projects since 2013. The project we are going to analyze was created in 2019, one year after the first release of <code>brain.js</code>.</p>
<p>This code implements a more advanced version of the "Rock, Paper, Scissors" game, which uses neural networks (via the <code>brain.js</code> library) to predict the player’s next move and even simulate emotions for the computer opponent based on its win/loss patterns.</p>
<p>This code creates an engaging, AI-driven version of "Rock, Paper, Scissors" with advanced features like move prediction and emotional simulation using neural networks.</p>
<p>Key features of this project are:</p>
<ul>
<li><p><strong>Neural Network for prediction</strong>: a model to predict the player’s next move based on their move history creates an adaptive gameplay experience, where the CPU adjusts its strategy.</p>
</li>
<li><p><strong>Emotion simulation</strong>: another model simulating emotions based on the game results (win/loss history), and it displays appropriate emojis like <code>😫</code>, <code>😊</code>, and so on, next to its moves.</p>
</li>
<li><p><strong>Interactive UI</strong>: The game uses DOM manipulation to display the player’s move, the CPU’s move, the result, and the CPU’s emotional state after each round.</p>
</li>
<li><p><strong>Dynamic scoring</strong>: Both player and CPU scores are updated and displayed after each round.</p>
</li>
</ul>
<h3 id="heading-analysis-of-the-project-4">Analysis of the Project</h3>
<h4 id="heading-quickly-discovering-of-the-start-and-end-of-the-workflow-3">Quickly discovering of the start and end of the workflow</h4>
<p>At a high level of generalization, this code follows the same pattern as the other projects, although the complexity of the functionalities has grown:</p>
<ul>
<li><p>Again, variables and states are initialized once the project is accessed.</p>
</li>
<li><p>Apart from that, an event handler of the click event is assigned carrying an anonymous function as a callback function. The <strong>contoller pattern</strong> seems to reappear in this project too.</p>
</li>
</ul>
<pre><code class="lang-mermaid">---
title: “Recurrent Neural Network – Rock, Paper, Scissors” by A. Worcerster - Simple SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
subgraph clickEventListener["Click Event (&lt;code&gt;forEach&lt;/code&gt; on &lt;code style="color:#f1ce32"&gt;options&lt;/code&gt;)"]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"}
end
end
init --&gt; |"(1) initialize values (dummies for &lt;code style="color:#f1ce32"&gt;cpuNextMove data&lt;/code&gt;) and functions (functions: brain.recurrent.LSTM &lt;code style="color:orange"&gt;net&lt;/code&gt; brain.NeuralNetwork &lt;code style="color:orange"&gt;emoNet&lt;/code&gt;, &lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;)&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers: &lt;code style="color:orange"&gt;anoymous function&lt;/code&gt;)"|interface
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface
end
style start fill:black
style stop fill:black, fill-stroke:white
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746282747010/f1c43834-0558-4d1c-8e71-f09f7f92f2c4.jpeg" alt="RPSBrain 01 - Simple SB-Diagram of the RPS game by A. Worcester" class="image--center mx-auto" width="764" height="939" loading="lazy"></p>
<p>A key difference from previous projects is the <strong>training of the neural network operations</strong>. Some of those functionalities are initialized to a initial state even before the user clicks.</p>
<h4 id="heading-refinement-4">Refinement</h4>
<p>If we still keep a high level of generalization, we can see that several of the responsibilities of the workflow will be taken by functions and even operations outside the event handler.</p>
<p>The project has several <code>brain.js</code> functionalities in place. The most evident ones are:</p>
<ul>
<li><p>The LSTM (Long Short Term Memory), which it is a neural network designed to capture associations and patterns that are separated in time or place - and it is the one associated with the prediction of the user’s next move.</p>
</li>
<li><p>A default feed-forward neural network of just one layer, designed to compare immediate patterns, and it is the one associated with the simulation of the emotions.</p>
</li>
</ul>
<p>The LSTM is used by another function, <code>calcNextMove</code>, to provide an immediate result even before the user interacts with the click event: a value for the <code>cpuNextMove</code> variable.</p>
<p><code>cpuNextMove</code> is indeed the <strong>calculation of the computer’s choice</strong> and it occurs <em>before</em> the user clicks, starting with a default value based on fake data.</p>
<pre><code class="lang-mermaid">---
title: “Recurrent Neural Network – Rock, Paper, Scissors” by A. Worcerster - SB-Diagram Refinement 01
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
constvar@{shape: lean-r, label: "&lt;span style="color:#f1ce32"&gt;constants and variables&lt;/span&gt;"} -.-o clickEventListener
LSTM@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;net&lt;/code&gt;&lt;br/&gt;LSTM"} -.-o calcNextMove
calcNextMove@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;&lt;br/&gt;computer choice"} --&gt; cpuNextMove@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuNextMove&lt;/code&gt;"}
NN@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;emoNet&lt;/code&gt;&lt;br/&gt;NN"} -.-o clickEventListener
cpuNextMove -.-o clickEventListener
subgraph clickEventListener["Click Event&lt;br/&gt;(&lt;code style="font-size:13px"&gt;forEach&lt;/code&gt; on &lt;code style="color:#f1ce32"&gt;options&lt;/code&gt;)"]
    eventHandler@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"}
end
end
init --&gt; |"(1) initialize values (dummies for &lt;code style="color:#f1ce32"&gt;cpuNextMove data&lt;/code&gt;) and functions (functions: brain.recurrent.LSTM &lt;code style="color:orange"&gt;net&lt;/code&gt; brain.NeuralNetwork &lt;code style="color:orange"&gt;emoNet&lt;/code&gt;, &lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;)&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers: &lt;code style="color:orange"&gt;anoymous function&lt;/code&gt;)"|interface
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class NN,LSTM inst
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746282227818/020fd3c7-3864-4e5c-8af1-de185a04484f.jpeg" alt="First Refinement of SB Diagram of the RPS game by A. Worcerster" class="image--center mx-auto" width="828" height="1135" loading="lazy"></p>
<h4 id="heading-further-refinement">Further Refinement</h4>
<p>This project has some complexities not seen in previous projects, so I will try to go through it slowly. Let’s first see another level of refinement where the steps are shown:</p>
<pre><code class="lang-mermaid">---
title: “Recurrent Neural Network – Rock, Paper, Scissors” by A. Worcerster - SB-Diagram Refinement 02
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
constvar@{shape: lean-r, label: "&lt;span style="color:#f1ce32"&gt;constants and variables&lt;/span&gt;"} -.-o clickEventListener
step05 --&gt; data@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;data&lt;/code&gt;"}
data -.-o calcNextMove
subgraph step00["stepInit - calculate computer choice"]
    calcNextMove@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;&lt;br/&gt;computer choice"} --&gt; cpuNextMove@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuNextMove&lt;/code&gt;"}
    LSTM@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;net&lt;/code&gt;&lt;br/&gt;LSTM instance"} -.-o calcNextMove
    cpuNextMove -.-o Dout((A))
    cpuNextMove -.-o Eout((B))
end
NN@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;emoNet&lt;/code&gt;&lt;br/&gt;NN"} -.-o step03
subgraph clickEventListener["Click Event&lt;br/&gt;(&lt;code style="font-size:13px"&gt;forEach&lt;/code&gt; on &lt;code style="color:#f1ce32"&gt;options&lt;/code&gt;)"]
    subgraph eventHandler["&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"]
        step01["step01 - prepare a scoring table for that option"] --&gt; step02["step02 - calculate winner"]
        step02 --&gt; step03["step03 - calculate cpu emotion"]
        step03 --&gt; step04["step04 - result handling and presentation: Winner"]
        step04 --&gt; step05["step05 - update data"]
        step05 --&gt; step06["step06 - recalculate winner and prepare display"]
        step06 --&gt; step07["step07 - calc next move; result handling and presentation: Scores"]
        Din((A)) -.-o step02
        Ein((B)) -.-o step06    
    end
end
end
init --&gt; |"(1) initialize values (dummies for &lt;code style="color:#f1ce32"&gt;cpuNextMove data&lt;/code&gt;) and functions (functions: brain.recurrent.LSTM &lt;code style="color:orange"&gt;net&lt;/code&gt; brain.NeuralNetwork &lt;code style="color:orange"&gt;emoNet&lt;/code&gt;, &lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;)&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers: &lt;code style="color:orange"&gt;anoymous function&lt;/code&gt;)"|interface
clickEventListener --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,gameConstrt subProc
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class NN,LSTM inst
classDef step fill:#474949, stroke: #CCC, color:#CCC
class step00,step01,step02,step03,step04,step05,step06,step07 step
classDef connectorcpuNextMove fill:skyblue, color:black
class Dout,Din,Eout,Ein connectorcpuNextMove
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746280491504/2cbb972c-535d-4a56-b5d7-23fb4f3eba63.jpeg" alt="Second Refinement of SB Diagram of the RPS game by A. Worcerster" class="image--center mx-auto" width="831" height="1655" loading="lazy"></p>
<p>We can see from the diagram that:</p>
<ol>
<li><p>The <code>cpuNextMove</code> is pre-calculated, and so the calculation of the computer’s choice occurs <em>before</em> the user’s next click. I have referred to this step as “stepInit” to indicate that the first calculation occurs at initialization.</p>
</li>
<li><p>After the choice of the user is captured, its value and the value of <code>cpuNextMove</code> are eventually used to calculate the winner. The result is stored to keep the history of computer scoring.</p>
</li>
<li><p>The history of computer scoring is the input used for the calculation of the emotions using the <code>emoNet</code>.</p>
</li>
<li><p>The user’s choice is then used to create the next entry for data, which keeps the history of user scoring within the <code>data</code> in a dedicated format.</p>
</li>
<li><p>After calculating the winner and displaying the results, the project will use data to calculate the cpuNextMove <em>before</em> the user clicks again.</p>
</li>
</ol>
<h4 id="heading-finalizing-the-diagram-and-comparison-to-previous-projects-2">Finalizing the diagram and comparison to previous projects</h4>
<p>We could have finished with the previous diagram as it is largerly refined, but I wanted to practice another level of refinement to reveal the role of that the <em>data flow</em> has in this project. This resulted in a more complex diagram that those previously shown:</p>
<pre><code class="lang-mermaid">---
title: “Recurrent Neural Network – Rock, Paper, Scissors” by A. Worcerster - Final SB-Diagram
config:
    theme: dark
    layout: "elk"
    flowchart:
        nodeSpacing: 50
        rankSpacing: 50
---
flowchart TD
subgraph _
subgraph main
init
constvar@{shape: lean-r, label: "&lt;span style="color:#f1ce32"&gt;constants and variables&lt;/span"} -.-o clickEventListener
step05 --&gt; data@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;data&lt;/code&gt;"}
cpuWinLoss@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuWinLoss&lt;/code&gt;"} -.-o Aout((A))
cpuWinLoss@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuWinLoss&lt;/code&gt;"} -.-o Bout((B))
cpuWinLoss@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuWinLoss&lt;/code&gt;"} -.-o Cout((C))
subgraph step00["stepInit - calculate computer choice"]
    calcNextMove@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;&lt;br/&gt;computer choice"} --&gt; cpuNextMove@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;cpuNextMove&lt;/code&gt;"}
    LSTM@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;net&lt;/code&gt;&lt;br/&gt;LSTM instance"} -.-o calcNextMove
    cpuNextMove -.-o Dout((A))
    cpuNextMove -.-o Eout((B))
end
data -.-o calcNextMove
delay01 --&gt; calcNextMove  
NN@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;emoNet&lt;/code&gt;&lt;br/&gt;NN instance"} -.-o step03
subgraph clickEventListener["Click Event&lt;br/&gt;(&lt;code style="font-size:13px"&gt;forEach&lt;/code&gt; on &lt;code style="color:#f1ce32"&gt;options&lt;/code&gt;)"]
    subgraph eventHandler["&lt;code style="color:orange"&gt;anonymous func&lt;/code&gt;&lt;br/&gt;event handler"]
        scoreValues@{shape: lean-r, label: "&lt;code style="color:#f1ce32"&gt;scoreValues&lt;/code&gt;"}
        step01["step01 - prepare a scoring table for this specific option"] --&gt; step02["step02 - calculate winner and update of cpu history"]
        step01 -.-o scoreValues
        subgraph step03["step03 - calculate cpu emotion"]
           likely@{shape: fr-rect, label: "&lt;code style="color:orange"&gt;brain.likely&lt;/code&gt;&lt;br/&gt;estimator func"} ~~~ nonode01[ ]
           style nonode01 height:0px;
        end

        Din((A)) -.-o step02
        scoreValues -.-o step02
        step02 --&gt; step03
        step03 --&gt; step04["step04 - result handling and presentation: Winner"]
        scoreValues -.-o step04
        step04 --&gt; step05["step05 - update data"]
        step05 --&gt; step06["step06 - recalculate of winner and prepare display"]
        subgraph step07["step07 - calc next move"]
             delay01@{shape: delay, label: outer setTimeout}
            subgraph step08["step08 - result handling and presentation: Scores"]
                delay02@{shape: delay, label: inner setTimeout}
            end
        end

        Cin((C)) -.-o delay02
        step06 --&gt; delay01
        delay02 -.-o delay01
        Ain((A)) -.-o step02
        Bin((B)) -.-o likely
        Ein((B)) -.-o step04

    end
end
end
init --&gt; |"(1) initialize values (dummies for &lt;code style="color:#f1ce32"&gt;cpuNextMove data&lt;/code&gt;) and functions (functions: brain.recurrent.LSTM &lt;code style="color:orange"&gt;net&lt;/code&gt; brain.NeuralNetwork &lt;code style="color:orange"&gt;emoNet&lt;/code&gt;, &lt;code style="color:orange"&gt;calcNextMove&lt;/code&gt;)&lt;br&gt;clean interface&lt;br&gt;add event listeners (event handlers: &lt;code style="color:orange"&gt;anoymous function&lt;/code&gt;)"|interface
eventHandler --&gt; stop@{shape: framed-circle}
start@{shape: start} --&gt; init@{shape: hex, label: "Initial Settings"}
choices --&gt; |"(2) user choice: either paper, rock or scissors"| clickEventListener
clickEventListener --&gt; |"(3) animations, results"| interface

subgraph legend
      direction LR
      subgraph flowlines
        start1[ ] --&gt;|"next step"| stop1[ ]
        style start1 height:0px;
        style stop1 height:0px;
        start2[ ] -.-o|"assignation"| stop2[ ]
        style start2 height:0px;
        style stop2 height:0px;
      end
      subgraph shapes
      variable["variable"]
      style variable width:135px, fill:none, stroke:none, color:#f1ce32
      subprocess[&lt;code style="color:orange;"&gt;subprocess&lt;/code&gt;]
      instance[&lt;code style="color:#87f134;"&gt;-instance-&lt;/code&gt;]
      style instance stroke:violet, stroke-width: 3px;
      end
end
end
interface ~~~ legend

style start fill:black
style stop fill:black, fill-stroke:white
classDef subProc fill:#1f2020, stroke: #CCC, color:#CCC
class eventHandler,gameConstrt subProc
classDef step fill:#474949, stroke: #CCC, color:#CCC
class step00,step01,step02,step03,step04,step05,step06,step07,step08 step
classDef inst fill:#1f2020, color:#87f134, stroke:violet, stroke-width: 3px
class LSTM,NN inst
classDef connectorcpuWinLoss fill:white, color:black
class Aout,Ain,Bout,Bin,Cout,Cin connectorcpuWinLoss
classDef connectorcpuNextMove fill:skyblue, color:black
class Dout,Din,Eout,Ein connectorcpuNextMove
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1746277838797/066c8372-c20e-4917-acf5-b8a70a743e96.jpeg" alt="Final SB Diagram of the RPS game by A. Worcerster" class="image--center mx-auto" width="747" height="1707" loading="lazy"></p>
<p>I think the use of the data in this project deserved additional explanation. In fact, it is not only the use of machine learning procedures that makes this project more complex – but also its associated use of more advanced data structures.</p>
<p>Here’s a selection of some possible values for some of the variables used to collect data at different points of the workflow:</p>
<pre><code class="lang-javascript">data structures:

<span class="hljs-string">"cpuNextMove: "</span> <span class="hljs-string">"👊"</span>

<span class="hljs-string">"cpuEmotions: "</span> <span class="hljs-comment">// [object Array] (4)</span>
[<span class="hljs-string">"😟"</span>,<span class="hljs-string">"😨"</span>,<span class="hljs-string">"😕"</span>,<span class="hljs-string">"🤨"</span>]

<span class="hljs-string">"data: "</span> <span class="hljs-comment">// [object Array] (3)</span>
[<span class="hljs-comment">// [object Array] (4)</span>
[<span class="hljs-string">"✌️"</span>,<span class="hljs-string">"👊"</span>,<span class="hljs-string">"✋"</span>,<span class="hljs-string">"✌️"</span>],<span class="hljs-comment">// [object Array] (4)</span>
[<span class="hljs-string">"👊"</span>,<span class="hljs-string">"✋"</span>,<span class="hljs-string">"✌️"</span>,<span class="hljs-string">"✌️"</span>],<span class="hljs-comment">// [object Array] (4)</span>
[<span class="hljs-string">"✋"</span>,<span class="hljs-string">"✌️"</span>,<span class="hljs-string">"✌️"</span>,<span class="hljs-string">"✋"</span>]]

<span class="hljs-string">"scoreValues: "</span> <span class="hljs-comment">// [object Object] </span>
{
  <span class="hljs-string">"✋"</span>: <span class="hljs-number">0.3</span>,
  <span class="hljs-string">"✌️"</span>: <span class="hljs-number">1</span>,
  <span class="hljs-string">"👊"</span>: <span class="hljs-number">0</span>
}

<span class="hljs-string">"cpuWinLoss: "</span> <span class="hljs-comment">// [object Array] (5)</span>
[<span class="hljs-number">0.3</span>,<span class="hljs-number">0.3</span>,<span class="hljs-number">0.3</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>]
</code></pre>
<p>The way <code>data</code> is made (an array of arrays) is a requirement for the LSTM algorithm in this particular case.</p>
<p>Also interesting is the use of the <code>scoreValues</code> object.</p>
<pre><code class="lang-javascript">        <span class="hljs-keyword">const</span> scoreValues = {
            [options[myMoveIdx]]: <span class="hljs-number">0.3</span>,         <span class="hljs-comment">// tie</span>
            [options[(myMoveIdx + <span class="hljs-number">1</span>) % <span class="hljs-number">3</span>]]: <span class="hljs-number">1</span>, <span class="hljs-comment">// cpu wins</span>
            [options[(myMoveIdx + <span class="hljs-number">2</span>) % <span class="hljs-number">3</span>]]: <span class="hljs-number">0</span>  <span class="hljs-comment">// cpu loses</span>
        };
</code></pre>
<p>Notice how the user’s choice (<code>myMoveIdx</code>) is used to compute the different possible <em>computer’s choices</em> as key, with the values associated to each key being the potential result <em>for the computer</em> given that user’s choice. The values have the form of a “score”:</p>
<ul>
<li><p>0 if the computer lost the match</p>
</li>
<li><p>0.3 if there was a tie</p>
</li>
<li><p>1 if the computer won the match</p>
</li>
</ul>
<p>With this object, finding if the computer won, lost or drew consists in finding the value, or score, which key is equals to <code>cpuNextMove</code>. In other words, <code>scoreValues</code> is a template used to calculate the winner.</p>
<p>The computer’s score will be then saved in an array, <code>cpuWindLoss</code>:</p>
<pre><code class="lang-javascript">cpuWinLoss.push(scoreValues[cpuNextMove]);
</code></pre>
<p>Values of the <code>cpuWinLoss</code> array will be eventually used to calculate the emotions. <code>cpuEmotions</code> is an array of emotion predictions based on the last 4 CPU scores. The predictions are obtained from a “table of emotions” that was arbitrarily suggested by the author (the <code>emo</code> object).</p>
<p>Aspects of this project that we can relate to previous ones are:</p>
<ul>
<li><p>It is made using imperative programming.</p>
</li>
<li><p>The existence of a event handler with poor modularity makes it more comparable to the way the event handler was designed in the less advanced projects, where the event handler took most of the responsibilities of the operations and the variables and utilities were declared at the global scope.</p>
</li>
<li><p>At a high level of generalization, the essential steps of the game design stay the same:</p>
<ul>
<li><p>a function (<code>calcNextMove</code>) calculates the computer’s choice.</p>
</li>
<li><p>another functionality (the operations around the emotion calculation) takes part in the realization of the “animation” associated with the corresponding display of the results.</p>
</li>
<li><p>An operation to calculate the winner is also present.</p>
</li>
<li><p>This project has also data handling logic, although much more advanced than previous projects</p>
</li>
</ul>
</li>
</ul>
<p>But how some of those steps are realized is very different in this project:</p>
<ul>
<li><p>The computer’s choice is based on the user’s scoring history, not a random function.</p>
</li>
<li><p>The computer’s choice calculation occurs <em>before</em> the user clicks. While the calculation could have been done before user interaction in previous projects without affecting their outcomes (assuming the user wouldn’t have access to the value of the computer’s choice before playing), performing it at click time here might have caused performance issues due to its higher CPU demand compared to the simpler <code>Math.random</code>. Thus, performance likely influenced the design choices.</p>
</li>
<li><p>The calculation of the winner is based not on a typical conditional control flow (<code>if-else</code>) or even a ternary operator, but rather obtained from a search across a customized data structure.</p>
</li>
<li><p>Instead of using logic that generates feedback independently of previous results, this game uses a more advanced process that factors in both the computer’s move and recent game history to generate contextual UI feedback after each turn.</p>
</li>
<li><p>The different implementations for the operations carried out by this project required different types of data structures with different levels of complexity, so data handling was more complex.</p>
</li>
</ul>
<p>If you were able to follow the analysis specifically for this project and want to compare it to a similar project implementing the same game, check the <a target="_blank" href="https://rockpaperscissors-ai.vercel.app/">example provided by brain.js team</a>. You might need to have a basic knowledge of Vue.js though.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>As a developer, you will be exposed to many different lines of creative code yourself. Or how Robert C. Martin pointed it out in his book “Clean Code”:</p>
<blockquote>
<p>“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code.”</p>
</blockquote>
<p>So, learning to understand other people’s code is an essential skill that every programmer should develop. And this learning only happens by studying other people’s code and trying to reveal their tricks and bugs.</p>
<p>That is why finding good ways to reveal patterns when comparing code is so important. And that has been the main purpose of this project.</p>
<p>When I started, I still wasn’t sure about what to expect from the approach. Let me share with you what I learned.</p>
<p>What I found limiting from this approach was:</p>
<ul>
<li><p>The more complex the code, the more complex the diagram gets, making it difficult to read. And the more difficult the diagram, the more difficult is to work out a diagram with Mermaid.js. You will also have to make more definitions, add more color, use more tricks, and so on in order to seek clarity. And the more “solutions” you have to find to clarify your diagram, the higher the risk of making it less clear.</p>
</li>
<li><p>It takes time and practice. This kind of technique is not something that you learn all at once. You might find yourself making a lot of changes before getting the “right” result. If you are doing this with Mermaid.js or any other scripting tool, you will have to learn to script with them, too.</p>
</li>
<li><p>This approach is not about visualizing algorithms or syntax. I suspect that if you read the analyses of this article with no knowledge about machine learning or object-oriented programming, this analysis likely didn’t teach you how to do machine learning or OOP. To understand those projects you have to already have internalized the “patterns” on how to do either OOP or machine learning, or be in the right moment of your learning curve, in order to be able to extract something from the code.</p>
</li>
</ul>
<p>What I found beneficial from this approach:</p>
<ul>
<li><p>Something that I learned the hard way was that <em>good</em> programming is not only about algorithms and syntax: it is also about structure and organization. And this approach will give you a lot of information about that.</p>
</li>
<li><p>It helps you break the code apart into functional operations. You adopt a “divide and conquer” approach to studying code.</p>
</li>
<li><p>Even if you are not visualizing the algorithms, you learn algorithms. Why? Because the approach forces you to understand the code. In order to find those functional operations, you will find yourself forced to study what some sections of the code are doing. So you will have to study more code.</p>
</li>
<li><p>You learn by comparison. That is an interesting by-product: once you have found different implementations for a similar functional operation, you learn by their differences. The diagrams will then guide you to the sections of the code that are solving <em>that</em> specific problem you are interested in and you’ll be able to compare it within the context of a larger codebase.</p>
</li>
<li><p>The diagrams acts as mnemotechnical artifacts to remember pieces of code. You can use those diagrams to recall a piece of code that was interesting to you, and then you’ll be able to find it more easily than by having to go through the whole code again.</p>
</li>
</ul>
<p>What I found more interesting about this approach is the numerous questions that came to my mind during and after doing the analyses:</p>
<ul>
<li><p><em>Why did the author follow this approach?</em></p>
</li>
<li><p><em>What drove their decisions?</em></p>
</li>
<li><p><em>How could I better organize it if I worked on it?</em></p>
</li>
<li><p><em>Which techniques would I like to combine?</em></p>
</li>
<li><p><em>What should I avoid for this project?</em></p>
</li>
</ul>
<p>And so on.</p>
<p>Another effect was the feeling that I could now easily recognize the same “template” in other projects without having to make the diagrams. It starts to be more natural.</p>
<p>If you feel you want to implement this approach next time you come across several codebases you want to compare, I recommend you do the following:</p>
<ul>
<li><p><strong>Don’t stick only to visuals</strong>. Combine this with other tools. This is just one part of the whole process. For example, use AI to get a textual description of the code and use the diagrams to visualize the flow.</p>
</li>
<li><p><strong>Always go to the code as it is the “source of truth”.</strong> You (or AI, if you’re using it) might have gotten it wrong at certain points, so always check.</p>
</li>
<li><p><strong>Better to compare code examples that are at your level or just a bit higher, and be prepared to challenge yourself by studying new concepts</strong>. For example, if you have just the fundamentals of OOP clear in your head but you haven’t started to work on it, find simple examples at your current level and a few more made in OOP that solve similar problems and compare the approaches. I ensure you that you will start finding the patterns.</p>
</li>
<li><p><strong>Come up with questions</strong>. The analysis might reveal structures and workflows and help you get into new programming techniques, but it won’t tell you if those structures or techniques were the “right” solution. You have to investigate more from that point. Then you can compare theory with practice. And then you will come up with more questions!</p>
</li>
<li><p>Select projects that are not subject to change.</p>
</li>
<li><p><strong>Don’t worry about how old the projects are</strong>. Syntax is not what you are looking to learn from this analysis. It is code structure, organization, and logic. The “map in the mind of the developer”.</p>
</li>
<li><p><strong>Keep it real</strong>. If your goal is to learn to code and your time is limited, bear in mind that this kind of analyses will take extra time. It won’t result in concrete code either. It might be good planning for analyzing new codebases at a high level of generalization. But even if it’s too general, I assure you that the time you devote to it will be worthy.</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Mermaid JavaScript Library to Create Flowcharts ]]>
                </title>
                <description>
                    <![CDATA[ If you’ve recently searched for an online diagramming tool, you might have noticed that most of them rely on drag-and-drop functionality. While this is helpful for people who can’t code, it can be hard to maintain. It can also be a bit difficult to m... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/use-mermaid-javascript-library-to-create-flowcharts/</link>
                <guid isPermaLink="false">678520dfd55476f9efb1de92</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ flowcharts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ evaristo.c ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jan 2025 14:19:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736777930250/cbc8af84-7109-45c9-9ee1-3d10c6b1b475.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you’ve recently searched for an online diagramming tool, you might have noticed that most of them rely on drag-and-drop functionality. While this is helpful for people who can’t code, it can be hard to maintain. It can also be a bit difficult to manipulate, having to move all those shapes into an editor, and it’s not as intuitive when trying to arrange lines and boxes so they don’t overlap.</p>
<p>Luckily, there are solutions that have taken a different path. They are based on libraries that can organize the shapes and lines for you. What you have to do instead is provide a script designed specifically for that tool outlining what kind of shapes you want to see and their relationships.</p>
<p>In this article, we’ll talk about a popular script-based diagramming tool called Mermaid. You’ll learn how Mermaid works and how you can use it to create flowcharts. We’ll also cover how to style your flowcharts in Mermaid. By the end, you should be able to use this helpful tool to create your own flowcharts.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-mermaid">What is Mermaid?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-started-with-mermaid">Getting Started with Mermaid</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-start-your-flowchart-in-mermaid">How to Start Your Flowchart in Mermaid</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-nodes-and-shapes-in-mermaid">Nodes and Shapes in Mermaid</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-styling-with-mermaid">How to Add Styling with Mermaid</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-mermaid">What is Mermaid?</h2>
<p><a target="_blank" href="https://mermaid.js.org/"><strong>Mermaid</strong></a> is a JavaScript library that <em>translates written declarations of entities and relationships into diagrams</em>. It’s like coding a diagram. The instructions are also Markdown-compliant.</p>
<p>Mermaid is not the only tool of this kind. There are other ones, like <a target="_blank" href="https://plantuml.com/">PlantUML</a>, that have been around longer. But scripting with Mermaid has a very gentle learning curve, and it distinguishes itself from similar tools in many ways:</p>
<ul>
<li><p>As opposed to other tools like PlantUML, Mermaid is <em>made for the web</em>. It is Node-compatible, and the diagrams show as modified SVGs with inserted “<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject">foreign objects</a>”. These are more compliant with HTML and CSS frameworks.</p>
</li>
<li><p>Also compared to other scripting libraries, the resulting charts are more visually appealing, as they use advanced algorithms to place the shapes and arrows.</p>
</li>
<li><p>Mermaid also makes strong use of Markdown for labelling, and has more recently started using JavaScript object-like formatting for shape declaration.</p>
</li>
<li><p>It also has a strong support, is actively maintained, and makes use of well-known, robust JS graphics libraries like <a target="_blank" href="https://d3js.org/">d3.js</a>, <a target="_blank" href="https://cytoscape.org/what_is_cytoscape.html">cytospace.js</a>, and <a target="_blank" href="https://github.com/dagrejs/dagre-d3">dagre-d3</a>.</p>
</li>
</ul>
<p>When compared to the most common drag-and-drop types of diagramming tools, Mermaid has the same advantages as other script-based diagramming tools. With a script, we can talk about <strong>version control, reusability, and many other terms</strong> associated with programming and automation that might not be possible with drag-and-drop tools.</p>
<h3 id="heading-challenges-with-mermaid">Challenges with Mermaid</h3>
<p>Of course, it is not a perfect tool. One of the main challenges with Mermaid – and with many script-based diagramming tools – is that it’s a WYSIWYG tool: Mermaid’s results are almost impossible to predict, and after that they are hard to customize.</p>
<p>Also, for each diagram you can make with Mermaid, there are prescribed shapes and arrows – the introduction of new shapes or relationships are limited.</p>
<p>Some other limitations are:</p>
<ul>
<li><p>As with other script-based tools, the script is not easy to debug, and for large diagrams the script can get very messy.</p>
</li>
<li><p>Even if the syntax is usually very intuitive, you have to learn a different syntax for each type of diagram.</p>
</li>
<li><p>Specifically for Mermaid, if you want to post-process the resulting diagram, you must find appropriate tools that can read the modified Mermaid SVGs.</p>
</li>
</ul>
<p>But if you use Mermaid for the cases where it performs well, you will have an excellent tool at your service.</p>
<p>Mermaid allows you to create about 21 types of diagrams, each with its own syntactic rules. In this tutorial, we’ll take a closer look at the flowchart syntax, which I’ve been working with recently. This guide is for those comfortable with scripting, looking to build flowcharts, and seeking a quick reference to Mermaid syntax before diving deeper into the full documentation.</p>
<p>To keep this content focused on Mermaid syntax, I will avoid going into details about using JavaScript in combination with Mermaid and will instead refer to the relevant Mermaid documentation where applicable.</p>
<p>I’ll also highlight a few minor issues I’ve noticed while using the latest version of the tool (version 11) to help you avoid potential pitfalls.</p>
<p>Finally, if you need more guidance on creating flowcharts in general, <a target="_blank" href="https://www.freecodecamp.org/news/how-to-make-flowcharts-with-mermaid">I’ve created a separate post</a> that walks you through the process step-by-step. While the examples in that post use Mermaid, its use is entirely optional.</p>
<h2 id="heading-getting-started-with-mermaid">Getting Started with Mermaid</h2>
<p>You can use Mermaid in several different ways.</p>
<p><strong>For those comfortable with web technologies</strong>, you can install Mermaid as a package or plugin and integrate it into applications using the Mermaid API, CLI, or plugins.</p>
<p>Once installed, you can render Mermaid diagrams wherever Mermaid syntax is included in your HTML or markdown files. The official documentation provides an example of rendering diagrams using a CDN (ESM style):</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    Here is one mermaid diagram:
    <span class="hljs-tag">&lt;<span class="hljs-name">pre</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mermaid"</span>&gt;</span>
            graph TD
            A[Client] --&gt; B[Load Balancer]
            B --&gt; C[Server1]
            B --&gt; D[Server2]
    <span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>

    And here is another:
    <span class="hljs-tag">&lt;<span class="hljs-name">pre</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mermaid"</span>&gt;</span>
            graph TD
            A[Client] --&gt;|tcp_123| B
            B(Load Balancer)
            B --&gt;|tcp_456| C[Server1]
            B --&gt;|tcp_456| D[Server2]
    <span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">import</span> mermaid <span class="hljs-keyword">from</span> <span class="hljs-string">'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'</span>;
      mermaid.initialize({ <span class="hljs-attr">startOnLoad</span>: <span class="hljs-literal">true</span> });
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>If you're using GitHub, Mermaid is supported in GitHub markdown. Additionally, <a target="_blank" href="https://www.freecodecamp.org/news/diagrams-as-code-with-mermaid-github-and-vs-code/">Zaira Hira has written a helpful guide</a> for Visual Studio Code users. Check your IDE for available plugins and extensions.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Important Note on CSS Collisions: </strong>When installing Mermaid in your project, watch for CSS naming conflicts. Mermaid (version 11) uses fixed classes and IDs to render SVGs, which may overlap with your project’s styles, causing hard-to-detect errors.</div>
</div>

<p>If you’re not interested in integrating Mermaid directly into your coding, online editors and cloud tools are a great option. Mermaid provides two key tools: <strong>Mermaid Chart</strong> and <strong>Mermaid Live</strong>.</p>
<ul>
<li><p><a target="_blank" href="https://www.mermaidchart.com/">Mermaid Chart</a> is a cloud-based project manager designed for collaboration and sharing. It offers features like templates, version history, and presentation capabilities, making it ideal for project management.</p>
</li>
<li><p><a target="_blank" href="https://mermaid.live/">Mermaid Live</a> is best for quick, one-off diagrams. You can see a view of Mermaid Live on my computer in the image below. You can select a diagram from sample options, modify its code in the editor under the <strong>“&lt;/&gt; Code”</strong> tab, or paste your own script. Changes instantly appear in the Diagram window, and diagrams can be exported as PNG or SVG from the <strong>Actions</strong> menu.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733822730335/3b353b4c-19d4-44f0-b779-bbc89c68c4a6.png" alt="Screen shot of Mermaid Live Editor" class="image--center mx-auto" width="1917" height="877" loading="lazy"></p>
<p>While Live is convenient, it’s not a reliable way to track your scripts, so save your work externally. There are other online editors similar to Mermaid Live, and <a target="_blank" href="https://www.freecodecamp.org/news/diagrams-as-code-with-mermaid-github-and-vs-code/">Zaira Hira’s article</a> provides insights into one of them.</p>
<p>For the following explanations, any installation you choose will work just the same, as we are going to put emphasis on the code. So choose your tools and let’s check out some Mermaid flowchart syntax.</p>
<h2 id="heading-how-to-start-your-flowchart-in-mermaid">How to Start Your Flowchart in Mermaid</h2>
<p>In order to create your first Mermaid diagram, you have to tell Mermaid what type of diagram you want to make. We are making a flowchart, so to start one you can just write this:</p>
<pre><code class="lang-mermaid">flowchart
</code></pre>
<p>Mermaid can distribute the shapes in two directions: top-down (default) or left-right. If you want to be specific about the layout direction, you have to write TD for top-down:</p>
<pre><code class="lang-mermaid">flowchart TD
</code></pre>
<p>and LR for left-right:</p>
<pre><code class="lang-mermaid">flowchart LR
</code></pre>
<p>Just keep in mind that you can select only one direction for your flowchart (either TD or LR).</p>
<h3 id="heading-how-to-write-a-comment">How to Write a Comment</h3>
<p>Now, before we start using shapes, let’s see how to write a comment in a Mermaid flowchart. A comment will not render on the chart – they’re just there to help you out. You likely know how useful they are as a developer.</p>
<p>To write a comment, just precede the text of the comment with “<code>%%</code>” :</p>
<pre><code class="lang-mermaid">flowchart
%% This is a comment!!!
</code></pre>
<h3 id="heading-how-to-configure-your-flowchart">How to Configure your Flowchart</h3>
<p>There are (or were) at least three ways to configure your flowcharts in Mermaid. The first one, using directives, is deprecated but still works for some cases. The second one is a frontmatter config. The other one is through a configuration file.</p>
<p>If you were using old versions of Mermaid (&lt;10.5.0) you could’ve configured your chart using <a target="_blank" href="https://mermaid.js.org/config/directives.html">directives</a>. You do that by declaring a JavaScript-object-like statement enclosed between percentages (“<code>%%…%%</code>”) symbols, usually after declaring the diagram type, like so:</p>
<pre><code class="lang-mermaid">%%{init: { 'flowchart': {theme:"base", themeVariables:{primarycolor:"#00ff00"} } }%% 
flowchart
    Hello --&gt; World
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">By the time of this writing, the Mermaid documentation sometimes still refers to directives as a way to configure your diagram. But keep in mind that the use of directives doesn’t work correctly in some renderers.</div>
</div>

<p>The frontmatter configuration method has replaced the directive method since version 10.5.0. It’s based on the YAML format. In that case, you have to use a YAML block before initializing your flowchart:</p>
<pre><code class="lang-mermaid">---
title: Hello Title
config:
  theme: base
  themeVariables:
    primaryColor: "#00ff00"
---
flowchart
    Hello --&gt; World
</code></pre>
<p>Directives and frontMatters are limited in scope compared to other configuration methods. They apply only to the graph below the configuration statement.</p>
<p>For developers who are installing the Mermaid package, the recommended method for configuration is using JavaScript. Mermaid is also configurable through a JSON configuration file that exists in the folder of the library. For more details about those methods, consult the <a target="_blank" href="https://mermaid.js.org/config/usage.html#configuration">documentation chapter about API usage</a>.</p>
<p>You can find a list of the attributes and properties that you can affect when configuring your diagram on <a target="_blank" href="https://mermaid.js.org/config/schema-docs/config.html">this page of the Mermaid documentation</a>.</p>
<p>I won’t go into much detail about configuration in this article, although I might refer to it a couple of times just to clarify a couple of things that can only be done by configuring the tool.</p>
<h2 id="heading-nodes-and-shapes-in-mermaid">Nodes and Shapes in Mermaid</h2>
<p>Across the Mermaid documentation, <strong>nodes</strong> are used as a generic term to refer to any step that is added to the flowchart. Mermaid documentation then introduces the <strong>shapes</strong>, also called <strong>node shapes</strong>. They are the representations of what happens in that node.</p>
<h3 id="heading-how-to-create-your-first-node-the-process-shape">How to Create Your First Node (The Process Shape)</h3>
<p>Adding a node to a flowchart with Mermaid is very easy. Just think of a unique name – or its <strong>ID</strong> according to the Mermaid documentation. For the sake of clarity, I’ll also refer to this ID as the <strong>node ID</strong>.</p>
<p>The node ID should be a single word with no space and preferably no other characters other than alphanumeric ones. The node ID will hold for the rest of the script and you will use it to recall that shape in other parts of the script.</p>
<p>Then adding the node consists in simply writing down the node ID under the diagram type declaration (here it’s <code>A</code>):</p>
<pre><code class="lang-mermaid">flowchart
    A
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732613071351/e4763247-0828-4a0c-998e-92beb46cc651.png" alt="What the shape will look like on your diagram - a square with an A in it." class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>Notice that so far we haven’t declared any shape for that node. When no shape is declared, the default shape is a rectangle, which is also the <strong>Process</strong> shape.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In Mermaid flowchart syntax, there is no way to declare a node without declaring at least one shape (the process shape)</div>
</div>

<p>The text that appears inside the shape is its <strong>label</strong>. There are different ways to label your shape. If you don’t label the shape, the ID is used as the label.</p>
<p>You can be as descriptive as you want with your node ID. You can provide a more meaningful name that can also be read as a label:</p>
<pre><code class="lang-mermaid">flowchart
    flowChartProcess
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732613862345/49ae30eb-d5d5-4892-9f67-025bb1836841.png" alt="Using a longer name for a node ID" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The indentation is not required when scripting with Mermaid, but I am doing it in order to keep the script organized.</div>
</div>

<p>As a rule, the name should be a single word, with some limitations when not using alphanumeric characters. For example, using some characters such as spaces is not allowed, like in this case: <code>flowChart Process</code> . Here the rendering would result in an error.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">There are reserved words and characters, such as the word “end” or the parenthesis “(…)”, that can’t be used as an id as they have specific uses. But you can use any reserved word as labels when labels are specified, as long as the label is enclosed between quotes.</div>
</div>

<h3 id="heading-how-to-declare-shapes-and-shape-labels-with-mermaid-two-different-syntaxes">How to Declare Shapes and Shape Labels with Mermaid: Two Different Syntaxes</h3>
<p>In Mermaid, you declare a node with an ID. Then you define a <strong>shape for that node</strong>.</p>
<p>You’ll need to be aware of the two different syntaxes available when declaring shapes with Mermaid. They are both live and can coexist in the same script as long as the interpreter is updated to the last version.</p>
<p>Let’s see the several ways of declaring those shapes. The following are two examples of the two available syntaxes. You can see how they’re used in the following example to render similar results:</p>
<pre><code class="lang-mermaid">flowchart LR
    flowChartProcess01[Process shape, version 10 syntax declaration, simplest labelling]
    flowChartProcess02["Process shape, version 10 syntax declaration, double-quoted labelling"]
    flowChartProcess03@{ shape: rect, label: "Process shape, version 11 syntax declaration, simplest labelling"}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734631211809/8538aa8a-c971-4446-9e87-954556a3b382.png" alt="Ways to declare shapes and labels with different Mermaid versions" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>Notice that in the example above, the first declared node didn’t require any quotes. That was because there were no special characters.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">As soon as you need to include reserved characters or words in your label, you must use quotes.</div>
</div>

<p>The first two declared nodes are examples of the original syntax. Even if not completely accurate, we will refer to that kind of syntax as the <strong>version 10 syntax</strong>.</p>
<p>As you can see from the script above, the version 10 declaration always contains:</p>
<ol>
<li><p>the name id,</p>
</li>
<li><p>followed by a combination of characters that describe the shape and that act as shape’s <strong>opening</strong> and <strong>closing</strong> characters,</p>
</li>
<li><p>with a text labelling between the shape characters.</p>
</li>
</ol>
<p>A shape’s opening and closing characters are mostly a combination of punctuation characters. Examples of special shape enclosing / opening characters are parenthesis, brackets, curly brackets, “less than“, “greater than”, and slashes. How you combine the enclosing characters will determine the kind of shape you want. For example, in the previous case, the Process shape was declared as <code>ID[&lt;LABEL&gt;]</code>.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">When declaring shapes with version 10 syntax, you always must provide a label. If you don’t do that, it will throw an error.</div>
</div>

<p>Starting with version 11.3, Mermaid introduced syntax updates aimed at greater flexibility. The last example of our script above is written using that new syntax.</p>
<p>For the version 11 declaration, you would use JavaScript-object-like syntax in this way: <code>ID@{shape: shape-alias, label: ”This is a label”}</code>. We will refer to that kind of syntax as the <strong>version 11 syntax</strong>. With this version, both properties are optional. If no shape is provided, it will show a rectangle instead. If you don’t add a label, then the renderer will use the node ID as a label.</p>
<p>The documentation provides a list of the <strong>proper names</strong> for each shape. Furthermore, you can use several <strong>aliases</strong> instead of the proper name as shape value. In this project, for the sake of simplicity we will stick to a single option for the naming with no reference to whether it is a proper name or an alias. If you want to get the full list, just <a target="_blank" href="https://mermaid.js.org/syntax/flowchart.html#expanded-node-shapes-in-mermaid-flowcharts-v11-3-0">consult the documentation</a>.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Either using version 10 or version 11, you have to define labels and shapes <em>only once</em> in your script.</div>
</div>

<p>In other words, if you have a node that is used in more than one relationship in your script, you will be ok defining the shape just for one of those node ID calls, as in the following example:</p>
<pre><code class="lang-mermaid">flowchart
    A --&gt; B
    A --&gt; C
    D --&gt; A[one time is enough]
    F --&gt; D
    %%F --&gt; A(uncommenting this will change the shape and the label too)
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735917613257/146c42d6-64ca-4c36-863b-782c3c8e2164.png" alt="You need just one shape declaration per node" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>But notice in that example that I’ve commented out one of the lines. If you uncomment that line, the label and shape will update to the new definitions for node <strong>A</strong>. In general, if you define different shapes or labels for the same node in different parts of the script, the last definition will take precedence.</p>
<p>I have found that, when using the modern declaration, you have to add a space after the colon (“:”) before the text, otherwise the interpreter won’t find the text.</p>
<blockquote>
<p>This one I have found to be incorrect (no space between <code>shape</code> and <code>text</code>):</p>
<p>{shape:text, label:text}</p>
<p>And this one was correct (a space after <code>shape:</code>):</p>
<p>{shape: text, label: text}</p>
</blockquote>
<h3 id="heading-quick-look-at-the-most-typical-shapes">Quick Look at the Most Typical Shapes</h3>
<p>There are more than 40 shapes available for flowcharts, as reported by the <a target="_blank" href="https://mermaid.js.org/syntax/flowchart.html#node-shapes">Mermaid documentation about shapes</a>. In the Mermaid documentation, shapes are named based on their geometry but also based on what they mean. Some of those shapes are named only based on their meanings, especially when there is not an easy word in geometry terminology that you can use to describe the shape.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In case you just want a list of essential shapes to start working on your flowchart but you don’t know which ones to pick, you can check out my article about flowcharts, where I give you some ideas.</div>
</div>

<p>These are the most common shapes that you’ll typically use when building a flowchart:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733765176295/06d45bcd-38c1-4c88-854d-c91bdb7e0a7c.jpeg" alt="Main flowchart shapes table. Image from https://www.smartdraw.com/flowchart/flowchart-symbols.htm" class="image--center mx-auto" width="700" height="454" loading="lazy"></p>
<p>As you can see in the table above, we have the following shapes:</p>
<ul>
<li><p>A start or end point (some people represent those kind of points with ovals, but in the Mermaid documentation the start point is represented by a circle, while the end point is represented by two nested circles)</p>
</li>
<li><p>Arrow (a connector that shows relationships between shapes)</p>
</li>
<li><p>Parallelogram (an input or output)</p>
</li>
<li><p>Rectangle (a process)</p>
</li>
<li><p>Diamond (a decision)</p>
</li>
</ul>
<p>Let’s go through each of these shapes now and see how to make them with Mermaid.</p>
<h3 id="heading-the-terminator-shape">The Terminator Shape</h3>
<p>As mentioned above, Mermaid use circles as the representation of the start point and the end point instead of the oval. The start and end points mark the starting and ending points of the process/system.</p>
<p>If we stick to the Mermaid documentation, the way to make them in Mermaid using version 10 and version 11 is as follows:</p>
<pre><code class="lang-mermaid">flowchart TD
    startv10((start v10))
    stopv10(((stop v10)))
    startv11A@{shape: circle, label: Start v11}
    startv11B@{shape: start, label: Start (small circle) v11}
    stopv11@{shape: dbl-circ, label: Stop v11}
    stopv11B@{ shape: framed-circle, label: Stop (small circle) v11 }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736598049946/3401a3a3-083d-4ef4-91ec-88adb19b7470.jpeg" alt="start and end points with different versions of Mermaid" class="image--center mx-auto" width="1097" height="198" loading="lazy"></p>
<p>In Mermaid v11, there are two types of circles you can use as a start and end points: a small shape and a regular shape. The small shapes don’t render the labelling.</p>
<p>If you decide to use the oval as the terminal (start/end points) shape, the simple circle might acquire other meanings. For example, it might become a <strong>connector shape</strong> (one that’s the exit point of a flowchart that continues in a separate flowchart or another point of the same flowchart). Or it might become another kind of connector that brings together several flowlines into a single flowline ( not as a multiprocess join, but just one that reduces the number of links when you’re looking for clarity).</p>
<p>If you prefer to use the oval (which in Mermaid is called the <strong>terminal shape</strong>), you can create it with the following code:</p>
<pre><code class="lang-mermaid">flowchart TD
    terminalv10([Terminal point v10])
    terminalv11@{ shape: stadium, label: "Terminal point v11" }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736294592460/898bede3-b035-4946-8ab2-8ccb90ece832.jpeg" alt="terminal points with different versions of Mermaid" class="image--center mx-auto" width="1070" height="155" loading="lazy"></p>
<h3 id="heading-the-arrow-rectangle-shape">The Arrow (Rectangle) Shape</h3>
<p>We’ll talk more about this one later on in this article.</p>
<h3 id="heading-the-inputoutput-parallelogram-shape">The Input/Output (Parallelogram) Shape</h3>
<p>You can use the parallelogram shape as an abstraction for data that’s available for input or output or for resources used or generated. It indicates that some information is required at this point in the workflow.</p>
<p>You can make this shape with Mermaid using the existing versions as follows:</p>
<pre><code class="lang-mermaid">flowchart TD
    inputoutputv10[/Input / Output v10/]
    inputoutputv11@{ shape: in-out, label: "Input / Output v11"}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736294704637/4541fa1f-bae1-4899-b2d5-c7e147605623.jpeg" alt="inputoutput shape with different versions of Mermaid" class="image--center mx-auto" width="1090" height="218" loading="lazy"></p>
<h3 id="heading-the-process-rectangle-shape">The Process (Rectangle) Shape</h3>
<p>You can represent a process using a rectangle in a flowchart. It represent a <strong>single step</strong> in your workflow, like an expression (for example, <code>x = y*x²</code>), a <strong>entire block statement</strong>, like “<code>loop through array and update values by multiplying by 2</code>”, or an <strong>entire sub-process</strong>, like an existing function or even a module.</p>
<p>It’s also referred to as a box (using the two versions):</p>
<pre><code class="lang-mermaid">flowchart TD
    processv10[Process v10]
    processv11@{ shape: rect, label: Process v11 }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736294826349/d289878f-3239-4e68-ad4a-e9c50d554332.jpeg" alt="process shape with different versions of Mermaid" class="image--center mx-auto" width="1117" height="285" loading="lazy"></p>
<h3 id="heading-the-decision-diamond-shape">The Decision (Diamond) Shape</h3>
<p>A decision is represented by a diamond. It’s an abstraction for a <strong>condition’s test</strong>, a YES/NO, or TRUE/FALSE question. It is the equivalent of an IF/ELSE statement in coding.</p>
<p>Using version 10 and version 11, you can make a diamond as follows:</p>
<pre><code class="lang-mermaid">flowchart TD
    decisionv10{Decision v10}
    decisionv11@{ shape: diam, label: Decision v11 }
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736294905673/7b543118-6c1a-4d78-ba68-cd323baae7ad.jpeg" alt="decision shape with different versions of Mermaid" class="image--center mx-auto" width="1103" height="622" loading="lazy"></p>
<h3 id="heading-markdown-and-html-in-mermaid">Markdown and HTML in Mermaid</h3>
<p>One of the most helpful features of Mermaid is that it accepts Markdown syntax for its labelling, as well as HTML. I would advise that you use Markdown notation, as HTML notation can result in silent errors.</p>
<p>Using double quotes and Markdown allows you to use special characters in your labels. But with Markdown syntax, you can also access various Markdown functionalities.</p>
<p>To use Markdown, you have to enclose your text in double quotes (“) followed by a backtick (`), like so:</p>
<pre><code class="lang-mermaid">flowchart TD
    flowChartProcess["`**flowChart Process**:
                        - typical shape declaration 
                        - *Markdown-style* labelling`"]
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732618144206/f00f9e9f-da69-48ae-9ad8-73bf0c9768b2.png" alt="Use of markdown for shape labelling in Mermaid flowchart" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Be aware that not all Markdown functionalities are recognized.</div>
</div>

<p>Now that you know how to use some basic shapes as well as how to use Markdown in Mermaid, let’s go on to the next step: how to draw relationships between shapes.</p>
<h3 id="heading-edges-relationships-and-edge-labels-in-mermaid">Edges (Relationships) and Edge Labels in Mermaid</h3>
<p><strong>Edges</strong>, also referred as <strong>arrows</strong> or <strong>links</strong> in Mermaid’s documentation, are the connections between nodes. They are officially called <strong>flowline shape</strong> by the ANSI standard. This is because a link might not be an arrow in some situations.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">I will refer to them as edges or links here, not arrows.</div>
</div>

<p>Drawing relationships between two nodes is as easy as adding nodes. To draw a simple arrow link between two shapes, you just have to do the following:</p>
<pre><code class="lang-mermaid">flowchart TD
    A --&gt; B
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732628585336/7758f7b5-6173-47fc-a32f-f48bcfbedb62.png" alt="Adding an arrow to a Mermaid flowchart" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>Technically, a link in Mermaid is the combination of a <strong>line</strong> and a <strong>marker</strong>. The marker is the small icon added at the end of the line. There are several types of links/edges you can draw by combining the different kinds of lines and markers that Mermaid provides:</p>
<pre><code class="lang-mermaid">flowchart TD
    %% dotted line, triangle marker
    A -.-&gt; B
    %% thick line, triangle marker
    C ==&gt; D
    %% solid cross-edged (solid line, cross marker)
    E --x F
    %% solid circle-edged (solid line, circle marker)
    G --o H
    %% combining circle marker with dotted line
    I -.-o J
    %% hidden
    K ~~~ L
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732628607536/44a80f6a-9fea-41e0-aafb-d17d61a643ec.png" alt="Different types of edges that can be added to Mermaid flowcharts" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Be aware that “o” and “x” become reserved characters when used as markers. If you need to use them as the first character of the node ID, either leave a space after the edge operator, or use capital letters.</div>
</div>

<p>Edges can also be bidirectional, for example:</p>
<pre><code class="lang-mermaid">flowchart TD
    A &lt;--&gt; B
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732628627520/42152064-6e34-4e03-9aec-93181be541a4.png" alt="42152064-6e34-4e03-9aec-93181be541a4" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>When drawing edges, you can use “syntactic sugar” in your script to reduce redundancy when defining relationships between nodes. For instance, if you have a node <strong>B</strong> situated in the middle of a sequence, you can simplify your script by chaining relationships instead of repeatedly specifying connections between <strong>B</strong> and its preceding and succeeding nodes. Also, operators can indicate crossed relationships between the same nodes.</p>
<p>The following script illustrates the difference between a verbose syntax (shown as comments) and a simplified syntax using chaining and operators:</p>
<pre><code class="lang-mermaid">flowchart TD
    %% ommitting a shape in between (chaining). the same as:
    %% A --&gt; B
    %% B --&gt; C
    A --&gt; B --&gt; C

    %% use of special character. the same as:
    %% D --&gt; F
    %% D --&gt; J
    %% F --&gt; K
    %% J --&gt; K
    D --&gt; F &amp; J --&gt; K
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732628641910/3b82896a-7b51-44bc-b8ae-6f6facc3dcb8.png" alt="Chaining and Operators in Mermaid flowchart syntax" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>Labelling links is also possible with Mermaid syntax, and it is very easy to do. There are different ways you can label a single arrow, as explained in the comments of the script: either inserting the label in between the line operator (<code>—</code>), or using <strong>vertical bars</strong> (<code>|...|</code>) placed after the marker (or when no marker, after the line operator) and before declaring the node:</p>
<pre><code class="lang-mermaid">flowchart TD
    %% inserting the label between the link operator
    A --"This is a label **between the link operator**"--&gt; B

    %% adding a link label between vertical bars, |...|
    A --&gt; |"This is a label **between special characters**"| B
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732629631977/866b28d9-3d74-4066-8e50-5112ef1d040a.png" alt="The two ways of adding labels to a links in Mermaid flowcharts" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<p>Both of those formats accept simple double-quoted or Markdown-style labelling. I have found myself more comfortable adding labels to links using the vertical bars.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Edge labelling is subject to the same restrictions as shape labelling when using reserved characters and words.</div>
</div>

<p>Now, before going on to the next section, let’s look at a quick example using what we have learned so far! I will use the typical syntax format for the example. Here it is:</p>
<pre><code class="lang-mermaid">flowchart TD
    A["Process A"] --&gt; |"Process A is followed by Process B"|B["Process B"]
    C["Process C"] -.-&gt; |"Process C relates to Process B"| B
    D["Process D"] --&gt; |"Process D is followed by Process C"| C
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734641046249/e9cf3ccc-6170-4338-bc20-b2fe9009d7bb.png" alt="Example of edge labelling" class="image--center mx-auto" width="885" height="523" loading="lazy"></p>
<h3 id="heading-subgraphs">Subgraphs</h3>
<p>In Mermaid you can also group sections of nodes under subgraphs. Here is an example right from the Mermaid documentation on how to create the syntax for a subgraph:</p>
<pre><code class="lang-mermaid">flowchart LR
  subgraph TOP
    direction TB
    subgraph B1
        direction RL
        i1 --&gt;f1
    end
    subgraph B2
        direction BT
        i2 --&gt;f2
    end
  end
  A --&gt; TOP --&gt; B
  B1 --&gt; B2
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735917794248/9bdfa5b6-725d-4ec5-841f-81be89c6d8f9.png" alt="Subgraphs with Mermaid" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>Notice that in that example, we were also able to declare different flow directions for the different (sub) graphs.</p>
<p>But the Mermaid documentation also clarifies a caveat: if a node inside a subgraph is connected to another node outside that subgraph, any declaration of subgraph direction will be overridden by the one declared for the most external (parent) subgraph. Again, here’s an example right from the Mermaid documentation:</p>
<pre><code class="lang-mermaid"> flowchart LR
    subgraph subgraph1
        direction TB
        top1[top] --&gt; bottom1[bottom]
    end
    subgraph subgraph2
        direction TB
        top2[top] --&gt; bottom2[bottom]
    end
    outside --&gt; subgraph1
    outside ---&gt; top2
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735917902060/b1282d51-11fc-490c-a81d-4a75d4851c19.png" alt="Example of direction inheritance with subgraphs" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>In the case above, the <code>subgraph2</code> was declared to be a top-bottom subgraph, but inherited the direction of the external subgraph which was declared as a left-right one. That happened because of the connection between two nodes belonging to different subgraphs at different declaration layers (the <code>subgraph2</code> is inside the “global” subgraph). In this case, <code>subgraph2</code> is a child of the global subgraph, so it inherits is direction.</p>
<h2 id="heading-how-to-add-styling-with-mermaid">How to Add Styling with Mermaid</h2>
<p>Styling in Mermaid is very CSS-compliant.</p>
<p>Let’s start with styling shapes. One way of doing it is by using the <code>style</code> command. It works as follows:</p>
<ol>
<li><p>Use the reserved word <code>style</code>,</p>
</li>
<li><p>followed by the name ID of the shape you want to style,</p>
</li>
<li><p>then indicate the properties you want to change and their new values.</p>
</li>
</ol>
<p>We’ll implement that pattern in the following example. Let’s assume that I want to differentiate between using different colors, and change the color of the letters of the labels:</p>
<pre><code class="lang-mermaid">flowchart TD
    A([this should be black with white letters]) --&gt; B([this should be grey with white letters])
    style A fill: black, color: white
    style B fill:grey, color:#fff
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735917988147/20c6d541-7755-464a-8a1a-2050c73be70f.png" alt="Shape styling with Mermaid" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>It’s important to understand that in Mermaid, styling is read up to the node level, not the shape level. You can apply different styles for the same node, too. They are read sequentially in order of appearance, so for two competing styles, the last one will be the valid one.</p>
<p>You can place the <code>style</code> expression anywhere in your code, but I would recommend doing it at the end of the script so you can track all changes.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Keep in mind that if, when styling, you refer to a non-existing node ID, Mermaid will create a new node without warning you.</div>
</div>

<p>Another useful way to add styling to your flowcharts, especially when you want to add the same styling to more than one node, is by <em>defining classes</em>. For that, you can use the special word <code>classDef</code> like so:</p>
<ol>
<li><p>Write <code>classDef</code> on one line</p>
</li>
<li><p>followed by the name you have chosen for the class</p>
</li>
<li><p>followed by the styling attributes that you want to change and their new values.</p>
</li>
</ol>
<p>To apply the class:</p>
<ol>
<li><p>Find the nodes for which you want to implement the change</p>
</li>
<li><p>add three colons (<code>:::</code>) at the end of the node declaration, and if labeling, at the end of the labeling expression</p>
</li>
<li><p>add the name of the class.</p>
</li>
</ol>
<p>The following is an example on how to add classes to shapes:</p>
<pre><code class="lang-mermaid">flowchart TD
    A[label A, no class] --&gt; B[label B, class bar]:::bar
    B --&gt; C[label C, class foo]:::foo
    C --&gt; D[label D, class bar]:::bar
    C --&gt; E[label E, class foo]:::foo
    classDef foo fill:green, color:#fff
    classDef bar fill:orange, color:#666
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918057458/46283ac9-cf5a-468d-9a6c-a92a3d5bb7bf.png" alt="Adding classes with Mermaid classDef" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Same as shape declaration, classes can be assigned to a node just once, no matter where in the flowchart. But you can add only one class per node.</div>
</div>

<p>Unfortunately, this kind of <code>classDef</code> is only applicable to <strong>shapes</strong> using <strong>version 10 syntax</strong>.</p>
<p>Something that the documentation doesn’t mention is that you can also style subgraphs. In fact, the name that you provide to a subgraph becomes its ID.</p>
<p>The styling formats applicable to shapes work almost the same for subgraphs. But the use of the <code>classDef</code> styling only works if the subgraph is also a node in the diagram.</p>
<p>The following example shows the application of the <code>style</code> command and the <code>classDef</code> command and how you can use them to add styling to subgraphs:</p>
<pre><code class="lang-mermaid"> flowchart LR
    %% applying a class as follow will give an error:
    %% "subgraph subgraph1:::asNode"
    subgraph subgraph1
        direction TB
        top1[top] --&gt; bottom1[bottom]
    end
    subgraph subgraph2
        direction TB
        top2[top] --&gt; bottom2[bottom]
    end
    outside:::asNode --&gt; subgraph1:::asNode
    outside ---&gt; top2

    style subgraph2 fill:orange
    classDef asNode fill:grey, color:orange
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918115736/6e22a8ef-e00b-4fb7-a50f-c317f54c7538.png" alt="Styling nodes and subgraphs" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>If you want to style edges, then you have to proceed differently. What actually worked for me was the use of another reserved word, <code>linkStyle</code>, which styles the <strong>line</strong> of the edge.</p>
<p>The problem with edges is that they don’t have IDs: they are treated more like being part of an array, so they should be referred with an index – which won’t always correspond to the edge you want. Here is an example, based on <a target="_blank" href="https://forum.obsidian.md/t/styling-links-in-mermaid/38789/2">this discussion</a>:</p>
<pre><code class="lang-mermaid">flowchart TD

A --&gt; B
B --&gt; C
B --&gt; D
D --&gt; E
D --&gt; F

linkStyle default stroke:red
linkStyle 0 stroke-width:4px,stroke:green
linkStyle 3 stroke:blue
linkStyle 4 stroke:blue
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918182173/7f80fae4-2994-4558-87c2-2cb0c506bbe5.png" alt="Styling links" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>The other problem with styling edges is that markers are decoupled from lines. So this method won’t affect the marker.</p>
<p>In general, I have found that adopting a consistent styling for edges is not simple with Mermaid. But it might be that for most of your projects, styling edges isn’t necessary.</p>
<p>Apart from deciding the styling of the line, the documentation suggests that we can apply some styling to the curvature of the line configuring the diagram using directives:</p>
<pre><code class="lang-mermaid">%%{ init: { 'flowchart': { 'curve': 'stepBefore' } } }%%
graph LR
A --&gt; B
B --&gt; C
B --&gt; D
D --&gt; E
D --&gt; F
</code></pre>
<p>The change should apply to all the edges in the flowchart and it should be based on the <a target="_blank" href="https://d3js.org/d3-shape/curve">d3-shape library</a>. But to date I haven’t been able to reliably configure curvature using either the directive method or the frontMatter method.</p>
<p>Keep in mind that the utilities to style edges with Mermaid might improve in the future. Meanwhile, I suggest asking dedicated communities about how to better style links with Mermaid if this is something you would like to implement for your diagrams. Share your findings with me to complement this article!</p>
<p>Finally, another way we can add more styling by affecting <strong>themes, layouts, and looks</strong>, which are set pre-set styling formats that you can modify. They will affect the styling of the whole diagram.</p>
<p>For example, out of the Mermaid documentation about the general syntax is <a target="_blank" href="https://mermaid.js.org/intro/syntax-reference.html">this script using the frontMatter method</a>:</p>
<pre><code class="lang-mermaid">---
config:
  layout: elk
  look: handDrawn
  theme: dark
---
flowchart TB
  A[Start] --&gt; B{Decision}
  B --&gt;|Yes| C[Continue]
  B --&gt;|No| D[Stop]
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918258769/59f41799-6e72-4e1a-946f-b75953e5a468.png" alt="Example of a theme in Mermaid" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>There are more ways to add styling, but they are more advanced. For the sake of simplicity, I will not discuss those more advanced solutions and will instead invite you to explore the Mermaid documentation.</p>
<h3 id="heading-directives-or-frontmatter">Directives or frontMatter?</h3>
<p>As I explained previously in this article, you can configure some attributes of the flowchart with either directives or YAML frontMatter. The documentation suggests that directives are deprecated.</p>
<p>Those methods can be used to configure the look-in-field of the whole diagram and/or some properties of the flowchart.</p>
<p>But I have been able to modify some properties of the flowchart with frontMatter as well as directives. For example, have a look at the following two examples, where the <code>fill</code> attribute is set based on a template <code>theme</code>, and the <code>nodeSpacing</code> is also modified:</p>
<pre><code class="lang-mermaid">---
title: Hello Chart
config:
    theme: base
    flowchart:
        nodeSpacing: 200
---
flowchart LR
A --&gt; B
B --&gt; C
B --&gt; D
D --&gt; E
D --&gt; F
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918365078/2a204976-3175-485f-bfa8-f951d296bbb1.png" alt="Configuring using frontMatter" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<pre><code class="lang-mermaid">%%{init:{'theme': 'base', 'flowchart':{'nodeSpacing': 200}}}%%
graph LR
A --&gt; B
B --&gt; C
B --&gt; D
D --&gt; E
D --&gt; F
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735918450420/7f9b9d84-7193-48ad-a841-be00ca234db6.png" alt="Configuring using a directive" class="image--center mx-auto" width="885" height="559" loading="lazy"></p>
<p>The results of both are almost the same, although on this occasion I couldn’t add a title to the one using a directive. There must be some advantages in preferring the YAML frontMatter approach, but be aware that you can still use both for some cases.</p>
<p>For details about the configurable flowchart properties using these and JavaScript methods, <a target="_blank" href="https://mermaid.js.org/config/schema-docs/config-defs-flowchart-diagram-config.html">visit the Mermaid documentation</a>. If you want examples on how to configure themes, <a target="_blank" href="https://mermaid.js.org/config/theming.html">follow this resource</a>. At the time of this writing, configuring through directives or frontMatter is something that I haven’t explored in depth. I invite you to give it a try and let me know what you discover.</p>
<h3 id="heading-interactivity">Interactivity</h3>
<p>Another thing that you can do with Mermaid is <a target="_blank" href="https://mermaid.js.org/syntax/flowchart.html#interaction">adding simple interactivity</a>. You can do this by using the following pattern, using the reserved words <code>click</code>, <code>call</code> and <code>callback</code>, where <code>callback</code> is the name of a callback function:</p>
<pre><code class="lang-mermaid">click nodeId callback "Tooltip when hovering"
click nodeId externalLink "Tooltip when hovering"
click nodeId call callback() "Tooltip when hovering"
</code></pre>
<p>This kind of interactivity is applicable when you have rendered the Mermaid flowchart in HTML and you have a JavaScript file associated with it. But for simple solutions, you can also make calls to a external pages by using the following pattern, as suggested by the documentation:</p>
<pre><code class="lang-mermaid">flowchart LR
    A--&gt;B
    B--&gt;C
    C--&gt;D
    click A callback "Tooltip for a callback"
    click B "https://www.github.com" "This is a tooltip for a link"
    click C call callback() "Tooltip for a callback"
</code></pre>
<p>Be aware that the configuration of <em>the whole project</em>, and not only the Mermaid configuration, might prevent you from using the interactive functionalities successfully. For example, the script given above cannot work from this article.</p>
<p>Visit the recommended resource given by the documentation itself for a working example for tooltips, but no links: <a target="_blank" href="https://jsfiddle.net/yk4h7qou/2/">https://jsfiddle.net/yk4h7qou/2/</a>. Check the examples in the Mermaid documentation to see how links work, but the tooltips won’t work: <a target="_blank" href="https://mermaid.js.org/syntax/flowchart.html#interaction">https://mermaid.js.org/syntax/flowchart.html#interaction</a>.</p>
<p>If this is something you want to try, read the documentation carefully for more insights about what you have to take in consideration when implementing this kind of solution.</p>
<h3 id="heading-mermaid-css-and-svg">Mermaid, CSS, and SVG</h3>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Mermaid documentation makes no reference to how SVGs are structured. Here I have made a quick review on how SVGs are rendered in the most recent versions.</div>
</div>

<p>You can go further than the functionalities provided by Mermaid by acting on the SVGs that the tool produces. The resulting SVG can be styled, the shapes can be modified, and so on based on your own needs and requirements.</p>
<p>So far, I have found that Mermaid produces an SVG that has a higher level structure like the following:</p>
<pre><code class="lang-bash">svg -----
        |
        (group)
        |
        markers and defs
        |
        group: class root ----
                              |
                              group: clusters (subgraphs)
                              |
                              group: edgePaths (edges)
                              |
                              group: edgeLabels (edge labels)
                              |
                              group: nodes
</code></pre>
<p>All those SVG elements might contain other groups for each node, label, edge, or subgraph you add to the diagram. For each of them, Mermaid assigns special naming, which is not strictly dynamic. For example, it might use the same id name for all the flowcharts you are creating on the same page.</p>
<p>But you can always intervene in the SVG and add specific modifications. For example, if you don’t have any other SVG on the same page you are working on, you can modify all the Process shapes using the following styling on your page:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
  <span class="hljs-selector-class">.cssClass</span> &gt; <span class="hljs-selector-tag">rect</span> {
    <span class="hljs-attribute">fill</span>: <span class="hljs-number">#ff0000</span>;
    <span class="hljs-attribute">stroke</span>: <span class="hljs-number">#ffff00</span>;
    <span class="hljs-attribute">stroke-width</span>: <span class="hljs-number">4px</span>;
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p>Notice that this is more about SVG than Mermaid, and deep diving into this is out of the scope of this article. I advise you to read more about SVGs if you want to know how to post-process Mermaid diagrams with additional features once you have created a diagram.</p>
<p>I also recommend reading the <a target="_blank" href="https://mermaid.js.org/config/usage.html">Mermaid API usage section</a> in the Mermaid documentation to better understand how to apply JavaScript to Mermaid configurations and diagram manipulation.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This article introduced you to the basics of Mermaid for creating flowcharts. We covered an overview of Mermaid, flowchart syntax, shapes, links, subgraphs, themes, and styling options. Key tips and examples, including some not found in the documentation, are included to help you learn the syntax.</p>
<p>With this guide, you should feel confident using Mermaid to integrate flowcharts into your workflow. Flowcharts are a valuable visual tool for improving understanding, and Mermaid makes creating them quick and easy.</p>
<p>To explore further, consider diving deeper into Mermaid's library for other diagram types, advanced customization, and interactivity. If you need more help, check out my other article on building flowcharts. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Make Flowcharts and Bring Joy to your Coding ]]>
                </title>
                <description>
                    <![CDATA[ Coding can be intense. Especially when you are knee-deep in debugging or trying to map complex projects. For many developers — novice and pros alike — it is not uncommon to spend hours staring at code, looking for answers that won’t come. You may hav... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-flowcharts-with-mermaid/</link>
                <guid isPermaLink="false">67852099c122b063bd5743eb</guid>
                
                    <category>
                        <![CDATA[ flow diagrams ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Learning Journey ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ effective coding ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ evaristo.c ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jan 2025 14:18:01 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736777856399/98a5d535-280e-4496-b0fb-67ad5a1b401d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Coding can be intense. Especially when you are knee-deep in debugging or trying to map complex projects. For many developers — novice and pros alike — it is not uncommon to spend hours staring at code, looking for answers that won’t come.</p>
<p>You may have tried every trick you know but still feel lost. But have you tried creating a visual representation of the problem so you can see how the code actually works?</p>
<p>I’m talking about using a <strong>flowchart</strong>.</p>
<p>In this article, you’ll learn how flowcharts work along with some common symbols and labels you can use in your flowcharts. We’ll also discuss some popular diagramming tools you can use to create flowcharts more easily. Finally, we’ll walk through how to actually build a flowchart so you can start using them in your projects.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-flowchart">What is a Flowchart?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-a-flowcharts-symbology-the-limitations-of-symbols-and-solutions">A Flowchart’s Symbology, the Limitations of Symbols, and Solutions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-common-symbols-and-labels-used-in-flowcharts">Common Symbols and Labels Used in Flowcharts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-shapes-to-your-flowchart-generalization-vs-refinement">How to Add Shapes to Your Flowchart: Generalization vs Refinement</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-popular-diagramming-tools-for-creating-flowcharts">Popular Diagramming Tools for Creating Flowcharts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-a-flowchart-methodology-and-example">How to Build a Flowchart – Methodology and Example</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-flowchart">What is a Flowchart?</h2>
<p>Simply put, a flowchart is a diagrammatic representation of an algorithm. It’s called a <em>flow</em>chart because it not only represents the steps but also depicts the direction the “job” flows as tasks are transferred to the next entity.</p>
<p>In many cases, a flowchart is considered part of a larger family of diagrams, usually referred to as <strong>flow diagrams</strong>. And although both names are commonly used, we’ll stick to the use of flowcharts to represent algorithms for now.</p>
<p>Here’s an example of a flowchart:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732568840505/37302d26-7815-468c-86cf-45fbae2e843a.webp" alt="An example of a flow diagram from https://www.visual-paradigm.com/tutorials/flowchart-tutorial/" class="image--center mx-auto" width="731" height="499" loading="lazy"></p>
<p>You’ll notice that it uses certain different shapes and colors – we’ll discuss these further below.</p>
<h3 id="heading-how-common-are-flowcharts-these-days">How Common Are Flowcharts These Days?</h3>
<p>“<em>Aren’t they from the time of, like, Cobol?</em>” you might ask. Well, yes they are – and from even before that. Flow diagrams were quite popular from their introduction in the 1920’s all the way to the 1970’s. But their use started to fall off soon after that.</p>
<p>So you might wonder: are developers actually using flowcharts – or any kind of diagram – nowadays? I did some quick research across different developer community chats. I found that while not all devs say they use flowcharts, many of them mentioned that they were important in helping them <em>sketch a vizualization</em> of the code or the system.</p>
<p>I also found that senior developers were less interested in the use of diagrams because they usually knew the algorithms or the codebase almost by heart. But newer developers who were exposed to a codebase for the first time, revisiting a forgotten algorithm, or those needing to share some code with others tended to use flowcharts more often.</p>
<h3 id="heading-why-do-devs-use-flowcharts">Why Do Devs Use Flowcharts?</h3>
<p>Here are some of the most common reasons developers use flowcharts these days:</p>
<ul>
<li><p><strong>Focus</strong>: A visual resource to help you think about a problem.</p>
</li>
<li><p><strong>Planning</strong>: Map out your steps before diving in.</p>
</li>
<li><p><strong>Sharing standard processes</strong>: As a tool to facilitate the reading of standard processes.</p>
</li>
<li><p><strong>Communicating and teaching</strong>: Explaining your code to both technical and non-technical people.</p>
</li>
<li><p><strong>Documenting</strong>: Keep track of your work in a way that’s easy to follow.</p>
</li>
<li><p><strong>Analysing existing code</strong>: Break down your code and others’ to see what’s really going on.</p>
</li>
</ul>
<p>Of course, there are other methods you could use to cope with the situations listed above. But there are advantages to using flowcharts over other methods that have to do with the way we process information in our brain.</p>
<p>Still, making flowcharts is an intellectual process that entails some risks, particularly when it comes to clarifying information. So we need the right tools and a methodology to work with them.</p>
<p>In the following sections, we will go through all those points in more detail:</p>
<ul>
<li><p>The semiotic of the flowchart – that is, the use of symbols to convey information. We’ll also discuss the role of the flowchart as an information tool, its limitations, and how to address them.</p>
</li>
<li><p>The most common symbols, their meanings, and how to use them</p>
</li>
<li><p>The intellectual processes of constructing flowcharts and their risks</p>
</li>
<li><p>A methodology to help you reduce those risks</p>
</li>
<li><p>The available tools to create flowcharts with a quick introduction to the one we will use for our examples</p>
</li>
</ul>
<h2 id="heading-a-flowcharts-symbology-the-limitations-of-symbols-and-solutions">A Flowchart’s Symbology, the Limitations of Symbols, and Solutions</h2>
<p>Earlier, I defined a flowchart as a diagram of sequences of steps, or <strong>workflow</strong>, of an algorithm. But we can also understand the flowchart as a “language”: when using a flowchart, we are translating the description of an algorithm from a verbal / textual language to a more symbolic one.</p>
<p>In other words, we can define a flowchart as a visualization of a streamlined workflow where we identify steps and relations by substituting meaningful symbols for verbal / textual descriptions.</p>
<h3 id="heading-how-symbols-work">How Symbols Work</h3>
<p>What are the advantages of using a visualization based on symbols to understand an algorithm?</p>
<p>Physically, our brain has to make more of an effort to extract meaning from either text or numbers than it does from visual attributes and shapes. For example, after some learning and under the relevant context, it is easy to get the meaning of this street sign:</p>
<p><img src="https://media-studies.com/wp-content/uploads/2021/07/barthes-road-sign-268x225.jpg" alt="children crossing road sign from https://media-studies.com/triadic-model-semiotics/" class="image--center mx-auto" width="268" height="225" loading="lazy"></p>
<p>This sign may work better than writing a board explaining that drivers should be careful as there are kids crossing the road.</p>
<p>In our example, if you have to pause to read the explanatory board, by the time you learn what the message is it could be too late. But our brain makes a faster evaluation of the situation when presented with the sign after some training.</p>
<p>Also, visual attributes and shapes can not only refer to concrete, tangible objects, but also to <em>concepts and actions</em>. For example, if you have done arithmetics before, you’ll know the meaning of the following symbols:</p>
<p><img src="https://b2990823.smushcdn.com/2990823/wp-content/uploads/2021/11/86-860869_math-math-symbol-math-clip-art-1-300x251.png?lossy=1&amp;strip=1&amp;webp=1" alt="Math arithmetic operators like multiplication, subtraction, division, and so on (Image from https://onlinemathcenter.com/blog/math/math-symbols-and-their-meanings-part-i-arithmetic-operators/)" class="image--center mx-auto" width="300" height="251" loading="lazy"></p>
<p>When we use a symbol to convey meaning, whether concrete or intangible, we usually talk about <a target="_blank" href="https://en.wikipedia.org/wiki/Semiosis"><strong>semiosis</strong></a>. Semiosis is the process of producing and interpreting signs and symbols to convey meaning. It involves the interaction between a symbol, its meaning, and the person or machine interpreting it. This process is central to the communication, understanding, and creation of knowledge in both people and machines.</p>
<p>Symbolic communication takes advantage of our innate visual processing skills. This helps reduce the need for long-winded explanations because the observer has learned somehow what the sign means. Instead of “semiosis”, some people prefer the term <strong>abstraction</strong> to refer to the same process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736344070987/cede4eac-ca8c-4fa9-9a76-280d08f655d7.png" alt="Model of Semiotics Theory, from https://opentext.wsu.edu/theoreticalmodelsforteachingandresearch/chapter/semiotic-theory/" class="image--center mx-auto" width="643" height="356" loading="lazy"></p>
<p>That it is what we do with flowcharts: abstracting meanings through symbols.</p>
<p>The value of semiotics in a visualization is substantial. Using meaningful symbols in a visualization such as a flowchart allows you and your audience to <em>focus on patterns</em> that written text, such as code or a script, can’t easily tell or describe.</p>
<p>And that is where the power of visualizations like flowcharts resides.</p>
<p>But flowchart symbols are not operators like you’d find in mathematics. Rather, they’re <em>representations.</em> In fact, they might represent something <em>specific to the person who draws them</em>.</p>
<p>Because of this, the symbols alone are often insufficient to fully convey abstract concepts. For example, the term "database” can represent many types of systems or technologies, and can have many different setups and uses. Also, as technology evolves, some symbols may lose their relevance.</p>
<p>To address this, clear textual explanations should accompany the shapes, ensuring the flowchart remains meaningful and avoids vagueness. You can also add styling and even images to strengthen the symbols’ meaning.</p>
<h2 id="heading-common-symbols-and-labels-used-in-flowcharts">Common Symbols and Labels Used in Flowcharts</h2>
<p>When creating a flowchart, you can use custom symbols, but it’s typically a good idea to stick to certain conventions. Conventions ensure better communication as well as consistency of messaging across different flowcharts.</p>
<p>The <a target="_blank" href="https://the9000store.com/articles/iso-9000-tips-iso-9001-flowchart-basics/">ANSI/ISO standards</a> list more than 30 recognized flowchart <strong>shapes</strong>, though their usage isn’t strictly regulated. This allows vendors and developers to agree on best practices.</p>
<p>Since these symbols require textual and styling support anyway, some devs argue that you can reduce the number of shapes to a “necessary few” versatile symbols instead. I refer to these as "wildcards”. Wildcards can represent broader abstractions when paired with clear text and or styling. But don’t hesitate to use other standard symbols if you think that they bring more clarity to your flowchart.</p>
<p>For our example, we will focus on the most common shapes. Some of the most common and most versatile shapes are:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1733765176295/06d45bcd-38c1-4c88-854d-c91bdb7e0a7c.jpeg" alt="Main flowchart shapes table. Image from https://www.smartdraw.com/flowchart/flowchart-symbols.htm" class="image--center mx-auto" width="700" height="454" loading="lazy"></p>
<p>As you can see in the table above, we have the following shapes:</p>
<ul>
<li><p>Oval (a start or end point)</p>
</li>
<li><p>Arrow (a connector that shows relationships between shapes)</p>
</li>
<li><p>Parallelogram (an input or output)</p>
</li>
<li><p>Rectangle (a process)</p>
</li>
<li><p>Diamond (a decision)</p>
</li>
</ul>
<p>Let’s go through each of these now and examine how they work and how to use them.</p>
<h3 id="heading-the-terminator-oval-shape">The Terminator (Oval) Shape</h3>
<p>This is the oval shape, called the start/end shape. It marks the starting and ending points of the process/system. The oval indicates the beginning or end result of the workflow, and the potential outcomes of a path.</p>
<p>Many devs use the oval shape, along with the words “start” and “end/stop/finish” for clarity.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736344293041/43e89861-4443-4335-9b56-8db1f35955a1.jpeg" alt="Start and Stop points using ovals" class="image--center mx-auto" width="1105" height="352" loading="lazy"></p>
<p>Some people prefer to use a single circle to represent the start and a double circle to represent the end of a flowchart:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736354321682/7d3639b1-bba8-4708-9d3b-2ea401d20973.jpeg" alt="Start and End points using circles" class="image--center mx-auto" width="1086" height="613" loading="lazy"></p>
<p>I personally prefer the circle – but it’s up to you. Just make sure you pick one and stick with it for consistency.</p>
<h3 id="heading-the-arrow-or-flowline-shape">The Arrow or Flowline Shape</h3>
<p>Also called the link or the edge by vendors and practitioners, this shape represents the connection between two steps. Also depending on its shape, it might indicate if that flow is broken, failed, or if it is an alternate path or process, and more.</p>
<p>The most common representation is the <strong>arrow</strong>, which indicates the direction of the workflow between two steps. The arrow points in the direction of the next step in the process.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736354396382/0f2d6f70-3f8c-426f-8231-fab1f3db599e.jpeg" alt="Flowline as arrow shape" class="image--center mx-auto" width="457" height="130" loading="lazy"></p>
<p>When working with flowcharts, I accompany arrow flowlines and any other flowline with concise descriptions about the next step, sometimes with information about variables and, when it makes sense, the current state.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736354505571/78beea08-63bb-4149-952a-960c4a7756f1.jpeg" alt="An arrow shape with labelling" class="image--center mx-auto" width="837" height="317" loading="lazy"></p>
<h3 id="heading-the-process-rectangle-shape">The Process (Rectangle) Shape</h3>
<p>You can represent a process using a rectangle in a flowchart. It’s also referred to as a box:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736355468300/d159a2b0-92fa-4df2-abaa-4402953208a5.jpeg" alt="Process shape" class="image--center mx-auto" width="1068" height="567" loading="lazy"></p>
<p>A box can represent a <strong>single step</strong>, like an expression (for example, <code>x = y*x²</code>), a <strong>entire block statement</strong>, like “<code>loop through array and update values by multiplying by 2</code>”, or an <strong>entire sub-process</strong>, like an existing function or even a module.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736355653833/3d88a287-7966-45ef-9a65-460422d4c2f9.jpeg" alt="Process shapes with different labels" class="image--center mx-auto" width="681" height="641" loading="lazy"></p>
<p>The process shape is a proper wildcard and it can morph into many things, so it’s important to add a label to it and using text or other resources like formatting to clarify its meaning.</p>
<h3 id="heading-the-decision-diamond-shape">The Decision (Diamond) Shape</h3>
<p>The decision is represented by a diamond. It is an abstraction for a <strong>condition’s test</strong>, a YES/NO, or TRUE/FALSE question. It is the equivalent of an IF/ELSE statement in coding.</p>
<p>The text accompanying this shape is a question formulating a comparison between an entering value and a control value. The flowchart usually splits into different branches depending on the answer or consequences after you use the decision shape:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736355725641/90042033-abc1-42a2-9c06-883d8f09e686.jpeg" alt="Decision shape with two branches" class="image--center mx-auto" width="905" height="620" loading="lazy"></p>
<p>The result of the decision box determines the next step in the process workflow. It’s usually declared to only answer a simple question, but you can abstract the question so it looks similar to an IF/ELSE IF/ … /ELSE control statement in coding, with lines representing different decisions.</p>
<p>When one of the flows returns to the decision shape from where it left, we are talking about <strong>a loop</strong>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736355864209/0f4b5cb4-b81c-482c-8d22-74854bf28d64.jpeg" alt="Decision shape with two branches, one of them in a loop" class="image--center mx-auto" width="1075" height="636" loading="lazy"></p>
<p>The interpretation is like asking to test the condition again after going through some steps along a specific workflow branch, then checking if the answer has changed.</p>
<h3 id="heading-the-inputoutput-parallelogram-shape">The Input/Output (Parallelogram) Shape</h3>
<p>You can use the parallelogram shape as an abstraction for data that’s available for input or output or for resources used or generated. It indicates that some information is required at this point in the workflow.</p>
<p>The input/output shape is typically accompanied by the following text:</p>
<ul>
<li><p>Either “input” or “output”, so you know which is being represented. You can also write other similar words like “get” / “put”, “in” / “out”, and so on.</p>
</li>
<li><p>An input or an output could be related to a variable that you are planning or you already have in your code. If that variable should have an expected type when either entering as input or output, I would also add the type.</p>
</li>
<li><p>Its corresponding state, as long as it provides more clarity to the flowchart.</p>
</li>
<li><p>Optionally, it would be also useful to mention the source of the input / output. Is it a dataset? A manual entry? A form? Will it be printed in the console?</p>
</li>
</ul>
<p>Notice that the whole point of the use of this shape is to trace the entry or the exit of data into or out of the process. Therefore, this shape is valuable when you want to have at least an idea of data exchange.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736355986275/e19e64b8-0b85-4ee8-aff7-333b1d0fd6e5.jpeg" alt="Input / Output shape with label" class="image--center mx-auto" width="1070" height="270" loading="lazy"></p>
<p>Finally, a less common symbol, but one that I use often is…</p>
<h3 id="heading-the-preparation-hexagon-symbol">The Preparation (Hexagon) Symbol</h3>
<p>The preparation symbol is represented by an hexagon and it abstracts the setup for the following step. I usually use this shape to declare all the initial conditions when the workflow begins. I accompany this shape with a list of variables, their types, and even functions or initial event settings, like event listeners, together with their initial values.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736356077330/05e0e186-ddf8-40e7-bfc5-ea859e7d86ae.jpeg" alt="Preparation shape with label" class="image--center mx-auto" width="1087" height="617" loading="lazy"></p>
<h2 id="heading-how-to-add-shapes-to-your-flowchart-generalization-vs-refinement">How to Add Shapes to Your Flowchart: Generalization vs Refinement</h2>
<p>Now that you understand the basics of the symbols, you may be wondering how to insert them into the diagram.</p>
<p>Especially for large diagrams, you’ll want to be very intentional about adding shapes. You’ll need to make careful decisions about placing and the number of shapes you’ll use, otherwise your flowchart could become unreadable.</p>
<p>You’ll need to make decisions about things like:</p>
<ul>
<li><p>where to place the shapes so it results in a tidy flowchart.</p>
</li>
<li><p>which of those shapes are essential to the understanding of the workflow, and which are not.</p>
</li>
</ul>
<p>Placing is perhaps the most difficult task of making a flowchart. If you are manually constructing your flowchart, unfortunately there’s not a simple formula that instructs you where to place the shapes in order to prevent overlapping. It’s up to you to visually resolve the placement and to decide when any overlap makes your diagram unreadable.</p>
<p>As you’ll see later, there are computationally-based solutions for the placing of shapes. But there is a simple rule that applies to all cases: the smaller the flowchart, the easier it is to place the shapes. So reducing the number of shapes and only including the key shapes is key to creating a clear flowchart.</p>
<p>Keep in mind that I’m not suggesting that you try to create the most minimalistic flowchart you can. Just that you try to make the simplest one that conveys enough information to help you understand the workflow.</p>
<h3 id="heading-how-to-choose-which-shapes-to-use">How to Choose Which Shapes to Use</h3>
<p>Deciding which shapes to use can turn into an iterative process of adding, moving, or removing text or symbols into or out of the flowchart.</p>
<p>There are two competing tendencies here: <strong>generalization</strong> and <strong>refinement</strong>.</p>
<p>For example, the next figure shows three different flowcharts that demonstrate how to use a coffee machine:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736368833320/b2e7ad79-8726-4e2d-b114-e0c36520044c.jpeg" alt="Three levels of generalization / refinement of flowcharts of how to use a coffee machine" class="image--center mx-auto" width="1282" height="1461" loading="lazy"></p>
<p>In the image above, you can see that the example on the left is the one with less explanations and fewer shapes, while the one on the right has more details.</p>
<p>In the same way, depending on your needs and the specific details you want to get out of the visualization, the flowchart can be more generalized or it can be more refined. In fact, it might acquire some elements of subjectivity, which usually rely on the <strong>amount of information and knowledge</strong> you have about the process <strong>before</strong> looking at the flowchart.</p>
<h4 id="heading-generalization">Generalization:</h4>
<p>In the case of flowcharts, <strong>generalization</strong>, also known as <em>lifting</em>, is when you enclose several steps into a few words and / or symbols. There are two reasons to use a more generalized approach:</p>
<ol>
<li><p>You and your audience are competent enough to complete the information not provided by the flowchart.</p>
</li>
<li><p>You and your audience don’t know much about that specific step.</p>
</li>
</ol>
<p>In the second case, there are two situations you might be dealing with:</p>
<ol>
<li><p>Even if you don’t know much about that part of the process, you can keep that step generalized because that step plays a small role in providing information that’s essential to you. Or,</p>
</li>
<li><p>The point is critical for you to understand the process, but you and your audience simply don’t know more.</p>
</li>
</ol>
<p>It’s in the second situation when you have to try to “open the box”. And this is done through refinement.</p>
<h4 id="heading-refinement">Refinement:</h4>
<p><strong>Refinement</strong> consists of adding more steps and more words and symbols in order to add more detail to a procedure. It usually follows researching and studying.</p>
<p>When you’re refining your flowchart, this doesn’t necessarily mean that you know absolutely nothing about the procedure. What you’re looking for is something that allows you to point to specific details, and what comes before and what comes next.</p>
<p>But how much generalization is helpful? And how much refinement?</p>
<p>When your flowchart is too general, it results in a simpler visualization but it doesn’t contain much information. You might have to use more words or rely on inner knowledge in order to explain what the chart or a step means. The first flowchart in the previous image is the most generalized of all of them.</p>
<p>The risk of over-generalization is <em>non-information</em>.</p>
<p>The process of refinement involves the opposite risk, and is, in my view, more dangerous. If you don’t control the refinement process, you might end up with an absolute mess, like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732788718770/657328f7-93b2-40a3-839f-f87bd47c9e76.jpeg" alt="A very messy and overly complex diagram" class="image--center mx-auto" width="1600" height="853" loading="lazy"></p>
<p>The above diagram isn’t a flowchart, but the risk is the same. The risk of excessive refinement is <em>noise</em>.</p>
<p>There are several rules and mechanisms that help you prevent reaching an unnecessary level of either refinement or abstraction. This is what we are going to learn in the next sections. But first, let’s take a quick look at the available tools you can use to make diagrams and flowcharts.</p>
<h2 id="heading-popular-diagramming-tools-for-creating-flowcharts">Popular Diagramming Tools for Creating Flowcharts</h2>
<p>Now that you know the shapes, what they are for, and have some idea about how to use them, you can start building a flowchart.</p>
<p>But before doing so, I’m going to make a short detour to talk about the tools you can use to build flowcharts.</p>
<p>Nowadays, the options are many. You can use online as well as offline resources. Some are specialized for building diagrams, while others are more general. Some you can access for free, and others are more for enterprise operations and come with high fees.</p>
<p>Below, you’ll find a quick table categorizing some of the dedicated tools I have used in the past or that I have been investigating recently.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Dedicated Solutions for Drawing Flowcharts</strong></td></tr>
</thead>
<tbody>
<tr>
<td></td></tr>
</tbody>
</table>
</div><div class="hn-table">
<table>
<thead>
<tr>
<td>CATEGORY</td><td>HOW</td><td>EXAMPLES (free)</td></tr>
</thead>
<tbody>
<tr>
<td>Drag and Drop</td><td>Shapes are manually dragged into a editor screen, linked with connectors and filled with relevant text.</td><td>draw.io</td></tr>
<tr>
<td>Scriptable</td><td>A script is written with a dedicated syntax for shapes, relationships, and text. The flowchart is automatically rendered and updated after changing the script.</td><td>Mermaid, PlantUML</td></tr>
<tr>
<td>AI-based</td><td>A descriptive prompt or even code is provided to the AI. The AI analyzes the content, usually recoding into a scriptable diagram before rendering it.</td><td>codetoflow.ai, ChatGPT plugins</td></tr>
<tr>
<td>Parser</td><td>Map (binary) code into dedicated graphical solutions based on established syntax rules.</td><td>drgarbagetools for Java in Eclipse, graphdracula for JQuery</td></tr>
</tbody>
</table>
</div><h4 id="heading-no-code-or-low-code-tools">No-code or low code tools:</h4>
<p>The large majority of the existing specialized diagramming tools are designed to help people without coding skills.</p>
<p>When using these types of tools, you have to manually construct the diagram by <strong>dragging-and-dropping</strong> shapes into an (online) editor: you select the shape and move it around until you find your preferred place for it on the screen. There are functionalities to draw the flowlines (“connectors”) also by a dragging action, and you can always edit the shapes to add text or styling.</p>
<h4 id="heading-script-based-tools">Script-based tools:</h4>
<p>But there are also some less well-known tools that have been around for a while that are rising in popularity now: the <strong>script-based</strong> options. With these kinds of tools, you describe the shapes and relationships by scripting them according to the syntax of the tool.</p>
<p>These kinds of tools have the relative advantage that the diagram will be drawn for you on a rendering screen or image. An algorithm will try to find the best place for your shapes on the screen without you having to place them manually.</p>
<h4 id="heading-ai-tools">AI tools:</h4>
<p>Then there are the <strong>AI</strong> tools. Many of those tools are based on the scripting tools. Some of them work as follows:</p>
<ol>
<li><p>the AI interprets either a descriptive prompt or the code itself</p>
</li>
<li><p>Then it translates the prompt into a script using a scriptable diagramming tool</p>
</li>
<li><p>The diagram renders according to the AI-generated code.</p>
</li>
</ol>
<p>I’ve found that these AI tools are still not quite up to the task for more complex projects – but they can come handy if you just want a quick solution. One that I have used is codetoflow.io, but there are also (guess what…) ChatGPT plugins you can use.</p>
<h4 id="heading-parsers">Parsers</h4>
<p>Even before the AI tools came around, there were the parsers. They map steps and relationships into shapes based on well-established syntax rules. Some of those parsers are turning to AI instead, as the AI generators are easier to program and require less maintenance. But sometimes the rule-based parsers can be more precise if the rules they are based on remain without changes.</p>
<p>Some of those tools read on binary code, which is a better proxy to follow the full workflow, something that popular AI tools are not capable of. Some IDEs, like Eclipse, allow you to add plugins to draw a flowchart of your code based on binaries. One example is <a target="_blank" href="https://sourceforge.net/projects/drgarbagetools/">drgarbagetools</a> which works only for Java in Eclipse.</p>
<h4 id="heading-general-purpose-tools">General-purpose tools:</h4>
<p>Apart from those dedicated tools, you can always use others that are not specifically built for diagramming. I have used PowerPoint and Google Slides in the past, and there are other presentation applications that support the ANSI / ISO shapes’ catalogue. You can also use tools like Figma, Miro, or others. There are too many others to list here.</p>
<p>And finally, there is always pen a paper.</p>
<h3 id="heading-our-example-using-mermaidjs">Our Example: Using Mermaid.js</h3>
<p>For the example in this tutorial, I’ll be using one of the scripting tools called Mermaid. One reason for using a script-based tool is the ease with which you can update the flowchart along the way. And this will come in handy when we reach the generalization / refinement step.</p>
<p>Although other tools do not hinder the generalization/refinement process, the fact that you might find yourself redoing the whole flowchart manually could become quite time consuming. With a script-based tool, you can focus mostly on writing down the right relationships and shapes, while you let the program place the shapes for you.</p>
<p>Although I’m using Mermaid here, I’m not prescribing the use of any particular tool for the examples ahead. You can use the one that suits your needs and with which you feel the most comfortable. None of them are perfect, and they all have their own merits.</p>
<p>But if you want to learn more about Mermaid, <a target="_blank" href="https://www.freecodecamp.org/news/use-mermaid-javascript-library-to-create-flowcharts">I’ve written another tutorial for you</a> that’ll give you a general overview of the tool and how to use it. I will also provide the syntax I am using to create the examples so you can try it yourself.</p>
<h2 id="heading-how-to-build-a-flowchart-methodology-and-example">How to Build a Flowchart – Methodology and Example</h2>
<p>When building a flowchart, you can follow these steps:</p>
<ol>
<li><p>Define the scope of your flowchart</p>
</li>
<li><p>Find the start of the workflow</p>
</li>
<li><p>Trace the workflow to the end while using high levels of generalization for the steps</p>
</li>
<li><p>Select what should be refined and what can be left generalized</p>
</li>
<li><p>Iterate: Research. Refine. Test. Research. Refine or Generalize. Test. Research. Refine or Generalize…</p>
</li>
<li><p>Enhance</p>
</li>
<li><p>Extend (optional)</p>
</li>
</ol>
<h3 id="heading-step-1-define-the-scope-of-your-flowchart">Step 1: Define the Scope of Your Flowchart</h3>
<p>It’s important to be clear about what you want to do with your flowchart. Is it representing a full codebase or just a fragment of a script? Is it an algorithm that you want to study or is it an analysis of some existing code? Do you want a detailed explanation of a workflow or just look at the relationships?</p>
<p>Having a clear goal for your flowchart will help you guide its construction.</p>
<p>For this example, we are going to use an exercise from freeCodeCamp’s curriculum:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> character = <span class="hljs-string">"#"</span>;
<span class="hljs-keyword">const</span> count = <span class="hljs-number">8</span>;
<span class="hljs-keyword">const</span> rows = [];

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; count; i = i + <span class="hljs-number">1</span>) {
  rows.push(character.repeat(i + <span class="hljs-number">1</span>))
}

<span class="hljs-keyword">let</span> result = <span class="hljs-string">""</span>

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> row <span class="hljs-keyword">of</span> rows) {
  result = result + row + <span class="hljs-string">"\n"</span>;
}

<span class="hljs-built_in">console</span>.log(result);
</code></pre>
<p>Our purpose here is to understand this code, particularly to gain more insights about the for-loops.</p>
<h3 id="heading-step-2-find-the-start-of-the-workflow">Step 2: Find the Start of the Workflow</h3>
<p>Once you have an idea of what you want to do with your flowchart, try to figure out the point from where the workflow begins. If it involves analyzing existing code, bear in mind that the start of the workflow might not be at the start of your target code. Just keep in mind that whatever triggers the whole procedure, that is an indication that the “start” is there.</p>
<p>The workflow usually starts with the setting of the initial declarations and values, so we could say that our flowchart could start like this for this example:</p>
<pre><code class="lang-mermaid">flowchart TD
start((start)) --&gt; |variable declaration| varDeclaration{{"*character*(str) 
                                          *count*(num) 
                                          *rows*(list) 
                                          *result*(str)"}}
varDeclaration -.-&gt; C["..."]
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736356220066/242c2201-6a0f-45b0-802c-fe5b71551291.jpeg" alt="Step 2: finding the start point" class="image--center mx-auto" width="420" height="635" loading="lazy"></p>
<h3 id="heading-step-3-trace-the-workflow-to-the-end-and-use-high-levels-of-generalization-in-each-step">Step 3: Trace the Workflow to the End and Use High Levels of Generalization in Each Step</h3>
<p>Once you’ve found the starting point, try to systematically trace the workflow steps from start to end. If there are procedures along the way, you can compact them into more generalized steps using no more than two shapes.</p>
<p>The most common shape for depicting a generalized step is the <strong>process shape</strong>. Candidates to keep generalized are functions, control statement blocks like loops or if-statements, modules, or even libraries. Labels of those steps should consist of general descriptions of the things that are happening or should happen at that step.</p>
<p>For our example, we can represent our workflow and in particular the for-loops at a general level like this:</p>
<pre><code class="lang-mermaid">flowchart TD
start((start)) --&gt; |variable declaration| varDeclaration{{"*character*(str) 
                                          *count*(num) 
                                          *rows*(list) 
                                          *result*(str)"}}
varDeclaration --&gt;|"Use *character* and *count* to fill the *rows* list through a for-loop with strings"| forloop01["for-loop01 with *count* as control: str.repeat(*character*) --&gt; *rows*.push(str)"]
forloop01 --&gt; |"Use the updated *rows* list to create a new *result* string"| forloop02["for-loop02 along *rows* items: 
*row* --&gt; 
*result* = *result* + *row* + '\n'"]
forloop02 --print output to the console--&gt; consolelog["console.log(*result*)"]
consolelog --&gt; stop(((stop)))
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736358790514/7416bcdf-bbc4-4386-97f7-27bca59e61d8.jpeg" alt="Step 3: finding the end point and adding general steps" class="image--center mx-auto" width="536" height="921" loading="lazy"></p>
<h3 id="heading-step-4-determine-what-requires-refinement-and-what-to-leave-generalized">Step 4: Determine What Requires Refinement and What to Leave Generalized</h3>
<p>Stop for a while and review the schema you’ve created. Once you have a picture of the whole workflow, you’ll want to decide which sections might require more details.</p>
<p>In our case, we’ll refine the parts of the flowchart that deal with the two for-loops. Describing a for-loop is a typical example when learning to create flowcharts, but I also realized that the two for-loops in our exercise are not of the same type. So I thought it would be interesting to see if the flowchart can reveal how they compare.</p>
<h3 id="heading-step-5-time-to-iterate-research-refine-or-generalize-test-repeat">Step 5: Time to Iterate (Research, Refine or Generalize. Test. Repeat.)</h3>
<p>What you’ve prepared up to Step 4 is a general sketch of the workflow. Now it’s time to dig into the areas where more detail is required. During this process, sometimes you’ll find yourself coming back to an abstraction while looking for the clearest way forward with your flowchart.</p>
<p>There are two things that will help you in this process:</p>
<ol>
<li><p><strong>New Shapes</strong>: this is the time when you may want to use some other shapes. Start with the most common ones. Use other shapes as long as you can give them a clear role in your flowchart and they help you reduce a long explanation about what the replaced shape does.</p>
</li>
<li><p><strong>Text</strong>: Extend the use of text to explain the workflow. It should be more specific to the algorithm itself.</p>
</li>
</ol>
<p>This process ends when you are satisfied with the clarity and level of detail of your flowchart. But there are a best practices that allow you to control the process:</p>
<ul>
<li><p>Try to keep everything to a single page.</p>
</li>
<li><p>Keep the number of shapes to around 20 per page.</p>
</li>
<li><p>Avoid line-crossing more than 4 times. Use connectors when that happens. Having to explain 5 or more connections is likely not a good thing.</p>
</li>
</ul>
<p>After any change, test your flowchart. <strong>Testing</strong> is the most subjective aspect of the methodology. There might not be a way to test the flowchart result against a tangible outcome.</p>
<p>If that makes you uncomfortable, try to think in the following way: the flowchart can be seen as a sort of ordered TODO list or brainstorm notes describing what the code or system should do in order to accomplish a desired task.</p>
<p>A flowchart is similar to this TODO list. But instead of writing all those steps as comments or even pseudo-code, you are using (conventional) symbols.</p>
<p>But barring the advances of AI or any use of <a target="_blank" href="https://en.wikipedia.org/wiki/No-code_development_platform">flow-based programming</a>, comments are not code, no matter how detailed they are.</p>
<p>So the decision of whether the flowchart is working or not is left to you and your audience. The most important question to resolve here is: is the information provided by the flowchart enough to understand what you need to understand about the process? Is it revealing something new? Is it helping you organize your ideas more clearly?</p>
<p>If you are still not satisfied, then repeat the process. But don’t feel like you have to stick to this process alone. You can always stop this effort and look for another way to explain your procedures if you find that a flowchart won’t work for you.</p>
<p>You could facilitate the refining and the clarity of the output by doing some additional research. Try to find how other people describe the procedure you are about to work on. Is there something about the language that you should keep in mind? Whenever possible, don’t start from scratch.</p>
<p>Also, try to be faithful as much as possible to the actual way in which the procedure should be coded, especially if you are refining. But don’t forget that it’s a representation. Feel free to work on a draft when not enough information is available.</p>
<p>Let’s go back to our example. I did some quick research to find out how others might interpret a for-loop in a flowchart. I found <a target="_blank" href="https://en.wikipedia.org/wiki/For_loop#/media/File:For_loop_example.svg">this reference useful</a> to guide my own description:</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/For_loop_example.svg/220px-For_loop_example.svg.png" alt="220px-For_loop_example.svg" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>This approach seems to be fairly standard and I will try to include some of those steps in my flowchart. I also found that according to JavaScript documentation, the kind of for-loop we are about to represent repeats <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">until a specified condition evaluates to false</a>, just like in the flowchart above.</p>
<p>Let’s start by working on the first for-loop only:</p>
<pre><code class="lang-mermaid">flowchart TD
    start((start)) --&gt; |variable declaration| varDeclaration{{"`*character*(str)
    *count*(num)
    *rows*(list)
    *result*(str)`"}}
    varDeclaration --&gt; |**Start First Loop**: entering initial values of *i* and *count*| inputToLoop01[/"`input: 
                                                                                                            *count* = 8
                                                                                                            *i* = 0
                                                                                                            `"/] 
    inputToLoop01 --&gt; forLoop01{"`Is *i* &lt; *count*?`"}
    forLoop01 -.NO: something happens..-&gt; stop(((stop)))
    forLoop01 --&gt; |YES| inputI[/"`input: *i*`"/]
    inputI --&gt; |"`create strings of length (*i* + 1) from *character*`"| repeatStr["**new string** = character.repeat(i+1)"]
    repeatStr --&gt; |"`add newly created string 
            at the end of *rows* list`"| pushToRows["`rows.push(**new string**)`"]
    pushToRows --&gt; |"`bottom of the block: update *i*`"| updateI[/i = i+1/]
    updateI --&gt; |evaluate condition| forLoop01
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736358955713/d7693d1f-1f47-417f-b147-d6f23f7f74c6.jpeg" alt="Step 5: refining; first for-loop" class="image--center mx-auto" width="562" height="1005" loading="lazy"></p>
<p>Perfect.</p>
<p>Let’s now focus on the second for-loop. It turns out that it’s syntactically different from the previous one. And in fact, there are <a target="_blank" href="https://en.wikipedia.org/wiki/For_loop">different kinds of loops in programming</a>. The one we refined earlier is usually known as the “traditional” one, or better a <em>numeric range</em> type for-loop. The second one is an <em>iterator</em> type for-loop.</p>
<p>An <a target="_blank" href="https://refactoring.guru/design-patterns/iterator">iterator</a> is a functionality that moves incrementally along a group of values or <em>items</em>. That functionality can have subprocesses to initialize the iterator – one to get the current value the iterator is pointing to, as well as a subprocess to go to the next one.</p>
<p>Also, remember that a for-loop stops repeating a workflow branch as soon as the condition evaluates to <code>false</code>.</p>
<p>Let’s try to reflect all this knowledge when refining the second for-loop. I will generalize the first for-loop for the sake of clarity:</p>
<pre><code class="lang-mermaid">flowchart TD
    start((start)) --&gt; |variable declaration| varDeclaration{{"`*character*(str)
    *count*(num)
    *rows*(list)
    *result*(str)`"}}
    varDeclaration --&gt; |**Start Range-Based Loop**: entering initial values of *i* and *count*| forLoop01["Range-Based For-Loop"]
    forLoop01 -- enter Iterator-Based For-Loop --&gt; inputToLoop02[/"`INPUT:
                                                                *rows* (list of str of size *count*)
                                                                *result* (empty str)`"/]
    something --&gt; stop(((stop)))
    inputToLoop02 --&gt; forLoop02{"`Are there still *rows*' items?`"}
    forLoop02 --&gt; |YES: get the current one| row[/"GET: *row* = currentItem(*rows*)"/]
    row --&gt; |"concatenate the current *row* item plus a line (\n) to the current value of *result*"| newStr["**new string** = *result* + *row* + '\n'"]
    newStr --&gt; |change the value of *result* for **new string**|newRes[*result* = **new string**]
    newRes --&gt; |"`bottom of the block: move to next item`"| updateR[/"nextItem(*rows*)"/]
    updateR --&gt; forLoop02
    forLoop02 --&gt; |NO: we exhausted all the items| something
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736363492801/fe1199c8-edba-4e5b-9874-3bf151cc0d48.jpeg" alt="Step 5: refining; second for-loop" class="image--center mx-auto" width="584" height="1304" loading="lazy"></p>
<p>Now we have a clear flowchart for each of the for-loops! We had to first understand what the loops were about, and then had to find a way to represent them. We used refinement and generalization to expand / contract the information rendered by the flowchart.</p>
<p>At the end, we just have to accept that these are still approximations — in order to get how those for-loops <em>really</em> work, we would have to go learn more about JavaScript, probably looking through the JavaScript source code, or even closer to the machine by analysing binaries. But I’m personally satisfied with the information I got from the analysis.</p>
<p>Now after making these changes, we can come back and merge both flowcharts (for each of the for-loops) to complete the full representation of the code:</p>
<pre><code class="lang-mermaid">flowchart TD
    start((start)) --&gt; |variable declaration| varDeclaration{{"`*character*(str)
    *count*(num)
    *rows*(list)
    *result*(str)`"}}
    varDeclaration --&gt; |**Start Range-Based For-Loop**: entering initial values of *i* and *count*| inputToLoop01[/"`INPUT: 
                                                                                                            *count* = 8
                                                                                                            *i* = 0
                                                                                                            `"/] 
    inputToLoop01 --&gt; forLoop01{"`Is *i* &lt; *count*?`"}
    forLoop01 --&gt; |YES| inputI[/"`GET: *i*`"/]
    inputI --&gt; |"`create strings of length (*i* + 1) from *character*`"| repeatStr["**new string** = character.repeat(i+1)"]
    repeatStr --&gt; |"`add newly created string 
            at the end of *rows* list`"| pushToRows["`rows.push(**new string**)`"]
    pushToRows --&gt; |"`bottom of the block: update *i*`"| updateI[/i = i+1/]
    updateI --&gt; |evaluate condition| forLoop01
    forLoop01 --&gt;|NO| outputRows[/"`OUTPUT: *rows* list of string items of size *count*`"/]
    outputRows --&gt; |**Start Iterator-Based For-Loop**: entering initial values of *rows* and *result*| inputToLoop02[/"`INPUT:
                                                                *rows* (list of str of size *count*)
                                                                *result* (empty str)`"/]
    inputToLoop02 --&gt; forLoop02{"`Are there still *rows*' items?`"}
    forLoop02 --&gt; |YES: get the current one| row[/"GET: *row* = currentItem(*rows*)"/]
    row --&gt; |"concatenate the current *row* item plus a line (\n) to the current value of *result*"| newStr["**new string** = *result* + *row* + '\n'"]
    newStr --&gt; |change the value of *result* for **new string**|newRes[*result* = **new string**]
    newRes --&gt; |"`bottom of the block: move to next item`"| updateR[/"nextItem(*rows*)"/]
    updateR --&gt; forLoop02
    forLoop02 --&gt; |NO: we exhausted all the items| outputResult[/"`OUTPUT: *result* (str)`"/]
    outputResult --&gt; |"`display *result* on the console`"|displayResult["`console.log(*result*)
            fa:fa-display`"]
    displayResult --&gt; stop(((stop)))
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736364028135/12ea16c2-69ea-4a1d-9eb4-57025b3aa205.jpeg" alt="Step 5: complete flowchart of the example code" class="image--center mx-auto" width="615" height="1304" loading="lazy"></p>
<h3 id="heading-step-6-enhance-the-flowchart">Step 6: Enhance the Flowchart</h3>
<p>Sometimes, specially with large flowcharts, the repeated use of similar shapes requires additional enhancement to provide more clarity. Normally you won’t quite know what you need to enhance until you have the full picture of something more final.</p>
<p>One way to do this is by grouping sections of the workflow. For that, you can use styling, like coloring the shapes, to highlight similar or related steps. It can also be helpful to highlight elements in the workflow that are really playing a fundamental role in the analysis.</p>
<p>You can also create groups of sub-procedures by boxing them (that is, placing a box around related elements of the flowchart).</p>
<p>Let’s apply some enhancements to our final flowchart by boxing and coloring:</p>
<pre><code class="lang-mermaid">flowchart TD
    start((start)) --&gt; |variable declaration| varDeclaration{{"`*character*(str)
    *count*(num)
    *rows*(list)
    *result*(str)`"}}
    varDeclaration --&gt; |**Start Range-Based For-Loop**: entering initial values of *i* and *count*| inputToLoop01[/"`INPUT: 
                                                                                                            *count* = 8
                                                                                                            *i* = 0
                                                                                                     `"/]:::input 
    subgraph RANGE_BASED_LOOP
    inputToLoop01 --&gt; forLoop01{"`Is *i* &lt; *count*?`"}
    forLoop01 --&gt; |YES| inputI[/"`GET: *i*`"/]:::get
    inputI --&gt; |"`create strings of length (*i* + 1) from *character*`"| repeatStr["**new string** = character.repeat(i+1)"]
    repeatStr --&gt; |"`add newly created string 
            at the end of *rows* list`"| pushToRows["`rows.push(**new string**)`"]
    pushToRows --&gt; |"`bottom of the block: update *i*`"| updateI[/i = i+1/]:::input
    updateI --&gt; |evaluate condition| forLoop01
    end
    forLoop01 --&gt;|NO| outputRows[/"`OUTPUT: *rows* list of string items of size *count*`"/]:::output
    outputRows --&gt; |**Start Iterator-Based For-Loop**: entering initial values of *rows* and *result*| inputToLoop02[/"`INPUT:
                                                                *rows* (list of str of size *count*)
                                                                *result* (empty str)`"/]:::input
    subgraph ITERATOR_BASED_LOOP
    inputToLoop02 --&gt; forLoop02{"`Are there still *rows*' items?`"}
    forLoop02 --&gt; |YES: get the current one| row[/"GET: *row* = currentItem(*rows*)"/]:::get
    row --&gt; |"concatenate the current *row* item plus a line (\n) to the current value of *result*"| newStr["**new string** = *result* + *row* + '\n'"]
    newStr --&gt; |change the value of *result* for **new string**|newRes[*result* = **new string**]
    newRes --&gt; |"`bottom of the block: move to next item`"| updateR[/"nextItem(*rows*)"/]:::input
    updateR --&gt; forLoop02
    end
    forLoop02 ---&gt; |NO: we exhausted all the items| outputResult[/"`OUTPUT: *result* (str)`"/]:::output
    outputResult --&gt; |"`display *result* on the console`"|displayResult[/"`console.log(*result*)
            fa:fa-display`"/]
    displayResult --&gt;|finish| stop(((stop)))

    style start fill:black, color:#fff
    style displayResult fill: #DFFF73
    style stop fill:grey, color:#fff, stroke: white
    classDef input fill:#F8D192
    classDef get fill:#F8D062
    classDef output fill:#ECF892
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736364525277/56399b5f-c967-425e-8a74-bd33c98e8411.jpeg" alt="Step 6: Flowchart after styling" class="image--center mx-auto" width="612" height="1191" loading="lazy"></p>
<h3 id="heading-step-7-extend-the-flowchart">Step 7: Extend the Flowchart</h3>
<p>This step is optional. If you have done what you can to keep the flowchart as clear as possible – but you are finding that it still needs more refinement – you may be dealing with a complex process.</p>
<p>In this case, it’s time to think about a separate flowchart to continue or extend the one you are working on. There are ways to indicate the connection between pages. You can also show a section of a flowchart as a generalization and show a more refined flowchart on a separate pages using references.</p>
<p>I won’t go into the details of how to do that here, as this article is long enough as it is. And in this case, I think we can keep our flowchart to just one page, so I won’t go further with creating new pages for it.</p>
<p>So we are done!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>When making a flowchart, we are not looking to imitate our code. Rather, we’re looking to <em>understand it</em>. This means that the flowchart has to be <em>clear</em>.</p>
<p>And if you use your flowcharts correctly, along with the right tools, they can help you reveal patterns and hidden operations, as well as stay organized, reduce overwhelm, and ultimately make coding feel more manageable. This will ultimately improve your coding skills and your state of mind.</p>
<p>So give flowcharts a try — you might be surprised at how much they can help you out.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
