Click here to Skip to main content
15,891,704 members
Articles / Web Development / HTML
Tip/Trick

Circular Arrows Using SVG in Razor

Rate me:
Please Sign up or sign in to vote.
4.25/5 (8 votes)
10 May 2015CPOL4 min read 22.2K   324   11   5
Creating circular arrow of an svg image

Introduction

This tip will show you how to draw a circular svg arrow image.

Background

My employer has asked me to create circular arrows and also texts inside the arrows if possible and has provided me the stack overflow sample links to get started on the job quickly. I did a lot of Google search to find any quick or easy understandable answers but unfortunately there was no answer available. Then I started learning SVG tutorial as soon as I could and tried to play around with the core concepts of the SVG code and finally I came up with the solution explained below, which turned out to be very few lines of code and the magic was done!

AIM: Achieve Circular Arrow style image

Image 1

Getting Started

Create a sample ASP.NET MVC 3 application as below. By default, the application will have sample classes and Home controller.

Image 2

Let’s create a new View page (say wagonwheel.cshtml) under View-> Home folder. Then call the view from the default HomeController (see code below).

Image 3

Using the Code

Now open the cshtml page and add the following code to the page. I have written an HTML function which returns the value in radians. The below formula gives us the power to calculate the x and y coordinate for any point on a circle given the radius, r, of the circle and the angle, a, of the point we want. The value returned by the below function will be used to draw an arc of a circle.

C#
@functions {
public static string pol(double progress, double radius)
{
return (Math.Sin(progress * Math.PI * 2.0) * radius).ToString("0.0") + "," 
+ (Math.Cos(progress * Math.PI * 2.0) * -radius).ToString("0.0");
}
}

From the above function, you can see that I’m passing two parameters. Radius is self-explanatory which will be used to calculate the radius of the circle. I divided the circle into 5 parts, so that we can draw 5 arrows as a circle (let say 100% divided into 5 parts is 20%, 40%,60%, 80%, 100%).

Therefore, progress parameter is used to draw an arc of certain percentage.

Image 4

Let’s start drawing an SVG <PATH> arc of 20%.

SVG Path Definition

Everything drawn under the path element should be placed inside "d" element. The following are the commands used inside the path:

  • M = moveto
  • L = lineto
  • H = horizontal lineto
  • V = vertical lineto
  • C = curveto
  • S = smooth curveto
  • Q = quadratic Bézier curve
  • T = smooth quadratic Bézier curveto
  • A = elliptical Arc
  • Z = closepath

One other important thing we need to know about ‘A’ elliptical arc.

SVG Arcs

Drawing arcs using the <path> element is done using the A and a commands. Like with lines, the uppercase command (A) uses absolute coordinates for its endpoint, where the lowercase command (a) uses relative coordinates (relative to the start point). Here is an example:

XML
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M50,50
A30,50 0 0,1 100,100"
style="stroke:#660000; fill:none;"/>
</svg>

Here is the resulting image:

Image 5

This example draws an arc from the point 50,50 to the point 100,100 (specified last in the A command).

The radius of the arc is set by the two first parameters set on the A command. The first parameter is rx (radius in x-direction) and the second is ry (radius in y-direction). Setting rx and ry to the same value will result in a circular arc. Setting rx and ry to different values will result in an elliptical arc. In the example above, rx was set to 30 and ry to 50.

The third parameter set on the A command is the x-axis-rotation. This sets the rotation of the arc's x-axis compared to the normal x-axis. In the above example, the x-axis-rotation is set to 0. Most of the time, you will not need to change this parameter.

The fourth and fifth parameters are the large-arc-flag and sweep-flag parameters. The large-arc-flag determines whether to draw the smaller or bigger arc satisfying the start point, end point and rx and ry.

Let's get to the point, draw an elliptical arc of 20%.

JavaScript
@{
var nib = 0.02;
var pad = 0.02; // padding between the arrows
var large = 0; //large-arc-flag
var rx = 100;
var ry = 80;
var rmid = (rx + ry) / 2;

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-102 -102 204 204" class="progressbar-graphic">

@for (int i = 0; i < 1; i++)
{
var start = i * 0.2 + pad / 2;
var end = (i + 1) * .2 - pad / 2;

<path d="M @pol(start, @rx) 
A @rx,@rx 0 @large,1 @pol(end, @rx) 
L @pol(end + nib,@rmid)
L @pol(end, @ry) 
A @ry,@ry 0 @large,0 @pol(start, @ry) 
L @pol(start + nib, @rmid) Z" 
class ="progressbar-progresspink">

</path>

}
</svg>

}

Here is the resulting image:

Image 6

From the above code, we can understand that drawing a path:

  • M -> move to certain point
  • A -> draw an large arc
  • L -> draw an slant line
  • L -> draw a line towards back
  • A -> draw an inner arc
  • L -> draw an line
  • Z -> close the path (which draws line back to the starting point)

Now to draw a five different arcs, all we have to do is increase the for loop to 5 times and the resulting image as below:

JavaScript
@{
var nib = 0.02;
var pad = 0.02; // padding between the arrows
var large = 0; //large-arc-flag
var rx = 100;
var ry = 80;
var rmid = (rx + ry) / 2;

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-102 -102 204 204" class="progressbar-graphic">

@for (int i = 0; i < 5; i++)
{
var start = i * 0.2 + pad / 2; 
var end = (i + 1) * .2 - pad / 2;

var classarrow = "progressbar-progresspink ";
if (i == 0) {
classarrow = "progressbar-progressred";
}
else if (i == 1)
{
classarrow = "progressbar-progressgreen";
}
else if (i == 2)
{
classarrow = "progressbar-progressyellow";
}
else if (i == 3)
{
classarrow = "progressbar-progresspink";
}
else if (i == 4)
{
classarrow = "progressbar-progressblue";
}
<path d="M @pol(start, @rx) 
A @rx,@rx 0 @large,1 @pol(end, @rx) 
L @pol(end + nib,@rmid) 
L @pol(end, @ry) 
A @ry,@ry 0 @large,0 @pol(start, @ry) 
L @pol(start + nib, @rmid) Z" 
class=@classarrow></path>

}
</svg>

}

Also, in the above code, you may have noticed that I’m using custom "class" to fill different colours. These classes can be defined inside your style.css file.

Finally, here is the result:

Image 7

References

I have been learning svg from the below articles. There are many other examples of svg and much better explanation of svg tutorials.

History

  • 8th May, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
New Zealand New Zealand
I am a professional software developer/Analyst programmer with over 4 years of commercial development experience, focusing on the design, development and testing of software solutions using Microsoft technologies. I have been learning android using Xamarin and visual studio in my free time.

Outside of work , I love playing cricket, volleyball, swimming and adventure , travelling are my hobbies.

Comments and Discussions

 
QuestionWhat are the terms meaning Pin
Member 126782267-Apr-17 9:06
Member 126782267-Apr-17 9:06 
QuestionNice but some issues Pin
wvd_vegt11-May-15 4:49
professionalwvd_vegt11-May-15 4:49 
Hi
The code fails to produce valid svg files when the decimal separator is not a . (in Europe it's sometimes a ,).

So you should add something like:

NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;


and add nfi as last parameter to the two ToString methods in the pol method like

return (Math.Sin(progress * Math.PI * 2.0) * radius).ToString("0.0", nfi) + "," +
       (Math.Cos(progress * Math.PI * 2.0) * -radius).ToString("0.0", nfi);

wvd_vegt

Questionsource code Pin
kleinelefant10-May-15 22:08
kleinelefant10-May-15 22:08 
SuggestionRe: source code Pin
Bilal Haider11-May-15 0:56
professionalBilal Haider11-May-15 0:56 
AnswerRe: source code Pin
khanzzirfan12-May-15 11:02
khanzzirfan12-May-15 11:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.