In the iPhone application Roambi, the pie chart shown can be animated to rotate with the user as if rotating a disc. We can hold and do lot of stuff with that.
Someone mentioned that the Roambi app was developed using core-plot library:
What library use Roambi app iPhone to draw chart?
How can I manipulate a pie chart developed using Core plot?
For a simple pie chart, even with the aforementioned animations, Core Plot is not necessary. If you only want a Core Plot solution, then please disregard this answer. However, here is a simple solution that requires no external packages or even any frameworks.
Create a UIView called PieChartView. In PieChartView.h:
#import <UIKit/UIKit.h>
@interface PieChartView : UIView {
float zeroAngle;
NSMutableArray *valueArray;
NSMutableArray *colorArray;
}
@property (nonatomic) float zeroAngle;
@property (nonatomic, retain) NSMutableArray *valueArray;
@property (nonatomic, retain) NSMutableArray *colorArray;
@end
Then the implementation in PieChartView.m:
#import "PieChartView.h"
@implementation PieChartView
@synthesize zeroAngle;
@synthesize valueArray, colorArray;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// DETERMINE NUMBER OF WEDGES OF PIE
int wedges = [valueArray count];
if (wedges > [colorArray count]) {
NSLog(@"INSUFFICENT COLORS FOR PIE CHART: Please add %d additional colors.",wedges-[colorArray count]);
for (int i=[colorArray count] ; i<wedges ; ++i) {
[colorArray addObject:[UIColor whiteColor]];
}
}
// DETERMINE TOTAL VOLUME OF PIE
float sum = 0.0;
for (int i=0; i<wedges ; ++i) {
sum += [[valueArray objectAtIndex:i] floatValue];
}
float frac = 2.0*M_PI/sum;
// DETERMINE CENTER AND MAXIMUM RADIUS OF INSCRIBED CIRCLE
int center_x = rect.size.width/2.0;
int center_y = rect.size.height/2.0;
int radius = (center_x > center_y ? center_x : center_y);
// DRAW WEDGES CLOCKWISE FROM POSITIVE X-AXIS
float startAngle=zeroAngle;
float endAngle=zeroAngle;
for (int i=0; i<wedges; ++i) {
startAngle = endAngle;
endAngle += [[valueArray objectAtIndex:i] floatValue]*frac;
[[colorArray objectAtIndex:i] setFill];
CGContextMoveToPoint(context, center_x, center_y);
CGContextAddArc(context, center_x, center_y, radius, startAngle, endAngle, 0);
CGContextClosePath(context);
CGContextFillPath(context);
}
}
- (void)dealloc {
[valueArray release];
[colorArray release];
[super dealloc];
}
@end
Now you can bind the float zeroAngle to the accelerometer in any way you wish to achieve the desired animation.
I didn't know CorePlot, and it might be some use for me in the near future, so I just gave it a look. CorePlot is interesting and is active.
Concerning Animations with CorePlot:
Core Animation
, it doesnt mean CorePlot graph will be easily animatable.Interesting reading on the topic on google groups.
So here are your options (by my order of preference):
Core Animation
)Core Animation
skills needed, again.I doubt Roambi uses CorePlot, but if they do, they use it as a base with TONS of custom in house code...
A quick look at the Core Plot source code reveals that CPPieChart
's inheritance looks like this:
CPPieChart : CPPlot : CPAnnotationHostLayer : CPLayer : CALayer
So you can see that in the end, CPPieChart
is just a heavily subclassed CALayer
. I might be entirely incorrect here, but there's nothing that indicates that this can't be animated like any other CALayer
. Try the following code to rotate the layer by 360 degrees:
CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D transform = CATransform3DMakeRotation(DegreesToRadians(360), 0, 0, 1);
rotation.toValue = [NSValue valueWithCATransform3D:transform];
rotation.duration = 10.0f;
[pieChart addAnimation:rotation forKey:@"rotation"];
If you can get this working then its just a matter of reading the values from the accelerometer and converting them to rotation angles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With