From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
In this tutorial we will show you how to create a diagram using Raphaël – a small JavaScript library that is great for working with vector graphics. The idea is very simple: we will draw some arcs using mathematical functions and we’ll be displaying a skill percentage in a main circle when we hover over those arcs.
Let’s start with the markup.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
The Markup
The HTML structure is going to consist of a main container with the class ‘get’. This container stores all data that we need to draw the arcs. Then we create a new div element with the id ‘diagram’ which will be the container for the arcs:
<div id="diagram"></div> <div class="get"> <div class="arc"> <span class="text">jQuery</span> <input type="hidden" class="percent" value="95" /> <input type="hidden" class="color" value="#97BE0D" /> </div> <div class="arc"> <span class="text">CSS3</span> <input type="hidden" class="percent" value="90" /> <input type="hidden" class="color" value="#D84F5F" /> </div> <div class="arc"> <span class="text">HTML5</span> <input type="hidden" class="percent" value="80" /> <input type="hidden" class="color" value="#88B8E6" /> </div> <div class="arc"> <span class="text">PHP</span> <input type="hidden" class="percent" value="53" /> <input type="hidden" class="color" value="#BEDBE9" /> </div> <div class="arc"> <span class="text">MySQL</span> <input type="hidden" class="percent" value="45" /> <input type="hidden" class="color" value="#EDEBEE" /> </div> </div>
The CSS
In the CSS we will only do two things: hide the elements with the class ‘get’ and set the width and height of the div with the id ‘diagram’:
.get { display:none; } #diagram { float:left; width:600px; height:600px; }
The JavaScript
The main idea is to first create a new Raphael object (variable ‘r’) and draw our first circle with a radius that we specify in ‘rad’.
Then we create a new circle in the Raphael object. We center the circle (x: 300px and y: 300px) and we add some text to it.
var o = { init: function(){ this.diagram(); }, random: function(l, u){ return Math.floor((Math.random()*(u-l+1))+l); }, diagram: function(){ var r = Raphael('diagram', 600, 600), rad = 73; r.circle(300, 300, 85).attr({ stroke: 'none', fill: '#193340' }); var title = r.text(300, 300, 'Skills').attr({ font: '20px Arial', fill: '#fff' }).toFront(); } }
Now, let’s go one step further.
We’ll extend the Raphael object with some custom attributes:
- alpha – angle of the arc
- random – random number from the specified range
- sx, sy – start drawing from this point
- x, y – end drawing at this point
- path
- M – move to the starting point. No line is drawn. All path data must begin with a ‘moveto’ command.
- A – radius-x, radius-y x-axis-rotation, large-arc-flag, sweep-flag, x, y (read more: https://developer.mozilla.org/en/SVG/Tutorial/Paths)
var o = { init: function(){ this.diagram(); }, random: function(l, u){ return Math.floor((Math.random()*(u-l+1))+l); }, diagram: function(){ var r = Raphael('diagram', 600, 600), rad = 73; r.circle(300, 300, 85).attr({ stroke: 'none', fill: '#193340' }); var title = r.text(300, 300, 'Skills').attr({ font: '20px Arial', fill: '#fff' }).toFront(); r.customAttributes.arc = function(value, color, rad){ var v = 3.6*value, alpha = v == 360 ? 359.99 : v, random = o.random(91, 240), a = (random-alpha) * Math.PI/180, b = random * Math.PI/180, sx = 300 + rad * Math.cos(b), sy = 300 - rad * Math.sin(b), x = 300 + rad * Math.cos(a), y = 300 - rad * Math.sin(a), path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]]; return { path: path, stroke: color } } $('.get').find('.arc').each(function(i){ var t = $(this), color = t.find('.color').val(), value = t.find('.percent').val(), text = t.find('.text').text(); rad += 30; var z = r.path().attr({ arc: [value, color, rad], 'stroke-width': 26 }); z.mouseover(function(){ this.animate({ 'stroke-width': 50, opacity: .75 }, 1000, 'elastic'); if(Raphael.type != 'VML') //solves IE problem this.toFront(); title.animate({ opacity: 0 }, 500, '>', function(){ this.attr({ text: text + 'n' + value + '%' }).animate({ opacity: 1 }, 500, '<'); }); }).mouseout(function(){ this.animate({ 'stroke-width': 26, opacity: 1 }, 1000, 'elastic'); }); }); } }
Then we’ll retrieve all the data needed, such as the percentage value, the color of the arc and the text. We increase the radius value for each arc and finally create a new arc path.
In the last step we are adding some animations on hover. When the mouse will be over the arc the title (which is placed in the main circle) is changing. Also, we’ll make the arc a little bit bigger.
Conclusion
In today’s tutorial you’ve learned some first steps on how to use Raphaël. It is a powerful library and you can do a lot of great stuff with it. Visit the Raphaël website for more examples.
Outstanding! 🙂
Nice!!!
Like This ^_^
Awesome 🙂
Thanks for share it!
Great Creative work !
Thank for sharing
This is just AMAZING!!!!
Thanks for share it, i’m really fan of your work! 🙂
This is awesome (y) You guys always publish the best js tuts. 🙂
Very good idea…thanks for sharing
nice one, will use this in new project I’m working on…
GREAT !
Thank you so much.
Awesome 🙂
Wow! That’s pretty slick! Now just to find a need for something like that 😉
cool trick! thanks for sharing.
Very nice effect, also easy to implement!
Wow, very nice effect! Thanx for share! 😉
But it is not possible to download. This messege is showed:
Forbidden
You don’t have permission to access /Tutorials/AnimatedSkillsDiagram/AnimatedSkillsDiagram.zip on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Hi Daniel,
it’s not allowed to directly access the ZIP file, you actually need to download it from this page. Please try it and let me know if there is still the same problem. Cheers, ML
Hi Mary,
Thanks for your response. Actually, I used the button from this same page and couldn’t get it. It’s istill heapens. But I discover that is a browser’s problem, couse when I use another I had success. Yupi! Cheers! DB.
😉
Hi Daniel, ok cool thanks, can you tell me which browser causes that problem? Cheers, ML
Great thing.
But did you see that it now work with IE9??
Using Firefox 3.6.13 this problem heapens. Then, switching to Safari 5.0.5 I could download.
Cheers, DB.
Very nice and I have implemented in my site.
However in IE9 not working as expected.
After hover the arcs remain expanded.
Hello Paulo,
please download the script again. Maybe you still had the older version that didn’t have the fix. Let me know if it worked, cheers, ML
Hi Mary Lou, tried but no success.
Then again the user can still change the value of the arcs.
They simply overlay on each other.
Is it possible to put links on
CSS3
Really Amazing…i Would love to Add on my Resume Page 🙂
Thanks Again
Thanks for the great script,i must admit Codrops is one of the most inspiring sites on the web.What i want to know is there any way of putting links inside of an arc,because i would like to use this as some kind of menu.
I tried something with anchors and onclick events,but can’t figure it out.
very good idea..thank u for sharing..
Is there any way to draw text on those arcs as opposed to in the center?
Hey Mary,
Great Tut indeed, I’ve installed it and it’s working fine on all browsers except IE9 I think it’s the same problem that happens with “Paulo Carvalho”.
I hope that u could give us a fix code if possible. if not u still awesome 😉
Does anyone know if this works in IE (other than IE9+)? I’m on Mac, but tested the demo link in Adobe Browser Labs and the circular bars appeared offset rather than centered.
Awesome!
You guys have some of the most fantastic tutorials on the web. I love all of them. Thank you. <3
Great tutorial and great demo
Hey guys I already test on IE9 (win 7)
and I found one mistake.
On mouseout some wrong happened.
it was supposed to the mouseout effect happen, but isn’t working.
When you have a free time check out it.
Is there a way to not use percentages? Just use numbers relative to one another? I’m not a js expert but I couldn’t find what is making the value a percentage. Unless the class of percentage is doing more than just getting called in init.js.
Thank you Mary Lou for sharing an awesome diagram, I adapted it to my portfolio website http://www.websalut.com/about_me.php
Hi! This is a great tutorial and thanks for that.
I found what’s wrong with IE9 and Opera. I don’t know exactly why but these lines:
if(Raphael.type != ‘VML’) //solves IE problem
this.toFront();
don’t work properly. Just remove them and it will fix the problem.
is there any way to make this just loop. another words. the same action that happens when you scroll over it. but have each one have that action for 1 second. coming from the inside and from the outside.
a trippy effect if can be done. i could not figure it out
how can i move or align to the top left corner? i tried editing the css but unable to do it…
http://www.storagedrop.com/graph.php
thank you
Could this be modified so that it was dynamic? if so how?
I love Raphael. And nice tutorial, already implemented at my site! 🙂
Love this effect. Went through the trouble of figuring out how to add more layers, style the graph, but when I tried to implement it into my live site I think I am getting some conflicts between rafael and mootools 🙁
Oh well!
Thanks for posting!
Under what license is the (demo) code? Could I simply use the code?
very creative and inventive!
very nice code drop.
Like to see some code drops, which can show viewBox in action.
I love Raphael. And nice tutorial, already implemented at my site! 🙂 Greetz, Marcell