Undefined
Undefined

Reputation: 1021

How to make a semi circle chart in react?

I am having a data like,

  {
    "initial": {
      "unit": "GB",
      "value": 2
    },
    "remaining": {
      "unit": "GB",
      "value": 0.2
    },
    "type": "Internet",
  }

Where the initial value is total gb of mobile data and remaining consists of the remaining data available.

Requirement:

My requirement is like the below image,

enter image description here

I have tried with pure HTML and CSS like here, But issue here is that everything is hard coded .. So if we have some percentage then we need to adjust the css class .sc-percentage accordingly

body { background-color:#555888; font-family:sans-serif; color:#fff; text-align:center }
code { display:inline-block; max-width:600px;  padding:80px 0 0; line-height:1.5; font-family:monospace; color:#ccc }

.sc-gauge  { width:200px; height:200px; margin:200px auto; }
.sc-background { position:relative; height:100px; margin-bottom:10px; background-color:#fff; border-radius:150px 150px 0 0; overflow:hidden; text-align:center; }
.sc-mask { position:absolute; top:20px; right:20px; left:20px; height:80px; background-color:#555888; border-radius:150px 150px 0 0 }
.sc-percentage { position:absolute; top:100px; left:-200%; width:400%; height:400%; margin-left:100px; background-color:#00aeef; }
.sc-percentage { transform:rotate(25deg); transform-origin:top center; }
.sc-min { float:left; }
.sc-max { float:right; }
.sc-value { position:absolute; top:50%; left:0; width:100%;  font-size:48px; font-weight:700 }
<code>

    To change the current value of the Gauge, you need to change 88 to something else in HTML section and update the .sc-percentage rotate value from 158deg to something else.
    
    This will be a part of the Simple Chart library.

</code>


<div class="sc-gauge">
    <div class="sc-background">
      <div class="sc-percentage"></div>
      <div class="sc-mask"></div>
      <span class="sc-value">0.2</span>
    </div>
    <span class="sc-min">0</span>
    <span class="sc-max">2</span>
</div>

I would like to form a chart exactly as like given in the above image.

I am open to implement any kind of library like chartjs, d3, apex etc.., that supports this feature of having semi circle..

As I am a beginner with this scenario, kindly help me to resolve the feature as I am stuck for very long time with this.

A big thanks in advance..

Upvotes: 1

Views: 3330

Answers (2)

T J
T J

Reputation: 43156

React component:

const data = {
  "initial": {
    "unit": "GB",
    "value": 2
  },
  "remaining": {
    "unit": "GB",
    "value": 0.9
  },
  "type": "Internet",
};

function SemiCircleChart({min, max, value}){

  const angle = (value / max) * 180;
  const style = {'--angle': angle + 'deg'};

  return (
    <div class="sc-gauge">
      <div class="sc-background">
        <div class="sc-percentage" style={style}></div>
        <div class="sc-mask"></div>
        <span class="sc-value">{ value }</span>
      </div>
      <span class="sc-min">{ min }</span>
      <span class="sc-max">{ max }</span>
    </div>)
}

ReactDOM.render(
    <SemiCircleChart
      min={0}
      max={data.initial.value}
      value={data.remaining.value}
    />,
  document.querySelector('#app')
);
:root {
  --angle: 90deg;
}

body {
  background-color: #555888;
  font-family: sans-serif;
  color: #fff;
  text-align: center
}

code {
  display: inline-block;
  max-width: 600px;
  padding: 0;
  line-height: 1.5;
  font-family: monospace;
  color: #ccc
}

.sc-gauge {
  width: 200px;
  height: auto;
  margin: 20px auto;
}

.sc-background {
  position: relative;
  height: 100px;
  margin-bottom: 10px;
  background-color: #fff;
  border-radius: 150px 150px 0 0;
  overflow: hidden;
  text-align: center;
}

.sc-mask {
  position: absolute;
  top: 20px;
  right: 20px;
  left: 20px;
  height: 80px;
  background-color: #555888;
  border-radius: 150px 150px 0 0
}

.sc-percentage {
  position: absolute;
  top: 100px;
  left: -200%;
  width: 400%;
  height: 400%;
  margin-left: 100px;
  background-color: #00aeef;
}

.sc-percentage {
  transform: rotate(var(--angle));
  transform-origin: top center;
}

.sc-min {
  float: left;
}

.sc-max {
  float: right;
}

.sc-value {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  font-size: 48px;
  font-weight: 700
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<code>
    This will be a part of the Simple Chart library.
</code>
<div id="app"></div>


Old answer:

You just need to use a CSS variable:

Declare a variable like:

:root{
  --angle: 90deg;
}

and use it like:

.sc-percentage {
  transform: rotate(var(--angle));
  transform-origin: top center;
}

You can update this variable as style attribute from JavaScript:

element.style.setProperty("--angle", '180deg');

180deg would be full arc.

Upvotes: 2

Andy Ray
Andy Ray

Reputation: 32066

Here's an example with animation: https://codesandbox.io/s/angry-moon-t08hp?file=/src/App.js

You can set style variables in React, which is what this Codesandbox does:

        <div
          class="sc-percentage"
          style={{ transform: `rotate(${(percent / 100) * 180}deg)` }}
        ></div>

And it uses a setInterval to toggle the percent.

The animation between the two percents is achieved simply with a CSS transition property:

.sc-percentage {
  transform: rotate(25deg);
  transition: transform 1s;
  transform-origin: top center;
}

Upvotes: 1

Related Questions