eeschimosu - 1 year ago 87
iOS Question

# How to create graph pies with different sizes using bézier paths in swift?

I want to make a nice graphic pie with 8 equal slices, that can be individually scaled or resized depending on an Int or something like this. This would look something like below just that all the slices should be equally cut:

I have tried this in Objective-C but it makes just one slice:

``````  -(CAShapeLayer *)createPieSlice {
CAShapeLayer *slice = [CAShapeLayer layer];
slice.fillColor = [UIColor redColor].CGColor;
slice.strokeColor = [UIColor blackColor].CGColor;
slice.lineWidth = 3.0;

CGPoint center = CGPointMake(100.0, 100.0);

UIBezierPath *piePath = [UIBezierPath bezierPath];
[piePath moveToPoint:center];

[piePath closePath]; // this will automatically add a straight line to the center
slice.path = piePath.CGPath;

return slice;
}
``````

How can I achieve that graph in swift?

Break the problem into logical pieces.

You have wedges of different arc widths. All those radii need to add up to a full circle. I assume they represent fractions of something that adds up to 100%. Do you want a specific order? If so, map your fractions in the order you want, such that they all add up to 100%.

Then write code that starts at an angle of zero, and creates arcs that are the specified fraction of 2π. Each one would start at the end of the previous one. Assign a radius that's appropriate based on the data you need.

Now write code that creates closed path segments in a UIBezierPath.

## EDIT

You've clarified, and told us that you always want 8 slices of the same width but with different radii.

So you need to write code that takes 8 input values and plots it as 8 arcs with different radius values.

Let's say your input value is an array of floats ranging from 0 to 1. At zero, the wedge is zero-sized. At 1.0, it's the largest circle size that will fit in your view (half the width of a square view.

So you would create an array of 8 floats:

``````var fractions = [0.5, 0.7, 0.3, 0.1, 1.0 .6, .2, .9]
``````

The code to create a bezier curve with 8 arcs might look something like this:

``````let pi = 3.1415826

let piePath = UIBezierPath()
for (index, afloat) in fractions
{
let startAngle = Double(index) / fractions.count * 2 * pi
let endAngle = Double(index+1) / fractions.count * 2 * pi
let center = CGPointMake( myView.width/2, myView.height/2)
piePath.moveToPoint(center)

startAngle: startAngle,
endAngle: endAngle,
clockwise: true)
piePath.lineToPoint(center)
piePath.closePath()
}
``````

I think the code above would create 8 closed pie-slice paths, but I'm not positive. It might be necessary to add a lineToPoint call between the first moveToPoint call and the arc call.

## Edit #2:

Since I am learning Swift, I decided to take this as an exercise and wrote a sample project that generates pie charts using a shape layer and a a custom path created from a UIBezierPath, as outlined above. You can find the sample project on github: PieCharts project on Github

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download