<?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" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://blog.raisaugat.com.np</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 07:12:39 GMT</lastBuildDate><atom:link href="https://blog.raisaugat.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to implement percent in gradient bar in React]]></title><description><![CDATA[In this article, we'll be creating a gradient bar that will show the percentage in React. There might be many packages that will be helpful in this scenario but the fun is when you can make it work from scratch. So let's begin.
Here is the demo link....]]></description><link>https://blog.raisaugat.com.np/how-to-implement-percent-in-gradient-bar-in-react</link><guid isPermaLink="true">https://blog.raisaugat.com.np/how-to-implement-percent-in-gradient-bar-in-react</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[CSS]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[SaugatRai]]></dc:creator><pubDate>Tue, 14 Mar 2023 09:23:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1678769717668/d613d587-88b8-4b79-afb5-12fbbad4865e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we'll be creating a gradient bar that will show the percentage in React. There might be many packages that will be helpful in this scenario but the fun is when you can make it work from scratch. So let's begin.</p>
<p>Here is the <a target="_blank" href="https://codesandbox.io/s/gradient-percent-bar-548d39">demo</a> link.</p>
<h3 id="heading-challenge">Challenge</h3>
<p>Creating a bar is easy unless there are no segments. But since we are creating a segmented bar, we need to take care of segments beforehand.</p>
<p>For this, we need a variable to store the number of segments. Let's say</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> BAR_COUNT = <span class="hljs-number">7</span>;
</code></pre>
<p>We are assuming there will be 7 segments of the bar but you can make more segments. The only constraint here is the color of each segment because for now, the 7 colors are hard-coded.</p>
<h3 id="heading-initialization">Initialization</h3>
<p>So a full bar is 100%. But since we have segments we also have to know how much percent will a segment hold. To determine this we can divide 100% by the total number of segments.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> quartilePercentage = <span class="hljs-number">100</span> / BAR_COUNT;
</code></pre>
<p>Since we have 7 segments, the percentage each bar will hold is 14.28%</p>
<p><em>100 / 7 = 14.28</em></p>
<p>This percentage will be handy when filling the bar with color later.</p>
<p>And since we need an actual percentage to show on the bar, we will pass them as props.</p>
<pre><code class="lang-typescript">&lt;GradientPercentBar percent={<span class="hljs-number">40</span>} /&gt;
</code></pre>
<p>We will use this percentage and assign it to a variable inside the component which will restrict the percentage to be maximum of 100.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> truePercent = percent &gt; <span class="hljs-number">100</span> ? <span class="hljs-number">100</span> : percent &lt; <span class="hljs-number">0</span> ? <span class="hljs-number">0</span> : percent;
</code></pre>
<p>We will also want to know where the percentage will fall and based on that we will assign a color. To figure out whether the label will be low, medium or high, we will divide the <code>truePercent</code> with the <code>quartilePercentage</code> we initialize earlier.</p>
<p><em>If truePercent = 40, the barIndicator will be 40/14.28 = 2.80 ~ 3.</em></p>
<p>Thus the <code>potentialLabel</code> is <strong>medium</strong>. So the bar will fall on 3rd segment</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> barIndicator = <span class="hljs-built_in">Math</span>.round(truePercent / quartilePercentage);

<span class="hljs-keyword">const</span> potentialLabel = barIndicator &lt; <span class="hljs-number">3</span> ? <span class="hljs-string">'low'</span> : barIndicator &lt;= <span class="hljs-number">5</span> ? <span class="hljs-string">'medium'</span> : <span class="hljs-string">'high'</span>;
</code></pre>
<h3 id="heading-indicator">Indicator</h3>
<p>We will create a simple indicator that will render the true percentage and the class will depend on the <code>potentialLabel</code>. We will get back to this function in a while.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">const</span> renderTooltip = useCallback(
    <span class="hljs-function">(<span class="hljs-params">potential: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> (
        &lt;div className={<span class="hljs-string">`indicator <span class="hljs-subst">${potential}</span>`</span>}&gt;
          &lt;span&gt;{truePercent}&lt;/span&gt;
        &lt;/div&gt;
      );
    },
    [truePercent]
  );
</code></pre>
<h3 id="heading-magic-function">Magic Function</h3>
<p>This function will be responsible for creating the bar hence the magic function.</p>
<p>Some variables initialization that we will be needing later.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> elementArr = [];
<span class="hljs-keyword">let</span> root = <span class="hljs-built_in">document</span>.documentElement;
<span class="hljs-keyword">let</span> percent;
<span class="hljs-keyword">let</span> quartileValue;
</code></pre>
<p>We will now loop through <code>BAR_COUNT</code> with starting index of 1 and with each iteration, we will assign the range of each bar.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> currentPoint = <span class="hljs-built_in">Math</span>.round(quartilePercentage * i);
</code></pre>
<p>This will provide us with the value each bar will have. For example</p>
<blockquote>
<p>In 1st iteration, i = 1 and (1 * 14.28) ~= 14</p>
<p>In 2nd iteration, i =2 and (2* 14.28) ~= 29</p>
<p>..</p>
<p>..</p>
<p>In 7th iteration, i = 7 and (7 * 14.28) ~= 100</p>
</blockquote>
<p>In this example, we have our <code>truePercent</code> value of 40, so all the bars below 40 should be filled. This will be done by pushing the element <code>elementArr</code> array.</p>
<pre><code class="lang-typescript">elementArr.push(&lt;div className=<span class="hljs-string">'item filled'</span> key={i} /&gt;);
</code></pre>
<p>But all the points above will have further calculations to determine what elements to push in <code>elementArr</code><strong>.</strong></p>
<p>Now we calculate the percentage that will be used to fill the bar with gradient color. If you are not familiar with CSS, we can use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-image">background-image</a> to generate a linear effect to show half filled and half-empty.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> previousPoint = <span class="hljs-built_in">Math</span>.round(quartilePercentage * (i - <span class="hljs-number">1</span>));

 <span class="hljs-keyword">const</span> difference = currentPoint - previousPoint;

 percent = <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">Math</span>.round(((truePercent - previousPoint) / difference) * <span class="hljs-number">100</span>)}</span>%`</span>;
</code></pre>
<p>We know that the <code>truePercent</code> lies in 3rd segment. But it will not fill to 3rd segment. Some of them will be half empty. Thus the above calculation comes in handy.</p>
<p>The above percentage will be</p>
<blockquote>
<p>((40- 29)/14) * 100 = 78.57 ~= 79</p>
</blockquote>
<p>This means the color will be filled up to 79% of 3rd segment and the rest will be white.</p>
<p>Now we have all the values required to implement the bar, we just need to push it into <code>elementArr</code><strong>.</strong></p>
<pre><code class="lang-typescript"> elementArr.push(
        &lt;div className={<span class="hljs-string">`item <span class="hljs-subst">${i === quartileValue ? <span class="hljs-string">'current filled'</span>               : <span class="hljs-string">''</span>}</span>`</span>} key={i}&gt;
            {i === quartileValue &amp;&amp; renderTooltip(potentialLabel)}
          &lt;/div&gt;
 );
</code></pre>
<p>After all the iterations, the elements will be pushed into <code>elementArr</code><strong>.</strong></p>
<p>Some code looks like this.</p>
<pre><code class="lang-typescript">root.style.setProperty(<span class="hljs-string">`--block-<span class="hljs-subst">${i}</span>`</span>, percent);
root.style.setProperty(<span class="hljs-string">`--left-value`</span>, percent);
</code></pre>
<p>These are used to set CSS variables that will be used CSS.</p>
<p>The <code>--block-${i}</code> is used in linear gradient while the <code>--left-value</code> is used to indicate how far the indicator is from the block.</p>
<h3 id="heading-final-structure">Final Structure</h3>
<p>The return function for the bar component is simple. It will call <code>rangeArray</code> function which will be responsible for generating the bar.</p>
<pre><code class="lang-typescript">    &lt;div className=<span class="hljs-string">'App'</span>&gt;
      &lt;div className=<span class="hljs-string">'potential__range'</span>&gt;
        &lt;div className=<span class="hljs-string">'range'</span>&gt;{rangeArray}&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
</code></pre>
<p>There is further CSS required to color the bar but the major functionality for the bar is done.</p>
<p>Hope this tutorial will be useful for some of you.</p>
]]></content:encoded></item></channel></rss>