Building a radial gauge with SVG and React - Part 1
June 29, 2017
While building the Trader App, I used SVG in React to build the radial gauge UI widget that displays the profit percentage in a visually appealing manner. The final product looks something like below (you can view the actual widget at https://veerasundar.com/trader)
As you can see, the gauge has several components.
Base dial with point markers.
A needle, anchored at center that points the progress.
A progress bar, either in red or green dependening on the progress value is in negative or positive.
For simplicity, let’s assume the gauge has a width and height of 120px. With this, let’s start building the components one by one.
SVG Gauge - CSS
We will be using below CSS to style our SVG gauge. Also note that we have rotated the SVG gauge by negative 90 degree using transform: rotate(-90deg), as it is needed to properly position the Gauge.
SVG Gauge - Base dial
As a first step, we will be building the base dial and the tick markers / labels for our SVG gauge. The output can be seen below.
Code for the base dial
As you can see, we have,
Defined a SVG element with width and height as 120px. We have also set the viewBox as 0 0 120 120 so that our SVG elements are scaled correctly (more about viewBox).
We defined a #tick element inside <defs> and reused it multiple times, rotating them using transform=rotate() according to their corresponding position in the dial. We also placed the labels of ticks using <text> and rotated them accordingly as we did for the tick markers.
Finally, we drew the base dial using the <circle> element.
SVG Gauge - Progress Bar
Next part would be to add the progress bar, indicating how much profit one have made (both positive / negative).
For example, in above gauges, the first gauge has made a negative -15% profit and the second one made a postive 59% profit. In order to visualize this, we will be using stroke-dasharray and stroke-dashoffset properties of circle element.
Code for drawing progress
You can see I have used the values stroke-dasharray="339.292" and stroke-dashoffset="364.73889999999994". To calculate the values, I used the following formuales.
As you can see the stroke-dasharray is nothing but the circumference of the circle and stroke-dashoffet is how much gap should be between each strokes. We use this gap to show the progress.
In my case, I needed half the circle to show positive progress and the other half to show negative progress, I divided the progress value by 200 to map it correctly.
SVG Gauge - Pointer Needles
Next we will be adding the pointer needles to exatly show the progress value inside the gauge (hey, what’s a gauge if it doesn’t have a needle!?).
Code to construct the needle
The needle has two components;
The pointer is drawn using polygon and it’s placed the center of the gauge cirle.
And a center cirlce, acting like a base of the needle.
We just need to calculate the rotation angle of our needle and rotate it using center of our SVG as origin (which is 60,60).
Note: I am using 180 below because I need to map the progress to only half the circle angle. If I wanted to map it to full circle, I would have used 360 here.
If you want to show your needle moving from 0 to the progress position, you can use animateTransform.
SVG Gauge - Assembly
Putting it all together, we will end up with our assembled SVG gauge.
SVG Gauge in production
Here’s the screenshot from Trader app where this gauge is used.
In the next post, I will show how to build this SVG Gauge in React component.