Cross over between UX Design & Front-end Development using the ORCA Process
Tags: ux, design, webdev, tailwindcss
Published: 2021-07-09 18:21:31

<!-- wp:paragraph -->
<p>I challenged myself to make a little Mars weather app using <a href="https://api.nasa.gov/">NASA's Insight Weather API</a>. As with most things I started pulling out all the docs and information to get my mind wrapped around what I was getting from the API to work with. And after looking at the docs for a bit I realized that one of the best ways for me to get my mind wrapped around the data was to apply the <a href="https://www.objectorientedux.com/">ORCA process</a> I've been learning. </p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":20} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2>Discovery</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In these first two images,  you can see how I used the ORCA process to identify potential content and data from existing weather applications. I also took note of some cool UI that might translate well to my mars app like the gradient slider for AIR Quality could easily become a slider for Atmospheric Opacity. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":4007,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.45.00-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.45.00-PM-1024x560.png" alt="" class="wp-image-4007"/></a><figcaption>Existing Earth Weather Application UI Research</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"id":4008,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.46.17-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.46.17-PM-1024x628.png" alt="" class="wp-image-4008"/></a><figcaption>Existing Earth Application UI research</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>These two activities I was working on plug into each other so well. To give you a very brief overview the <a href="https://www.objectorientedux.com/">ORCA process</a> takes you through several activities that help you define the Objects of your user's mental modal which might be represented in the system. How all those objects you defined are related to each other by defining their relationships, what users can do to act upon those objects by defining Calls-to-Action, and exploring those objects in great detail to define the Attributes of those objects. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Since I was working directly with an API was able to include that in my discovery process as well. I'm taking the data from NASA and turning it into a JSON object guess what?? It's organized as objects. Now I'm able to see and document what data I can get from this API and what its limitations are. This will also give me a jumping-off point for thinking about other APIs that I could potentially explore, the next image is a snapshot of the data coming back. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":3950,"width":390,"height":301,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://michaelahoffman.com/wp-content/uploads/2021/04/image-3.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/04/image-3.png" alt="" class="wp-image-3950" width="390" height="301"/></a><figcaption>InSight Weather API </figcaption></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>With this particular API, I'm only getting high-quality data which meant I may need to plan for missing content and attributes on any given sol (Martian Day). </p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":20} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2>Relationships</h2>
<!-- /wp:heading -->

<!-- wp:image {"id":4009,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.48.17-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-2.48.17-PM-1024x721.png" alt="" class="wp-image-4009"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>As part of Relationship discovery in the ORCA process, you make a little system model to start thinking about how the objects in your data set relates to each other. This was also something that the API was really helpful with. I had assumed, incorrectly, that the API would return one data point for the temperature for each Sol (Martian Day) but because I was working with an API I was able to see I would get at least 18 data points for temperature each Sol if the Sol passed the validity check.  </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Next, I translated my objects into an object map where I also added in all the attributes the API was going to return for me. Now onto translating this into UI and a functioning web app. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":4011,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.00.54-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.00.54-PM-690x1024.png" alt="" class="wp-image-4011"/></a></figure></div>
<!-- /wp:image -->

<!-- wp:heading -->
<h2>Translating the Objects &amp; Relationships to the UI</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As I move from low-fidelity to higher fidelity through this process I build on what I've created before. Before I dig into the UI elements of the design I move through making some sketches of the objects. And through this process I'm figuring out how I want this data to display consistently to avoid shapeshifting. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"align":"center","id":4013,"sizeSlug":"large","linkDestination":"media"} -->
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.36.48-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.36.48-PM-491x1024.png" alt="" class="wp-image-4013"/></a></figure></div>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>As an example, I sketched out a Sol mini card with just a few of the attributes from my map. Once I get to the grid card I added a few more attributes in, as well as, explored some UI elements like using an icon for representing atmospheric opacity. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":4016,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.42.40-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.42.40-PM-1024x718.png" alt="" class="wp-image-4016"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Now I've moved into the next level of fidelity but you can see how I'm using my object cards to create the UI for the application. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":4015,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.41.28-PM.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-21-at-3.41.28-PM-1024x655.png" alt="" class="wp-image-4015"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>A a part of this project I wanted to take a peek at <a href="https://tailwindcss.com/">Tailwind CSS</a> and get the chance to work with that framework. I typically have worked with Bootstrap in the past and haven't gotten many chances to try other frameworks other than in my personal projects. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Well, that looks nice to start with. I've got more fun stuff with the UI in mind based on what the data points are saying but that will be more fun when it's dynamic and not a static image. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Speaking of that onto making it function and replacing the placeholder data with the real data from the API. </p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":20} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2>Moving into Functionality</h2>
<!-- /wp:heading -->

<!-- wp:image {"id":3966,"sizeSlug":"large","linkDestination":"media"} -->
<figure class="wp-block-image size-large"><a href="https://michaelahoffman.com/wp-content/uploads/2021/04/image-5.png"><img src="https://michaelahoffman.com/wp-content/uploads/2021/04/image-5-1024x488.png" alt="" class="wp-image-3966"/></a></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Remember earlier in this conversation I said I'm getting only high quality data? As it turns out the API is not returning as much weather data as it could. Because of this most of my data points would end up reading No Data like in the screenshot above. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>What a bummer. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Beyond realizing the data would be mostly empty most of the time and I would never be able to implement a search with the existing API. I got to work with the sort &amp; find methods in this little project to bring back and display the most recent date separately from the rest of the days in my UI.  </p>
<!-- /wp:paragraph -->

<!-- wp:spacer {"height":20} -->
<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- /wp:spacer -->

<!-- wp:heading -->
<h2>A peek at the Code</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>First I assigned the sol number to the sol as an id and converted the result into an integer. </p>
<!-- /wp:paragraph -->

<!-- wp:prismatic/blocks -->
<pre class="wp-block-prismatic-blocks"><code class="language-">constructor(data: IWeather) {
    const sols = data.sol_keys.map((k) => {
      const sol: ISol = data[k];
      sol.id = parseInt(k);
      return sol;
    }); </code></pre>
<!-- /wp:prismatic/blocks -->

<!-- wp:paragraph -->
<p>Now that I'm returning an integer I run that through the sort method to get an ordered array based on the sol id descending. </p>
<!-- /wp:paragraph -->

<!-- wp:prismatic/blocks -->
<pre class="wp-block-prismatic-blocks"><code class="language-">const first = sols
      .sort((a: ISol, b: ISol) => b.id - a.id)

// [858, 856, 855, 854]</code></pre>
<!-- /wp:prismatic/blocks -->

<!-- wp:paragraph -->
<p>Looking good, now I used the find method to get the first result in the array which happens to be the largest one since the sorted array is in descending order.</p>
<!-- /wp:paragraph -->

<!-- wp:prismatic/blocks -->
<pre class="wp-block-prismatic-blocks"><code class="language-">const first = sols
      .sort((a: ISol, b: ISol) => b.id - a.id)
      .find((x: ISol) => true);</code></pre>
<!-- /wp:prismatic/blocks -->

<!-- wp:paragraph -->
<p>Once I have that I'm able to assign the result to the primarySol... properties of my class for the WeeklyWeather. Below you can see the final result. </p>
<!-- /wp:paragraph -->

<!-- wp:prismatic/blocks -->
<pre class="wp-block-prismatic-blocks"><code class="language-">&lt;pre>export class WeeklyWeather {
  primarySolNumber: number;
  primarySolDate: string;
  primarySolSeason: string;
  sol: ISol[];

  constructor(data: IWeather) {
    const sols = data.sol_keys.map((k) => {
      const sol: ISol = data[k];
      sol.id = parseInt(k);
      return sol;
    });

    const first = sols
      .sort((a: ISol, b: ISol) => b.id - a.id)
      .find((x: ISol) => true);

    this.primarySolNumber = first.id;
    this.primarySolDate = first.First_UTC;
    this.primarySolSeason = first.Season;
  }
}
&lt;/pre></code></pre>
<!-- /wp:prismatic/blocks -->

<!-- wp:paragraph -->
<p>Dear NASA, please update your API so that I can pass a quality parameter and get lower quality data. ? This way I can finish out my little project! </p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>It was still really fun to experiment with utilizing the ORCA process on this little personal project. I also had a lot of fun saying things like "I'm receiving telemetry from NASA." And even getting to experiment with another CSS framework was fun and challenging. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can still see my public repo of the fledgling project on <a href="https://github.com/michaelahoffman/mars-weather-app" target="_blank" rel="noreferrer noopener">GitHub</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you want to geek out about space, APIs, UX, the ORCA process or other things you can find me <a href="https://twitter.com/md_hoffman">@md_hoffman</a> on twitter! </p>
<!-- /wp:paragraph -->