I have very limited skill set in SVG,Canvas and CSS3. I have been trying to create a donut chart in angular 2 with no luck. There are some ready to use libraries available but we are not allowed to pull in 3rd party libraries into the project.Can someone point me in the right direction or help me with it.Basically i played around with SVG but there seems to be no 'arc' element in SVG
Create a Donut chart in Angular 2
Asked Answered
This can be easily done using SVG with stroke-dasharray and stroke-dashoffset. In your donut component html include the following code :-
<svg height="100%" width="100%" viewBox="0 0 120 120">
<circle *ngFor="let item of items;let i=index" cx="60" cy="60" r="50" fill="transparent" stroke-width="20"
[attr.stroke-dasharray]="getPerimeter(50)" [attr.stroke-dashoffset]="getOffset(50,i)" [attr.stroke]="getColor(i)"/>
</svg>
Basically perimiter of the circle is determined by 2πr where r is the radius. Stroke-dash offset will specify at what point should the new segment start.This can be calculated by subtracting the percentage of perimeter occupied by the previous segments from the total perimeter.In your TS file :-
export class DonutComponent{
items:Array<{name:string,count:number,color:string}>=[
{name:'Orange',count:50,color:'orange'},
{name:'Apple',count:25,color:'red'},
{name:'Pear',count:15,color:'green'}
];
private _total:number =0;
constructor() {
if(this.items.length>0)
{
this._total = this.items.map(a=>a.count).reduce((x,y)=>x+y);
}
}
getPerimeter(radius:number):number
{
return Math.PI*2*radius;
}
getColor(index:number):string
{
return this.items[index].color;
}
getOffset(radius:number,index:number):number
{
var percent=0;
for(var i=0;i<index;i++)
{
percent+=((this.items[i].count)/this._total);
}
var perimeter = Math.PI*2*radius;
return perimeter*percent;
}
}
The items can be made as input to the component if you want to make the donut generic
Added the source code for a more generic one in github .
Thank you Krishnanunni Jeevan ,that helped a lot. I was wondering if its possible to put a text at center and make it configurable –
Mckenna
I have updated the source code in github with displaying text at center –
Pyrogen
This is a brilliant solution. I am trying to modify this circle a bit so that the starting of 1st arc is at 90 degree instead of 0. Any suggestion on how to do this? –
Teacake
@Teacake Thankyou , You should be able to alter the getOffset function to do that. At present for index 0, the offset is 0. You can change it so that for index 0, the offset becomes 3/2 * PI * R . The function should be intelligent to handle other indexes too. I will see if I can alter the function to handle the cases –
Pyrogen
@KrishnanunniJeevan Thanks. I will try this. Right now i am using transform: rotate(270deg); transform-origin: 50% 50%; style on the first graph to mimic that! –
Teacake
Thanks @KrishnanunniJeevan this is really a best solution for me. –
Rosetta
© 2022 - 2024 — McMap. All rights reserved.