Dashboard Temp Share Shortlinks Frames API

HTMLify

data-structures-and-algorithms-visualization.html
Views: 14 | Author: cody
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
<!DOCTYPE html>
<html lang="en" dir="ltr" data-cast-api-enabled="true">
  <head>
    <!-- META -->
    <meta charset="UTF-8">
    <meta http-equiv="Content-Language" content="en">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- Primary Meta Tags -->
    <title>Data Structures and Algorithms Visualizer Project Walkthrough</title>
    <meta name="title" content="Data Structures and Algorithms Visualizer Project Walkthrough">
    <meta name="author" content="Jacob Grisham">
    <meta name="keywords" content="Jacob,Grisham,Jacob Grisham,Data Structures and Algorithms Visualizer,Data Structures,Algorithms">
    <meta name="description" content="Walkthrough of my project Data Structures and Algorithms Visualizer. Data Structures and Algorithms Visualizer is a front-end web app built with React, Typescript, D3.js, CSS Modules, Sass, CSS and hosted on Netlify. The main feature is the ability to visualize the following algorithms in real-time: Linear Search, Binary Search, Bubble Sort, Selection Sort, Merge Sort, and Insertion Sort.">

    <!-- Open Graph / Facebook -->
    <meta property="og:locale" content="en_US">
    <meta property="og:type" content="website">
    <meta property="og:url" content="https://www.jacobgrisham.com/">
    <meta property="og:title" content="Data Structures and Algorithms Visualizer Project Walkthrough">
    <meta property="og:site_name" content="Jacob Grisham Professional Portfolio">
    <meta property="og:image" content="https://www.jacobgrisham.com/img/thumbnail.png">
    <meta property="og:image:secure_url" content="https://www.jacobgrisham.com/img/thumbnail.png">
    <meta property="og:image:type" content="image/png">
    <meta property="og:image:height" content="630">
    <meta property="og:image:width" content="1200">
    <meta property="og:image:alt" content="Data Structures and Algorithms Visualizer">
    <meta property="og:description" content="Walkthrough of my project Data Structures and Algorithms Visualizer. Data Structures and Algorithms Visualizer is a front-end web app built with React, Typescript, D3.js, CSS Modules, Sass, CSS and hosted on Netlify. The main feature is the ability to visualize the following algorithms in real-time: Linear Search, Binary Search, Bubble Sort, Selection Sort, Merge Sort, and Insertion Sort." name="description">
    <meta property="fb:app_id" content="2733409333567092">

    <!-- Twitter Meta Tags -->
    <meta property="twitter:card" content="summary_large_image">
    <meta property="twitter:url" content="https://www.jacobgrisham.com/">
    <meta property="twitter:title" content="Data Structures and Algorithms Visualizer Project Walkthrough">
    <meta property="twitter:description" content="Walkthrough of my project Data Structures and Algorithms Visualizer. Data Structures and Algorithms Visualizer is a front-end web app built with React, Typescript, D3.js, CSS Modules, Sass, CSS and hosted on Netlify. The main feature is the ability to visualize the following algorithms in real-time: Linear Search, Binary Search, Bubble Sort, Selection Sort, Merge Sort, and Insertion Sort.">
    <meta property="twitter:image" content="https://www.jacobgrisham.com/img/thumbnail.png">

    <!-- SEO -->
    <link rel="canonical" href="https://www.jacobgrisham.com/pages/projects/data-structures-and-algorithms-visualization.html">

    <!-- FONTS -->
    <link href="https://fonts.googleapis.com/css2?&family=Montserrat:wght@100;200;300&family=Nunito+Sans:wght@200;300;400&family=PT+Mono&display=swap" rel="stylesheet">

    <!-- CSS -->
    <link rel="stylesheet" href="../css/style.css">
    <!-- Include this second link for production -->
    <link rel="text/css" href="../css/style.css">

    <!-- FAVICON -->
    <link rel="icon" href="../favicon.ico" type="image/x-icon">
    <link rel="shortcut icon" href="../favicon.ico">
    <link rel="apple-touch-icon" sizes="180x180" href="../favicon_io/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="../favicon_io/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="../favicon_io/favicon-16x16.png">
    <link rel="manifest" href="../site.webmanifest">
    </head>
  <body class="projects-body">
    <!-- Loader -->
    <div class="laptop loader">
      <svg class="laptop__svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 79.375 79.375" height="300" width="300">
        <g transform="translate(-2.22 3.222)">
          <g transform="translate(-335.788 -22.347) scale(.39771)">
            <rect fill="#b3b3b3" width="137.583" height="89.958" x="880.884" y="99.204" ry="2.022"/>
            <rect y="100.527" x="882.207" height="87.313" width="134.938" ry="2.134" rx="0"/>
            <path d="M886.175 104.496h127v79.375h-127z" fill="#4d4d4d"/>
            <rect fill="#333" width="29.788" height="70.68" x="891.36" y="113.22" ry="0" rx="0"/>
          </g>
          <path d="M16.674 20.813h50.597v.317H16.674zM30.53 24.5h36.617v15.488H30.529zm0-1.555h9.184V24.5H30.53z" fill="#1a1a1a"/>
          <path d="M30.53 22.69h9.183v.255H30.53z" fill="#003380"/>
          <rect fill="#2c5aa0" width="6.399" height=".455" x="32.113" y="23.546" ry=".227"/>
          <path d="M30.534 41.82h36.645v8.972H30.534zm-.005-1.557h9.184v1.555H30.53z" fill="#1a1a1a"/>
          <path d="M30.53 40.007h9.183v.256H30.53z" fill="#003380"/>
          <rect fill="#2c5aa0" ry=".227" y="40.793" x="32.089" height=".455" width="6.399"/>
          <g transform="translate(-19.725 -1.116) scale(.39771)" fill="#ccc">
            <rect ry=".767" y="62.346" x="99.493" height="1.535" width="14.902"/>
            <rect width="14.902" height="1.535" x="103.298" y="65.818" ry=".767"/>
            <rect width="16.379" height="1.535" x="106.895" y="69.291" ry=".767"/>
            <rect width="11.497" height="1.535" x="106.959" y="72.763" ry=".767"/>
            <rect ry=".767" y="76.235" x="107.055" height="1.535" width="11.497"/>
            <rect ry=".767" y="79.707" x="106.927" height="1.535" width="11.497"/>
            <rect ry=".767" y="83.179" x="102.833" height="1.535" width="16.379"/>
            <rect ry=".767" y="86.651" x="102.746" height="1.535" width="13.001"/>
            <rect ry=".767" y="90.123" x="106.991" height="1.535" width="16.379"/>
            <rect ry=".767" y="93.595" x="107.338" height="1.535" width="9.882"/>
            <rect ry=".767" y="97.067" x="100.024" height="1.535" width="16.379"/>
            <rect ry=".767" y="100.539" x="100.196" height="1.535" width="12.74"/>
            <rect ry=".767" y="104.011" x="100.379" height="1.535" width="12.44"/>
          </g>
          <g transform="translate(-411.355 -23.965) scale(.39771)">
            <rect fill="#ccc" ry=".887" y="193.745" x="1056.522" height="4.151" width="166.317"/>
            <path fill="#999" d="M1222.19 197.896h-165.048l4.029 2.723h156.468z"/>
          </g>
          <rect fill="#b3b3b3" ry=".4" y="53.067" x="38.233" height=".801" width="7.35"/>
          <rect fill="#999" ry=".4" y="43.091" x="31.651" height=".801" width="10.779"/>
          <rect fill="#999" width="10.779" height=".801" x="31.651" y="45.052" ry=".4"/>
          <rect fill="#999" width="10.779" height=".801" x="31.651" y="47.013" ry=".4"/>
          <rect fill="#999" width="10.779" height=".801" x="31.651" y="48.975" ry=".4"/>
          <rect fill="#999" ry=".051" y="49.718" x="43.875" height=".103" width="1.511"/>
          <rect fill="#999" width="5.07" height=".801" x="43.661" y="43.181" ry=".4"/>
          <rect fill="#999" width="13.784" height=".801" x="43.683" y="45.152" ry=".4"/>
          <rect fill="#999" width="10.779" height=".801" x="43.703" y="46.958" ry=".4"/>
          <rect fill="#c83737" width="4.572" height=".61" x="31.725" y="25.832" ry=".305"/>
          <rect fill="#fd5" width="8.157" height=".61" x="37.883" y="25.823" ry=".305"/>
          <rect fill="#fd5" ry=".305" y="27.46" x="37.922" height=".61" width="10.535"/>
          <rect fill="#fd5" ry=".305" y="29.214" x="37.922" height=".61" width="6.053"/>
          <rect fill="#999" width="10.779" height=".801" x="31.751" y="30.95" ry=".4"/>
          <rect fill="#ccc" ry=".325" y="32.771" x="31.771" height=".649" width="3.93"/>
          <rect fill="#c83737" ry=".305" y="32.771" x="36.627" height=".61" width="4.572"/>
          <rect fill="#5fbcd3" width="6.053" height=".61" x="42.045" y="32.731" ry=".305"/>
          <rect fill="#ccc" width="3.93" height=".649" x="48.951" y="32.672" ry=".325"/>
          <rect class="code" id="code-8" fill="#fd5" width="6.053" height=".61" x="35.771" y="34.449" ry=".305" />
          <rect class="code" id="code-7" fill="#5fbcd3" ry=".305" y="34.5" x="42.27" height=".61" width="9.509" />
          <rect class="code" id="code-6" fill="#ccc" ry=".325" y="36.08" x="38.948" height=".649" width="3.93" />
          <rect class="code" id="code-5" fill="#37c871" ry=".325" y="36.08" x="44.106" height=".649" width="2.847" />
          <rect class="code" id="code-4" fill="#37c871" ry=".325" y="36.131" x="47.923" height=".649" width="2.692" />
          <rect class="code" id="code-3" fill="#5fbcd3" ry=".325" y="36.131" x="51.585" height=".649" width="6.097" />
          <rect class="code" id="code-2" fill="#ccc" width="3.93" height=".649" x="35.904" y="37.834" ry=".325" />
          <rect class="code" id="code-1" fill="#c83737" width="7.203" height=".61" x="41.102" y="37.905" ry=".305" />
        </g>
      </svg>
    </div>

    <div class="projects-body__focus-container">
      <!-- HEADER -->
      <section>
        <h1 class="projects-body__main-heading">Data Structures and Algorithms Visualizer Project Walkthrough</h1>
        <h2 class="blog-body__sub-heading">December 2020 - January 2021</h2>
    
        <h2 class="projects-body__heading">Source Code
          <span>
            <a href="https://github.com/JacobGrisham/Data-Structures-and-Algorithms-Visualizer" aria-label="link to Data Structures and Algorithms Visualizer source code" target="_blank" rel="noopener noreferrer">
              <svg class="skills-box__header-icon">
                <use xlink:href="../img/sprite.svg#icon-github"></use>
              </svg>
            </a>
          </span>
        </h2>

        <div>
          <img src="../img/DSAMetaImage-min.png" class="projects-body__image lax"></img>
        </div>
      </section>
  
      <!-- ABOUT -->
      <section>
        <h2 class="projects-body__heading">About</h2>
        <p>Originally a final project from CS50, where we were tasked to build web application using Flask, HTML, and CSS. Built an application based on algorithms to continue to learn, understand, and practice algorithmic programming. Furthermore, chose to visualize the algorithms to gain an even deeper understanding how the algorithms work and to make the application interactive. The core of the application was built from December 2020 - January 2021, with sporadic updates up until July 2021.</p>
      </section>
  
      <!-- PRODUCT FEATURES AND SPECIFICATIONS -->
      <section>
        <h2 class="projects-body__heading">Product Features and Specifications</h2>
        <ul class="projects-body__list">
          <li>Visualize Linear Search, Binary Search, Bubble Sort, Selection Sort, Merge Sort, and Insertion Sort</li>
          <li>Random numbers in an array are graphed as a bar chart</li>
          <li>The values of the array are displayed and updated in an HTML table below the bar chart</li>
          <li>They are also accessible through a tooltip that displays the value when hovered over</li>
          <li>The Javascript Execution times are logged in cards to allow comparison of different algorithm runtimes and for further information on the Big-O</li>
        </ul>
      </section>
  
      <!-- TECHONOLOGIES -->
      <section class="technologies">
        <h2 class="projects-body__heading technologies__header">Technologies</h2>
        <div class="skills-box__no-shadow">
          <h4 class="skills-box__header">
            <svg class="skills-box__header-icon">
              <use xlink:href="../img/sprite.svg#icon-embed2"></use>
            </svg>
            Front-End
          </h4>
          <ul class="skills-box__list">
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-react"></use>
              </svg>
              React
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-typescript"></use>
              </svg>
              Typescript
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-javascript"></use>
              </svg>
              Javascript ES6+
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-d3-dot-js"></use>
              </svg>
              D3.js
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-css-modules"></use>
              </svg>
              CSS Modules
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-sass"></use>
              </svg>
              Sass
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-css3"></use>
              </svg>
              CSS
            </li>
          </ul>
        </div>

        <!-- DEVELOPMENT -->
        <div class="skills-box__no-shadow">
          <h4 class="skills-box__header">
            <svg class="skills-box__header-icon">
              <use xlink:href="../img/sprite.svg#icon-cogs"></use>
            </svg>
            Development
          </h4>
          <ul class="skills-box__list">
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-git"></use>
              </svg>
              Git
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-github"></use>
              </svg>
              GitHub
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-codacy"></use>
              </svg>
              Codacy
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-codeclimate"></use>
              </svg>
              CodeClimate
            </li>
          </ul>
        </div>
    
        <!-- PRODUCTION -->
        <div class="skills-box__no-shadow">
          <h4 class="skills-box__header">
            <svg class="skills-box__header-icon">
              <use xlink:href="../img/sprite.svg#icon-cloud-upload"></use>
            </svg>
            Production
          </h4>
          <ul class="skills-box__list">
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-netlify"></use>
              </svg>
              Netlify
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-google-domains"></use>
              </svg>
              Google Domains
            </li>
            <li class="skills-box__item">
              <svg class="skills-box__icon">
                <use xlink:href="../img/sprite.svg#icon-google-analytics"></use>
              </svg>
              Google Analytics
            </li>
          </ul>
        </div>
      </section>

      <!-- UX/UI MOCKS AND GRAPHIC DESIGN -->
      <section>
        <h2 class="projects-body__heading">UX/UI Mocks and Graphic Design</h2>
        <p><a href="https://xd.adobe.com/view/f1625089-b481-4bd9-ba1f-37153debea1c-a431/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Created prototype in AdobeXD</a> to prevent wasted engineering time, to practice UX/UI design, and to practice building from a UX/UI design specification. Below is an AdobeXD interactive wireframe mock for the mobile view. Start scrolling through and click on the screen to see hints where you should click next (highlighted in blue).</p>
        <div class="adobexd">
          <img src="../img/iPhone.svg" alt="iPhone" class="adobexd--iphone">
          <iframe src="https://xd.adobe.com/embed/7f4daf4a-42f4-4149-bb85-025696895860-2a1e/" frameborder="0" allowfullscreen class="adobexd--iphone--mock"></iframe>
        </div>
        <p><a href="https://xd.adobe.com/view/7f4daf4a-42f4-4149-bb85-025696895860-2a1e/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Wireframed website with a Mobile-first design</a> as practice for implementing the industry-standard principle. Below is an AdobeXD interactive wireframe mock for the desktop view. Start scrolling through and click on the screen to see hints where you should click next (highlighted in blue).</p>
        <div class="adobexd">
          <img src="../img/MacBook-Pro.svg" alt="MacBook Pro" class="adobexd--macbook">
          <iframe src="https://xd.adobe.com/embed/f1625089-b481-4bd9-ba1f-37153debea1c-a431/" frameborder="0" allowfullscreen class="adobexd--macbook--mock"></iframe>
        </div>
      </section>

      <!-- DESIGN AND ARCHITECTURE -->
      <section>
        <h2 class="projects-body__heading">Design and Architecture</h2>
        <p class="projects-body__paragraph-spacing-below">D3 Library for data visualization because D3 is the ideal solution for data visualization problems and to challenge myself with learning a new framework.</p>
        <p class="projects-body__paragraph-spacing-below">Initially built this application with a backend server using the Python framework, Flask, which was primarily used for its <a href="https://jinja.palletsprojects.com/en/3.0.x/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Jinja</a> templating capabilities. The application was hosted on the <a href="https://devcenter.heroku.com/articles/free-dyno-hours" class="curriculum__link" target="_blank" rel="noopener noreferrer">free tier plan on Heroku</a>, alongside two other application using the free tier plan. The main problem with this approach was that it was both heavy and expensive. It was heavy in that Jinja wasn't strictly neccessary to achieve templating. It was expensive in that the free tier plan on Heroku put the app to sleep after 30 minutes. Furthermore, using <a href="https://kaffeine.herokuapp.com/" class="curriculum__link" target="_blank" rel="noopener noreferrer">kaffeine</a> to circumvent sleeping caused the free dyno minutes to expire by the 24th of each month. Therefore, after learning about React and the <a href="https://jamstack.org/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Jamstack</a>, I put the two together and refactored this application by migrating from a server-based architecture with Flask to a static website architecture with <a href="https://create-react-app.dev/docs/making-a-progressive-web-app/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Create-React-App Typescript Progressive Web App (PWA)</a>, and by switching cloud-hosting providers from Heroku to Netlify. The code is more simple with React doing all the work and more secure with being statically typed with Typescript. The website has better performance, offline capability, and 100% uptime as a PWA.</p>
        <p class="projects-body__paragraph-spacing-below">Initially all the javascript for controlling 95% of the application was stored in one file. Refactoring the application with React opened the opporunity to use split the logic into modular chunks that live in their own files. Now React components only load the logic that they need and the code-splitting enables more organized code.</p>
        <p>Initially syled with Bootstrap 4 to quickly style the application and to shift focus towards spending more time on the data visualization and underlying algorithms. After shipping the minimum viable product to production, went back and refactored the frontend with <a href="https://glenmaddern.com/articles/css-modules" class="curriculum__link" target="_blank" rel="noopener noreferrer">CSS Modules</a> and <a href="https://sass-lang.com/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Sass</a> since the file size and load-time of Bootstrap was expensive relative to how much I was using it the website. I used less than 10 Boostrap classes. There are a number of benefits of using CSS Modules and Sass. Similar to the point above, CSS Modules allows React components to only load the resources, in this case styling, that they need, <em>and</em> CSS Modules promotes code-splitting enables more organized code. Sass, compared to vanilla CSS, allows nesting and variable definitions. Now the code is modular and more DRY. However, I noticed that CSS Modules isn't compatible with D3 since D3 doesn't have access to the hashed classnames generated by CSS Modules. Therefore, I included one vanilla CSS file referenced at the root of the application for D3 to have constant access to.</p>
      </section>

      <!-- PRODUCTION METRICS -->
      <section>
        <h2>Production System Cost</h2>
        <ul class="projects-body__list">
          <li>Netlify Starter Plan: free</li>
          <li>Google Domain for big-o.app: $14/year</li>
          <li>GitHub Free Tier: free</li>
        </ul>
        <h2 class="projects-body__heading">Production Metrics</h2>
        <ul class="projects-body__list">
          <li><span class="projects-body__bold-text">Traffic</span>: 180+ total website visits since launch</li>
          <li><span class="projects-body__bold-text">Site Reliability</span>: 100% uptime service-level indicator (SLI) and available even when internet is disconnected thanks to Progressive Web App features</li>
          <li><span class="projects-body__bold-text">Security</span>: Mozzila Observatory</li>
          <li><span class="projects-body__bold-text">Performance</span>: from Google Lighthouse</li>
          <li><span class="projects-body__bold-text">Accessibility</span>: from Google Lighthouse</li>
          <li><span class="projects-body__bold-text">Cross-Browser Compatibility</span>: from LambdaTest</li>
        </ul>
      </section>

      <!-- LESSONS LEARNED -->
      <section>
        <h2 class="projects-body__heading">Lessons Learned</h2>
        <ul class="projects-body__list">
          <li>Searching and Sorting Algorithms</li>
          <li>Asynchronous Javascript</li>
          <li><a hre="https://d3js.org/" aria-label="D3" class="curriculum__link" target="_blank" rel="noopener noreferrer">D3.js</a> Data Visualization</li>
          <li>Before Refactor</li>
          <ul class="projects-body__list">
            <li>Hosting <a href="https://flask.palletsprojects.com/en/2.0.x/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Flask</a> backend server on <a href="https://www.heroku.com/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Heroku</a></li>
            <li>Continuous Integration and Continuous Deployment to Heroku with <a href="https://circleci.com/" class="curriculum__link" target="_blank" rel="noopener noreferrer">circleci</a></li>
            <li>Bootstrap 4 for styling</li>
          </ul>
          <li>During Refactor</li>
          <ul class="projects-body__list">
            <li>Refactored applciation as a <a href="https://create-react-app.dev/docs/making-a-progressive-web-app/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Create-React-App Typescript Progressive Web App (PWA)</a></li>
            <li>Integrating D3 with React</li>
            <li>Refactored application with <a href="https://glenmaddern.com/articles/css-modules" class="curriculum__link" rel="noopener noreferrer">CSS Modules</a> and <a href="https://sass-lang.com/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Sass</a> styling</li>
            <li><a href="https://www.netlify.com/" class="curriculum__link">Netlify</a> to host a static <a href="https://jamstack.org/" class="curriculum__link" target="_blank" rel="noopener noreferrer">Jamstack</a> website</li>
          </ul>
        </ul>
      </section>
    </div>

    <!-- FOOTER -->
    <footer class="footer">
      <p class="footer__fun-note">Made with<svg class="footer__icon"><use xlink:href="../img/sprite.svg#icon-heart"></use></svg>in SF</p>
      <p>Copyright &copy; <time id="date"></time> by Jacob Grisham</p>
    </footer>

  <!-- JAVASCRIPT -->
  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=G-SV51NLJS21"></script>
  <script type="text/javascript" src="../js/common.js"></script>
  </body>
</html>