<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: karthik-raja-g</title>
    <description>The latest articles on DEV Community by karthik-raja-g (@karthik_raja).</description>
    <link>https://dev.to/karthik_raja</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F597264%2Fbeee6f41-51fb-4d0a-bbe5-65d88d5bc8bf.png</url>
      <title>DEV Community: karthik-raja-g</title>
      <link>https://dev.to/karthik_raja</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karthik_raja"/>
    <language>en</language>
    <item>
      <title>A simple React gauge with  blob</title>
      <dc:creator>karthik-raja-g</dc:creator>
      <pubDate>Wed, 17 Mar 2021 18:23:12 +0000</pubDate>
      <link>https://dev.to/karthik_raja/a-simple-react-gauge-with-blob-1ddf</link>
      <guid>https://dev.to/karthik_raja/a-simple-react-gauge-with-blob-1ddf</guid>
      <description>&lt;h4&gt;
  
  
  A little background
&lt;/h4&gt;

&lt;p&gt;While working I was asked to develop a static gauge like the one below.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33gnv5gkrmqrxkup2x6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33gnv5gkrmqrxkup2x6v.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first I thought I can do this by using some library. So, I started looking for libraries in react. After a few hours of trying a bunch of libraries, I wasn't able to get the gauge exactly as given in the design. Though some came pretty close, there was one big catch in all of them. &lt;strong&gt;The indicator blob&lt;/strong&gt;. I couldn't find a single library that had an indicator blob along the circumference.&lt;/p&gt;

&lt;p&gt;After a few more hours of unsuccessful Googling, I decided to make my own gauge (I had no other way). &lt;/p&gt;

&lt;h3&gt;
  
  
  D3 to the rescue.
&lt;/h3&gt;

&lt;p&gt;Now with different goal, I started searching again and stumbled upon &lt;a href="https://wattenberger.com/blog/gauge" rel="noopener noreferrer"&gt;this&lt;/a&gt; mind blowing blog by Amelia wattenberger. This had everything I needed to make the gauge. She had used D3 library to make a gauge. After going through the blog and getting some basic understanding of SVGs and D3, I finally managed to draw the gauge as per the requirement and I'll be sharing how I did it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before proceeding further, it is MANDATORY to go through Amelia's &lt;a href="https://wattenberger.com/blog/gauge" rel="noopener noreferrer"&gt;blog&lt;/a&gt; first, as the code that I'm about to write is just a tweaked version of Amelia's code. About 80% of the code will be in her blog. I will only include my changes. So, keep this in mind and continue.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Drawing the arcs
&lt;/h4&gt;

&lt;p&gt;Since the gauge is split into 4 parts, we need to draw 4 arcs along the semicircle. We'll be using d3's &lt;code&gt;arc()&lt;/code&gt; function. In gauges, the left and right side values are the minimum and maximum values respectively. This means the the value increases in clockwise direction. In d3, the degree value is measured in Radians. So keeping all these in mind we have to give the &lt;code&gt;startAngle()&lt;/code&gt; and &lt;code&gt;endAngle()&lt;/code&gt; for each arc to complete the semicircle, which has it's range between     -pi/2 (left) to pi/2 (right). &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Red and orange arcs
They come inside the left part (negative) of the semicircle, between     -pi/2 and 0. So the red arc will be between -pi/2 and -pi/4. Orange arc will be between -pi/4 and 0.
```javascript
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;const redArc = arc()&lt;br&gt;
    .innerRadius(1)&lt;br&gt;
    .outerRadius(0.9)&lt;br&gt;
    .startAngle(-Math.PI/2)&lt;br&gt;
    .endAngle(-Math.PI/4)&lt;br&gt;
    .padAngle(0)&lt;br&gt;
    .cornerRadius(2)();&lt;/p&gt;

&lt;p&gt;const orangeArc = arc()&lt;br&gt;
    .innerRadius(1)&lt;br&gt;
    .outerRadius(0.9)&lt;br&gt;
    .startAngle(-Math.PI/4)&lt;br&gt;
    .endAngle(0)&lt;br&gt;
    .padAngle(0)&lt;br&gt;
    .cornerRadius(2)();&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Green and blue arcs
They come inside the right part (positive) of the semicircle, between 0 and pi/2. So the code will be:
```javascript


  const greenArc = arc()
    .innerRadius(1)
    .outerRadius(0.9)
    .startAngle(0)
    .endAngle(Math.PI/4)
    .padAngle(0)
    .cornerRadius(2)();

  const blueArc = arc()
    .innerRadius(1)
    .outerRadius(0.9)
    .startAngle(Math.PI/4)
    .endAngle(Math.PI / 2)
    .padAngle(0)
    .cornerRadius(2)();


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now that we have generated the required path values for the arcs, lets actually draw them.
```javascript
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;return(&lt;br&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
)&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
The above code generates a semicircle like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ed79cogch4iqo8ingoiq.png)

Notice there's no gap between the arcs. To provide this gap, we need to offset the `startAngle` a bit for the orange, green and blue arcs. For me the following offset values gave the best appearance.

orange: -Math.PI/4.15
green: -0.04
blue: Math.PI/4.2

Now we have our main gauge
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/57opdxryltw4n7y411n9.png)

#### Setting up the blob, value and label
The code for the blob, value and label is exactly same as the one in Amelia's blog. Additionally, I changed the blob and value colour based on the arc. This is the only tweak I did. I just created a simple function that returns the colour code based on the value given to the gauge and used it for the blob and value:
```javascript


   const getBlobColor = value =&amp;gt; {
    if (value &amp;gt;= 0 &amp;amp;&amp;amp; value &amp;lt;= 25) return "#e81246";
    if (value &amp;gt; 25 &amp;amp;&amp;amp; value &amp;lt;= 50) return "#ee8d41";
    if (value &amp;gt; 50 &amp;amp;&amp;amp; value &amp;lt;= 75) return "#4dff4d";
    if (value &amp;gt;= 75) return "#2e5bff";
  };


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the code for the final gauge without value and label in the centre:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt; &lt;span class="nx"&gt;viewBox&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;redArc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#e81246&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;orangeArc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#ee8d41&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;greenArc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#4dff4d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;blueArc&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#2e5bff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;circle&lt;/span&gt;
       &lt;span class="nx"&gt;cx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;markerLocation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
       &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;markerLocation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
       &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.07&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="nx"&gt;strokeWidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.04&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
       &lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;getBlobColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
     &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/svg&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is pretty much it. I have only written the changes that I did for my requirement. The main code is in Amelia's blog. Please check that first. &lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

</description>
      <category>react</category>
      <category>d3</category>
      <category>gauge</category>
    </item>
  </channel>
</rss>
