From d3e58bac0cbc74a793e4658682db50f189deeaf4 Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Mon, 13 Aug 2012 17:53:57 -0300 Subject: [PATCH 01/17] Add gesture for push on chart portions. --- iOSPlot/Shared/PCPieChart.m | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 2a907db..7bb77b1 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -62,6 +62,14 @@ - (NSString*)description @end +@interface PCPieChart() + +@property (strong, nonatomic) UITapGestureRecognizer *tapGesture; + +-(void)TapByUser:(id)sender; + +@end + @implementation PCPieChart - (id)initWithFrame:(CGRect)frame @@ -75,6 +83,12 @@ - (id)initWithFrame:(CGRect)frame _percentageFont = [UIFont boldSystemFontOfSize:20]; _showArrow = YES; _sameColorLabel = NO; + + _tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapByUser:)]; + _tapGesture.delegate=self; + _tapGesture.numberOfTapsRequired=1; + [self addGestureRecognizer:_tapGesture]; + } return self; } @@ -458,4 +472,54 @@ - (void)drawRect:(CGRect)rect } } +-(void)TapByUser:(id)sender +{ + CGRect rect = self.frame; + float x = (rect.size.width - self.diameter)/2; + float y = (rect.size.height - self.diameter)/2; + //float gap = 1; + //float inner_radius = diameter/2; + float origin_x = x + self.diameter/2; + float origin_y = y + self.diameter/2; + + + //Find by what angle it has to rotate + CGPoint touchPointOnSelf=[(UITapGestureRecognizer *)sender locationInView:self]; + + + if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(self.diameter/2.f,2.f)) + NSLog(@"Touch inside"); + else { + NSLog(@"Touch outside"); + return; + } + + float angle=atan2f((touchPointOnSelf.y - origin_y), (touchPointOnSelf.x - origin_x)); + angle += M_PI * 0.5f; // Chart alligment. + + + if(angle<0) + angle+=2* M_PI; + + float total = 0; + for (PCPieComponent *component in self.components) + { + total += component.value; + } + float startDeg = 0; + float endDeg = 0; + + for (PCPieComponent *component in self.components) { + float perc = [component value]/total; + endDeg = startDeg+perc*2*M_PI; + if (angle > startDeg && angle < endDeg) { + NSLog(@"Portion %@ with value %f %% was touched", component.title, component.value); + break; + } + startDeg = endDeg; + } + +} + + @end From 02c9dbcd58a8b4a5a8dc32305baaf796bea48c0b Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Tue, 14 Aug 2012 17:01:12 -0300 Subject: [PATCH 02/17] add inner circle, tittle and desestiamte touch inside the inner circle. --- iOSPlot/PlotCreator.xcodeproj/project.pbxproj | 2 + iOSPlot/Shared/PCPieChart.h | 5 +- iOSPlot/Shared/PCPieChart.m | 74 ++++++++++++++++--- iOSPlot/iPhone/PieChartViewController.m | 3 + 4 files changed, 74 insertions(+), 10 deletions(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj index 156456b..33ed49e 100755 --- a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj +++ b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj @@ -293,6 +293,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = PlotCreator_Prefix.pch; INFOPLIST_FILE = "PlotCreator-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.1; PRODUCT_NAME = PlotCreator; RUN_CLANG_STATIC_ANALYZER = YES; }; @@ -307,6 +308,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = PlotCreator_Prefix.pch; INFOPLIST_FILE = "PlotCreator-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 5.1; PRODUCT_NAME = PlotCreator; RUN_CLANG_STATIC_ANALYZER = YES; VALIDATE_PRODUCT = YES; diff --git a/iOSPlot/Shared/PCPieChart.h b/iOSPlot/Shared/PCPieChart.h index 6431233..45bdfe2 100644 --- a/iOSPlot/Shared/PCPieChart.h +++ b/iOSPlot/Shared/PCPieChart.h @@ -48,11 +48,14 @@ #define PCColorRed [UIColor colorWithRed:1.0 green:51/255.0 blue:51/255.0 alpha:1.0] #define PCColorYellow [UIColor colorWithRed:1.0 green:220/255.0 blue:0.0 alpha:1.0] #define PCColorDefault [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0] +#define PCColorInnerCircle [UIColor colorWithRed:0.85 green:0.80 blue:0.85 alpha:1.0] +#define PCColorTextInnerCircle [UIColor colorWithRed:0.05 green:0.15 blue:0.05 alpha:1.0] @interface PCPieChart : UIView @property (nonatomic, assign) int diameter; @property (nonatomic, strong) NSMutableArray *components; @property (nonatomic, strong) UIFont *titleFont, *percentageFont; -@property (nonatomic, assign) BOOL showArrow, sameColorLabel; +@property (nonatomic, strong) NSString *titleInnerCircle; +@property (nonatomic, assign) BOOL showArrow, sameColorLabel, showInnerCircle; @property (nonatomic, assign, getter = hasOutline) BOOL outline; @end diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 7bb77b1..b8aea67 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -66,6 +66,9 @@ @interface PCPieChart() @property (strong, nonatomic) UITapGestureRecognizer *tapGesture; +@property (nonatomic, assign) int diameterInnerCircle; +@property (nonatomic, strong) UIFont *titleFontInnerCircle; + -(void)TapByUser:(id)sender; @end @@ -107,10 +110,14 @@ - (void)drawRect:(CGRect)rect float x = (rect.size.width - self.diameter)/2; float y = (rect.size.height - self.diameter)/2; float gap = 1; - float inner_radius = self.diameter/2; + float radius = self.diameter/2; float origin_x = x + self.diameter/2; float origin_y = y + self.diameter/2; + _diameterInnerCircle = self.diameter / 3.f; + float x_innerCircle = x + radius - _diameterInnerCircle / 2.f; + float y_innerCircle = y + radius - _diameterInnerCircle / 2.f; + // label stuff float left_label_y = LABEL_TOP_MARGIN; float right_label_y = LABEL_TOP_MARGIN; @@ -145,14 +152,14 @@ - (void)drawRect:(CGRect)rect CGContextSetFillColorWithColor(ctx, [component.colour CGColor]); CGContextMoveToPoint(ctx, origin_x, origin_y); - CGContextAddArc(ctx, origin_x, origin_y, inner_radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); + CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); CGContextClosePath(ctx); CGContextFillPath(ctx); CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); CGContextSetLineWidth(ctx, gap); CGContextMoveToPoint(ctx, origin_x, origin_y); - CGContextAddArc(ctx, origin_x, origin_y, inner_radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); + CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); CGContextClosePath(ctx); CGContextStrokePath(ctx); @@ -234,8 +241,8 @@ - (void)drawRect:(CGRect)rect //CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 5); - int x1 = inner_radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; - int y1 = inner_radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; + int x1 = radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; + int y1 = radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; CGContextSetLineWidth(ctx, 1); if (left_label_y + optimumSize.height/2 < y)//(left_label_y==LABEL_TOP_MARGIN) { @@ -382,8 +389,8 @@ - (void)drawRect:(CGRect)rect //CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 5); CGContextSetLineWidth(ctx, 1); - int x1 = inner_radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; - int y1 = inner_radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; + int x1 = radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; + int y1 = radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; if (right_label_y + optimumSize.height/2 < y)//(right_label_y==LABEL_TOP_MARGIN) @@ -469,6 +476,49 @@ - (void)drawRect:(CGRect)rect } nextStartDeg = endDeg; } + + if (_showInnerCircle) { + CGContextRef ctx = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(ctx); + CGFloat r,g,b,a; + UIColor *color = PCColorInnerCircle; + [color getRed:&r green:&g blue:&b alpha:&a]; + CGContextSetRGBFillColor(ctx, r, g, b, a); // white color + CGContextSetShadow(ctx, CGSizeMake(0.3f, 0.2f), margin); + CGContextFillEllipseInRect(ctx, + CGRectMake(x_innerCircle, + y_innerCircle, + _diameterInnerCircle, + _diameterInnerCircle)); + UIGraphicsPopContext(); + + if (_titleInnerCircle) { + float width = cosf(25) * _diameterInnerCircle; + if (width < 8) + width = 8; + float height = fabsf(sinf(25) * _diameterInnerCircle); + int fontSize = height; + _titleFontInnerCircle = [UIFont boldSystemFontOfSize:fontSize]; + + CGFloat r,g,b,a; + UIColor *color = PCColorTextInnerCircle; + [color getRed:&r green:&g blue:&b alpha:&a]; + + CGFloat text_x = x_innerCircle + (_diameterInnerCircle - width) * 0.5f; + CGFloat text_y = y_innerCircle + (_diameterInnerCircle - height) * 0.5f; + + + CGRect titleFrame = CGRectMake(text_x, text_y, width, height); + + UIGraphicsPushContext(ctx); + CGContextSetRGBFillColor(ctx, r, g, b, a); + [_titleInnerCircle drawInRect:titleFrame + withFont:_titleFontInnerCircle + lineBreakMode:UILineBreakModeWordWrap + alignment:UITextAlignmentCenter]; + UIGraphicsPopContext(); + } + } } } @@ -486,8 +536,13 @@ -(void)TapByUser:(id)sender //Find by what angle it has to rotate CGPoint touchPointOnSelf=[(UITapGestureRecognizer *)sender locationInView:self]; + if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { + NSLog(@"Touch inside Inner Circle"); + return; + } + - if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(self.diameter/2.f,2.f)) + if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameter*0.5f,2.f)) NSLog(@"Touch inside"); else { NSLog(@"Touch outside"); @@ -513,7 +568,8 @@ -(void)TapByUser:(id)sender float perc = [component value]/total; endDeg = startDeg+perc*2*M_PI; if (angle > startDeg && angle < endDeg) { - NSLog(@"Portion %@ with value %f %% was touched", component.title, component.value); + NSLog(@"Portion %@ with value %f%% and percent %.1f%% was touched", + component.title, component.value, component.value/total*100.f); break; } startDeg = endDeg; diff --git a/iOSPlot/iPhone/PieChartViewController.m b/iOSPlot/iPhone/PieChartViewController.m index 7304efa..37e9b6c 100644 --- a/iOSPlot/iPhone/PieChartViewController.m +++ b/iOSPlot/iPhone/PieChartViewController.m @@ -51,6 +51,9 @@ - (id)init [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; [pieChart setDiameter:width/2]; [pieChart setSameColorLabel:YES]; + + [pieChart setShowInnerCircle:YES]; + [pieChart setTitleInnerCircle:@"Center Title"]; [self.view addSubview:pieChart]; From e0ab0c8c4167fad67bc2d4bfdbea20a70f87e188 Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Tue, 14 Aug 2012 17:02:06 -0300 Subject: [PATCH 03/17] . --- iOSPlot/Shared/PCPieChart.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index b8aea67..603d661 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -536,7 +536,9 @@ -(void)TapByUser:(id)sender //Find by what angle it has to rotate CGPoint touchPointOnSelf=[(UITapGestureRecognizer *)sender locationInView:self]; - if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { + + if (_showInnerCircle + && powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { NSLog(@"Touch inside Inner Circle"); return; } From 469a3b5dfc833e2b7234d19fd4b77b4d66fbbcba Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Tue, 14 Aug 2012 17:17:58 -0300 Subject: [PATCH 04/17] Add new Pie Chart View Controller to list implementing the new tools. --- iOSPlot/PieChartViewController3.h | 13 +++ iOSPlot/PieChartViewController3.m | 100 ++++++++++++++++++ iOSPlot/PlotCreator.xcodeproj/project.pbxproj | 6 ++ .../UserInterfaceState.xcuserstate | Bin 0 -> 32281 bytes .../UserInterfaceState.xcuserstate | Bin 39103 -> 0 bytes .../WorkspaceSettings.xcsettings | 10 -- .../xcdebugger/Breakpoints.xcbkptlist | 46 ++++++++ .../xcschemes/PlotCreator.xcscheme | 24 +++-- .../xcschemes/xcschememanagement.plist | 0 iOSPlot/iPhone/ChartListViewController.m | 82 +++++++------- iOSPlot/iPhone/PieChartViewController.m | 5 +- 11 files changed, 226 insertions(+), 60 deletions(-) create mode 100644 iOSPlot/PieChartViewController3.h create mode 100644 iOSPlot/PieChartViewController3.m create mode 100644 iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/honcheng.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/honcheng.xcuserdatad/WorkspaceSettings.xcsettings create mode 100644 iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist rename iOSPlot/PlotCreator.xcodeproj/xcuserdata/{honcheng.xcuserdatad => gustavohalperin.xcuserdatad}/xcschemes/PlotCreator.xcscheme (84%) rename iOSPlot/PlotCreator.xcodeproj/xcuserdata/{honcheng.xcuserdatad => gustavohalperin.xcuserdatad}/xcschemes/xcschememanagement.plist (100%) diff --git a/iOSPlot/PieChartViewController3.h b/iOSPlot/PieChartViewController3.h new file mode 100644 index 0000000..eb8bdf8 --- /dev/null +++ b/iOSPlot/PieChartViewController3.h @@ -0,0 +1,13 @@ +// +// PieChartViewController3.h +// PlotCreator +// +// Created by gustavo halperin on 8/14/12. +// +// + +#import + +@interface PieChartViewController3 : UIViewController + +@end diff --git a/iOSPlot/PieChartViewController3.m b/iOSPlot/PieChartViewController3.m new file mode 100644 index 0000000..01d22a2 --- /dev/null +++ b/iOSPlot/PieChartViewController3.m @@ -0,0 +1,100 @@ +// +// PieChartViewController3.m +// PlotCreator +// +// Created by gustavo halperin on 8/14/12. +// +// + +#import "PieChartViewController3.h" +#import "PCPieChart.h" + +@implementation PieChartViewController3 + +- (id)init +{ + self = [super init]; + if (self) + { + [self.view setBackgroundColor:[UIColor colorWithWhite:1 alpha:1]]; + [self setTitle:@"Pie Chart"]; + + + int height = [self.view bounds].size.width/3*2.; // 220; + int width = [self.view bounds].size.width; //320; + PCPieChart *pieChart = [[PCPieChart alloc] initWithFrame:CGRectMake(([self.view bounds].size.width-width)/2,([self.view bounds].size.height-height)/2,width,height)]; + [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; + [pieChart setDiameter:width/2]; + [pieChart setSameColorLabel:YES]; + + [pieChart setShowInnerCircle:YES]; + [pieChart setTitleInnerCircle:@"Center Title"]; + + [self.view addSubview:pieChart]; + + if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad) + { + pieChart.titleFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:30]; + pieChart.percentageFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:50]; + } + + NSString *sampleFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"sample_piechart_data.plist"]; + NSDictionary *sampleInfo = [NSDictionary dictionaryWithContentsOfFile:sampleFile]; + NSMutableArray *components = [NSMutableArray array]; + for (int i=0; i<[[sampleInfo objectForKey:@"data"] count]; i++) + { + NSDictionary *item = [[sampleInfo objectForKey:@"data"] objectAtIndex:i]; + PCPieComponent *component = [PCPieComponent pieComponentWithTitle:[item objectForKey:@"title"] value:[[item objectForKey:@"value"] floatValue]]; + [components addObject:component]; + + if (i==0) + { + [component setColour:PCColorYellow]; + } + else if (i==1) + { + [component setColour:PCColorGreen]; + } + else if (i==2) + { + [component setColour:PCColorOrange]; + } + else if (i==3) + { + [component setColour:PCColorRed]; + } + else if (i==4) + { + [component setColour:PCColorBlue]; + } + } + [pieChart setComponents:components]; + + } + return self; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Overriden to allow any orientation. + return YES; +} + + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc. that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + + + +@end diff --git a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj index 33ed49e..83d66e7 100755 --- a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj +++ b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 2860E32E111B888700E27156 /* AppDelegate_iPad.m in Sources */ = {isa = PBXBuildFile; fileRef = 2860E32C111B888700E27156 /* AppDelegate_iPad.m */; }; 2860E32F111B888700E27156 /* MainWindow_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2860E32D111B888700E27156 /* MainWindow_iPad.xib */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + C9B46D8E15DAE7880069B114 /* PieChartViewController3.m in Sources */ = {isa = PBXBuildFile; fileRef = C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */; }; F832606A1363D49B0045F9DC /* ChartListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F83260691363D49B0045F9DC /* ChartListViewController.m */; }; F83260AA1363D8170045F9DC /* back_button.png in Resources */ = {isa = PBXBuildFile; fileRef = F83260A81363D8170045F9DC /* back_button.png */; }; F83260AB1363D8170045F9DC /* back_button@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F83260A91363D8170045F9DC /* back_button@2x.png */; }; @@ -44,6 +45,8 @@ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Shared/main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* PlotCreator_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlotCreator_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* PlotCreator-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "PlotCreator-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + C9B46D8C15DAE7880069B114 /* PieChartViewController3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PieChartViewController3.h; sourceTree = ""; }; + C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PieChartViewController3.m; sourceTree = ""; }; F83260681363D49B0045F9DC /* ChartListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChartListViewController.h; path = iPhone/ChartListViewController.h; sourceTree = ""; }; F83260691363D49B0045F9DC /* ChartListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ChartListViewController.m; path = iPhone/ChartListViewController.m; sourceTree = ""; }; F83260A81363D8170045F9DC /* back_button.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = back_button.png; path = Images/back_button.png; sourceTree = ""; }; @@ -119,6 +122,8 @@ F897D6FF136311E60025FE6E /* PieChartViewController.m */, F83260C01363D91E0045F9DC /* PieChartViewController2.h */, F83260C11363D91E0045F9DC /* PieChartViewController2.m */, + C9B46D8C15DAE7880069B114 /* PieChartViewController3.h */, + C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */, F87DE41B1370D82D00347F69 /* HalfPieChartViewController.h */, F87DE41C1370D82D00347F69 /* HalfPieChartViewController.m */, F83260681363D49B0045F9DC /* ChartListViewController.h */, @@ -276,6 +281,7 @@ F87DE41A1370D68300347F69 /* PCHalfPieChart.m in Sources */, F87DE41D1370D82D00347F69 /* HalfPieChartViewController.m in Sources */, F8B8196215D573FB0005945A /* JSONKit.m in Sources */, + C9B46D8E15DAE7880069B114 /* PieChartViewController3.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..0120afd86975dfb0b1dd24f51538114c00ae24f8 GIT binary patch literal 32281 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 literal 0 HcmV?d00001 diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/honcheng.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/honcheng.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 854ce496cf508425d0aa8c89ffbec10e5d7d03b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39103 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 - - - - HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges - - SnapshotAutomaticallyBeforeSignificantChanges - - - diff --git a/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist new file mode 100644 index 0000000..f3e501e --- /dev/null +++ b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist @@ -0,0 +1,46 @@ + + + + + + + + + + + diff --git a/iOSPlot/PlotCreator.xcodeproj/xcuserdata/honcheng.xcuserdatad/xcschemes/PlotCreator.xcscheme b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcschemes/PlotCreator.xcscheme similarity index 84% rename from iOSPlot/PlotCreator.xcodeproj/xcuserdata/honcheng.xcuserdatad/xcschemes/PlotCreator.xcscheme rename to iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcschemes/PlotCreator.xcscheme index 81b5b9d..470d42e 100644 --- a/iOSPlot/PlotCreator.xcodeproj/xcuserdata/honcheng.xcuserdatad/xcschemes/PlotCreator.xcscheme +++ b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcschemes/PlotCreator.xcscheme @@ -1,7 +1,7 @@ + LastUpgradeVersion = "0450" + version = "1.3"> @@ -23,23 +23,31 @@ + + + + Date: Tue, 14 Aug 2012 17:24:56 -0300 Subject: [PATCH 05/17] add gitignore. --- .gitignore | 15 +++++++++++++++ .../UserInterfaceState.xcuserstate | Bin 32281 -> 33273 bytes 2 files changed, 15 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..edc082c --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Xcode +build/* +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +*.xcworkspace +!default.xcworkspace +xcuserdata +profile +*.moved-aside diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index 0120afd86975dfb0b1dd24f51538114c00ae24f8..24200d8022fa4a23b8e9e0f395e7b6e1f8237f72 100644 GIT binary patch delta 9331 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 Date: Tue, 14 Aug 2012 17:51:02 -0300 Subject: [PATCH 06/17] Partial commit. --- .../UserInterfaceState.xcuserstate | Bin 33273 -> 33204 bytes iOSPlot/Shared/PCPieChart.h | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index 24200d8022fa4a23b8e9e0f395e7b6e1f8237f72..eefe6c44281c8b5415fb56b01da465c38a415675 100644 GIT binary patch delta 8211 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 Date: Wed, 15 Aug 2012 17:29:50 -0300 Subject: [PATCH 07/17] Add percent inside portion pie chart instead of be outside. It is not yet perfect but need to more in the middle of the portion. --- iOSPlot/PieChartViewController3.m | 1 + .../UserInterfaceState.xcuserstate | Bin 33204 -> 35414 bytes .../xcdebugger/Breakpoints.xcbkptlist | 41 -- iOSPlot/Shared/PCPieChart.m | 638 +++++++++--------- 4 files changed, 322 insertions(+), 358 deletions(-) diff --git a/iOSPlot/PieChartViewController3.m b/iOSPlot/PieChartViewController3.m index 01d22a2..3918f28 100644 --- a/iOSPlot/PieChartViewController3.m +++ b/iOSPlot/PieChartViewController3.m @@ -29,6 +29,7 @@ - (id)init [pieChart setShowInnerCircle:YES]; [pieChart setTitleInnerCircle:@"Center Title"]; + [pieChart setShowValuesInChart:YES]; [self.view addSubview:pieChart]; diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index eefe6c44281c8b5415fb56b01da465c38a415675..f93b92c091dbf57d3365f2abbe7593a2157ce0fd 100644 GIT binary patch delta 16652 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 diff --git a/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist index f3e501e..05301bc 100644 --- a/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ b/iOSPlot/PlotCreator.xcodeproj/xcuserdata/gustavohalperin.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist @@ -2,45 +2,4 @@ - - - - - - - - diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 603d661..91f5ea8 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -1,34 +1,34 @@ /** * Copyright (c) 2011 Muh Hon Cheng * Created by honcheng on 28/4/11. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject * to the following conditions: - * - * The above copyright notice and this permission notice shall be + * + * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT - * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT - * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT + * WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT + * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * + * * @author Muh Hon Cheng * @copyright 2011 Muh Hon Cheng * @version - * + * */ #import "PCPieChart.h" @@ -96,6 +96,22 @@ - (id)initWithFrame:(CGRect)frame return self; } +- (void)setShowArrow:(BOOL)showArrow +{ + _showArrow = showArrow; + if (_showArrow) { + _showValuesInChart = NO; + } +} + +- (void)setShowValuesInChart:(BOOL)showValuesInChart +{ + _showValuesInChart = showValuesInChart; + if (_showValuesInChart) { + _showArrow = NO; + } +} + #define LABEL_TOP_MARGIN 15 #define ARROW_HEAD_LENGTH 6 #define ARROW_HEAD_WIDTH 4 @@ -121,8 +137,7 @@ - (void)drawRect:(CGRect)rect // label stuff float left_label_y = LABEL_TOP_MARGIN; float right_label_y = LABEL_TOP_MARGIN; - - + if ([self.components count]>0) { @@ -185,8 +200,6 @@ - (void)drawRect:(CGRect)rect nextStartDeg = endDeg; } - nextStartDeg = 0; - endDeg = 0; float max_text_width = x - 10; for (int i=0; i<[tmpComponents count]; i++) { @@ -194,296 +207,291 @@ - (void)drawRect:(CGRect)rect nextStartDeg = component.startDeg; endDeg = component.endDeg; - if (nextStartDeg > 180 || (nextStartDeg < 180 && endDeg> 270) ) - { - // left - - // display percentage label - if (self.sameColorLabel) - { - CGContextSetFillColorWithColor(ctx, [component.colour CGColor]); - } - else - { - CGContextSetRGBFillColor(ctx, 0.1f, 0.1f, 0.1f, 1.0f); - } - //CGContextSetRGBStrokeColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); - //CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); - CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 3); - - //float text_x = x + 10; - NSString *percentageText = [NSString stringWithFormat:@"%.1f%%", component.value/total*100]; - CGSize optimumSize = [percentageText sizeWithFont:self.percentageFont constrainedToSize:CGSizeMake(max_text_width,100)]; - CGRect percFrame = CGRectMake(5, left_label_y, max_text_width, optimumSize.height); - - if (self.hasOutline) { - CGContextSaveGState(ctx); - - CGContextSetLineWidth(ctx, 1.0f); - CGContextSetLineJoin(ctx, kCGLineJoinRound); - CGContextSetTextDrawingMode (ctx, kCGTextFillStroke); - CGContextSetRGBStrokeColor(ctx, 0.2f, 0.2f, 0.2f, 0.8f); - - [percentageText drawInRect:percFrame withFont:self.percentageFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; - - CGContextRestoreGState(ctx); - } else { - [percentageText drawInRect:percFrame withFont:self.percentageFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; - } - - if (self.showArrow) - { - // draw line to point to chart - CGContextSetRGBStrokeColor(ctx, 0.2f, 0.2f, 0.2f, 1); - CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - //CGContextSetRGBStrokeColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); - //CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); - //CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 5); - - - int x1 = radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; - int y1 = radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; - CGContextSetLineWidth(ctx, 1); - if (left_label_y + optimumSize.height/2 < y)//(left_label_y==LABEL_TOP_MARGIN) - { - - CGContextMoveToPoint(ctx, 5 + max_text_width, left_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, left_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, y1); - CGContextStrokePath(ctx); - - //CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - CGContextMoveToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); - CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_LENGTH); - CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - - } - else - { - - CGContextMoveToPoint(ctx, 5 + max_text_width, left_label_y + optimumSize.height/2); - if (left_label_y + optimumSize.height/2 > y + self.diameter) - { - CGContextAddLineToPoint(ctx, x1, left_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, y1); - CGContextStrokePath(ctx); - - //CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - CGContextMoveToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); - CGContextAddLineToPoint(ctx, x1, y1-ARROW_HEAD_LENGTH); - CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - } - else - { - float y_diff = y1 - (left_label_y + optimumSize.height/2); - if ( (y_diff < 2*ARROW_HEAD_LENGTH && y_diff>0) || (-1*y_diff < 2*ARROW_HEAD_LENGTH && y_diff<0)) - { - - // straight arrow - y1 = left_label_y + optimumSize.height/2; - - CGContextAddLineToPoint(ctx, x1, y1); - CGContextStrokePath(ctx); - - //CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - CGContextMoveToPoint(ctx, x1, y1-ARROW_HEAD_WIDTH/2); - CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_LENGTH, y1); - CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_WIDTH/2); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - } - else if (left_label_y + optimumSize.height/20) || (-1*y_diff < 2*ARROW_HEAD_LENGTH && y_diff<0)) - { - // straight arrow - y1 = right_label_y + optimumSize.height/2; - - CGContextMoveToPoint(ctx, text_x, right_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, y1); - CGContextStrokePath(ctx); - - //CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - CGContextMoveToPoint(ctx, x1, y1-ARROW_HEAD_WIDTH/2); - CGContextAddLineToPoint(ctx, x1-ARROW_HEAD_LENGTH, y1); - CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_WIDTH/2); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - } - else if (right_label_y + optimumSize.height/2180) - { - // arrow point up - y1 += ARROW_HEAD_LENGTH; - - CGContextMoveToPoint(ctx, text_x, right_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, right_label_y + optimumSize.height/2); - CGContextAddLineToPoint(ctx, x1, y1); - CGContextStrokePath(ctx); - - //CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); - CGContextMoveToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); - CGContextAddLineToPoint(ctx, x1, y1-ARROW_HEAD_LENGTH); - CGContextAddLineToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - } - } - } - - // display title on the left - CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); - right_label_y += optimumSize.height - 4; - optimumSize = [component.title sizeWithFont:self.titleFont constrainedToSize:CGSizeMake(max_text_width,100)]; - CGRect titleFrame = CGRectMake(text_x, right_label_y, optimumSize.width, optimumSize.height); - [component.title drawInRect:titleFrame withFont:self.titleFont]; - right_label_y += optimumSize.height + 10; - } - nextStartDeg = endDeg; + if (_showValuesInChart) { + float angle_rad = (-nextStartDeg - endDeg + 180)*0.5f / 180.f * M_PI; + float origin_x_label = cosf(angle_rad) * _diameter * 0.5f * 0.66f; + float origin_y_label = - sinf(angle_rad) * _diameter * 0.5f * 0.66f; + + CGContextSetShadow(ctx, CGSizeMake(0.2f, 0.1f), 3); + CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); + + //float text_x = x + 10; + NSString *percentageText = [NSString stringWithFormat:@"%.1f%%", component.value/total*100]; + CGSize optimumSize = [percentageText sizeWithFont:self.titleFont constrainedToSize:CGSizeMake(max_text_width,100)]; + CGRect percFrame = CGRectMake(origin_x+origin_x_label - _diameter * 0.33f, + origin_y+origin_y_label, + max_text_width, + optimumSize.height); + [percentageText drawInRect:percFrame withFont:self.titleFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + + + } + else { + if (nextStartDeg > 180 || (nextStartDeg < 180 && endDeg> 270) ) + { + // left + + // display percentage label + if (self.sameColorLabel) + { + CGContextSetFillColorWithColor(ctx, [component.colour CGColor]); + } + else + { + CGContextSetRGBFillColor(ctx, 0.1f, 0.1f, 0.1f, 1.0f); + } + CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 3); + + //float text_x = x + 10; + NSString *percentageText = [NSString stringWithFormat:@"%.1f%%", component.value/total*100]; + CGSize optimumSize = [percentageText sizeWithFont:self.percentageFont constrainedToSize:CGSizeMake(max_text_width,100)]; + CGRect percFrame = CGRectMake(5, left_label_y, max_text_width, optimumSize.height); + + if (self.hasOutline) { + CGContextSaveGState(ctx); + + CGContextSetLineWidth(ctx, 1.0f); + CGContextSetLineJoin(ctx, kCGLineJoinRound); + CGContextSetTextDrawingMode (ctx, kCGTextFillStroke); + CGContextSetRGBStrokeColor(ctx, 0.2f, 0.2f, 0.2f, 0.8f); + + [percentageText drawInRect:percFrame withFont:self.percentageFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + + CGContextRestoreGState(ctx); + } else { + [percentageText drawInRect:percFrame withFont:self.percentageFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + } + + if (self.showArrow) + { + // draw line to point to chart + CGContextSetRGBStrokeColor(ctx, 0.2f, 0.2f, 0.2f, 1); + CGContextSetRGBFillColor(ctx, 0.0f, 0.0f, 0.0f, 1.0f); + + int x1 = radius/4*3*cos((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_x; + int y1 = radius/4*3*sin((nextStartDeg+component.value/total*360/2-90)*M_PI/180.0)+origin_y; + CGContextSetLineWidth(ctx, 1); + if (left_label_y + optimumSize.height/2 < y)//(left_label_y==LABEL_TOP_MARGIN) + { + + CGContextMoveToPoint(ctx, 5 + max_text_width, left_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, left_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, y1); + CGContextStrokePath(ctx); + + CGContextMoveToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); + CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_LENGTH); + CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + + } + else + { + + CGContextMoveToPoint(ctx, 5 + max_text_width, left_label_y + optimumSize.height/2); + if (left_label_y + optimumSize.height/2 > y + self.diameter) + { + CGContextAddLineToPoint(ctx, x1, left_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, y1); + CGContextStrokePath(ctx); + + CGContextMoveToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); + CGContextAddLineToPoint(ctx, x1, y1-ARROW_HEAD_LENGTH); + CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + } + else + { + float y_diff = y1 - (left_label_y + optimumSize.height/2); + if ( (y_diff < 2*ARROW_HEAD_LENGTH && y_diff>0) || (-1*y_diff < 2*ARROW_HEAD_LENGTH && y_diff<0)) + { + + // straight arrow + y1 = left_label_y + optimumSize.height/2; + + CGContextAddLineToPoint(ctx, x1, y1); + CGContextStrokePath(ctx); + + CGContextMoveToPoint(ctx, x1, y1-ARROW_HEAD_WIDTH/2); + CGContextAddLineToPoint(ctx, x1+ARROW_HEAD_LENGTH, y1); + CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_WIDTH/2); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + } + else if (left_label_y + optimumSize.height/20) || (-1*y_diff < 2*ARROW_HEAD_LENGTH && y_diff<0)) + { + // straight arrow + y1 = right_label_y + optimumSize.height/2; + + CGContextMoveToPoint(ctx, text_x, right_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, y1); + CGContextStrokePath(ctx); + + CGContextMoveToPoint(ctx, x1, y1-ARROW_HEAD_WIDTH/2); + CGContextAddLineToPoint(ctx, x1-ARROW_HEAD_LENGTH, y1); + CGContextAddLineToPoint(ctx, x1, y1+ARROW_HEAD_WIDTH/2); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + } + else if (right_label_y + optimumSize.height/2180) + { + // arrow point up + y1 += ARROW_HEAD_LENGTH; + + CGContextMoveToPoint(ctx, text_x, right_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, right_label_y + optimumSize.height/2); + CGContextAddLineToPoint(ctx, x1, y1); + CGContextStrokePath(ctx); + + CGContextMoveToPoint(ctx, x1+ARROW_HEAD_WIDTH/2, y1); + CGContextAddLineToPoint(ctx, x1, y1-ARROW_HEAD_LENGTH); + CGContextAddLineToPoint(ctx, x1-ARROW_HEAD_WIDTH/2, y1); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + } + } + } + + // display title on the left + CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); + right_label_y += optimumSize.height - 4; + optimumSize = [component.title sizeWithFont:self.titleFont constrainedToSize:CGSizeMake(max_text_width,100)]; + CGRect titleFrame = CGRectMake(text_x, right_label_y, optimumSize.width, optimumSize.height); + if (_showValuesInChart == NO) { + [component.title drawInRect:titleFrame withFont:self.titleFont]; + } + right_label_y += optimumSize.height + 10; + } + } } if (_showInnerCircle) { CGContextRef ctx = UIGraphicsGetCurrentContext(); UIGraphicsPushContext(ctx); - CGFloat r,g,b,a; - UIColor *color = PCColorInnerCircle; - [color getRed:&r green:&g blue:&b alpha:&a]; - CGContextSetRGBFillColor(ctx, r, g, b, a); // white color + CGContextSetFillColorWithColor(ctx, [PCColorInnerCircle CGColor]); CGContextSetShadow(ctx, CGSizeMake(0.3f, 0.2f), margin); CGContextFillEllipseInRect(ctx, CGRectMake(x_innerCircle, @@ -500,10 +508,6 @@ - (void)drawRect:(CGRect)rect int fontSize = height; _titleFontInnerCircle = [UIFont boldSystemFontOfSize:fontSize]; - CGFloat r,g,b,a; - UIColor *color = PCColorTextInnerCircle; - [color getRed:&r green:&g blue:&b alpha:&a]; - CGFloat text_x = x_innerCircle + (_diameterInnerCircle - width) * 0.5f; CGFloat text_y = y_innerCircle + (_diameterInnerCircle - height) * 0.5f; @@ -511,7 +515,7 @@ - (void)drawRect:(CGRect)rect CGRect titleFrame = CGRectMake(text_x, text_y, width, height); UIGraphicsPushContext(ctx); - CGContextSetRGBFillColor(ctx, r, g, b, a); + CGContextSetFillColorWithColor(ctx, [PCColorTextInnerCircle CGColor]); [_titleInnerCircle drawInRect:titleFrame withFont:_titleFontInnerCircle lineBreakMode:UILineBreakModeWordWrap @@ -542,7 +546,7 @@ -(void)TapByUser:(id)sender NSLog(@"Touch inside Inner Circle"); return; } - + if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameter*0.5f,2.f)) NSLog(@"Touch inside"); From af8650675624c303dec6d5737c316163fb623099 Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Wed, 15 Aug 2012 17:31:49 -0300 Subject: [PATCH 08/17] . --- .../UserInterfaceState.xcuserstate | Bin 35414 -> 35415 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index f93b92c091dbf57d3365f2abbe7593a2157ce0fd..741bb1d9657a565a0ae021db1256f28a8dd8981f 100644 GIT binary patch delta 703 zcmWN;drZwy8~|{)8^iJ_WkTAbJTkO-&!%~edFL&!G?v|S&hLEB?|i>so6W6-w!C-M zAFLKLcZ_MSmL(#2t!d>^n@O}W>~2#?N?{jB~_|Is!~;{YE`T1RD)kNs}Jgv`l{NUdCpQN)5&u7 zI(g0&r`&0Ex}0v^Lwj{k-CsxQXgyfR>qUB*-mP3)^B_ZJYgUzuCXo z7yIErjKVlvfU9r~uEUL(i92x@`Y;!d;VCS}(|8txcmd0>94qh!R$(>PU?aZ5clezm zD3*p(JSEU5N}{>6f>zO5+Cb^FnSl0E4(+2n%BMqAKqtvxL?v{FF4I*irwXc~YPw7J z=^4GGHu_56se`(xn?3C10X&2gIf+N}Sf0u=coxs*IXsWoa|Z9^T`XAf9?s@mKEMb0 p2p{JF7x6g`@io5AH~9|VMeRajYiIbexZia0RZ$wU~)nxF3U9iTAJ?AL1jd$G`{tgsu1;+prxwOqhu>eM~*w23xT9vz?~bd-+MNea>#Dx-3`Lf5F0s^}Kg(kpsPU%5NS za4g4j0w;1Z&)@~@=cT-YSMeIwyp3~t2j}x{-owRwm;)tzj8E`+4skhO;YzOJ+kBUw zaRWE=Xa34RxScyBOnlN)`b&}|%U~HQsWL$($rPC`GiAAC%0}5FIih5%1SC&(NrCK> ogHk9Za!N|&vRswxa#QZeeW{juc_VG|XNxcFzoJP6vEdQ_08qL|E&u=k From 8ea7783ceec8f748d6abd47b4bf2cd866bfd9f11 Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Thu, 16 Aug 2012 10:30:35 -0300 Subject: [PATCH 09/17] . --- .../UserInterfaceState.xcuserstate | Bin 35415 -> 36312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index 741bb1d9657a565a0ae021db1256f28a8dd8981f..a0aedf4a44d7fb1d7e41f0cee8ab056110b76b26 100644 GIT binary patch delta 14388 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

r$ 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 From b60c71a154ad76073efa9eb4919e3028298d0e25 Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Thu, 16 Aug 2012 10:30:48 -0300 Subject: [PATCH 10/17] Fixed bug regarding possition of percent. --- .../UserInterfaceState.xcuserstate | Bin 36312 -> 36312 bytes iOSPlot/Shared/PCPieChart.m | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index a0aedf4a44d7fb1d7e41f0cee8ab056110b76b26..8de6ea250e99d68a86231265992735f4d3523317 100644 GIT binary patch delta 55 ycmcaHo9V`ErVZDF1a;fD=gf(zHZ?Oh(NQq8G%()$A}CNCBz(6FMc6B=PZ Date: Thu, 16 Aug 2012 10:35:30 -0300 Subject: [PATCH 11/17] Add shadow. --- .../UserInterfaceState.xcuserstate | Bin 36312 -> 36295 bytes iOSPlot/Shared/PCPieChart.m | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index 8de6ea250e99d68a86231265992735f4d3523317..83f78f0fb4973429dff6b833f51bb50abc2b3eb4 100644 GIT binary patch delta 8117 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 delta 8142 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 diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 0e5b51c..6417321 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -212,7 +212,7 @@ - (void)drawRect:(CGRect)rect float origin_x_label = cosf(angle_rad) * _diameter * 0.5f * 0.75f; float origin_y_label = - sinf(angle_rad) * _diameter * 0.5f * 0.75f; - CGContextSetShadow(ctx, CGSizeMake(0.2f, 0.1f), 3); + CGContextSetShadow(ctx, CGSizeMake(1.f, 1.0f), .6f); CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); //float text_x = x + 10; From 9c1bef3bbe8c41a3176705d81187b39ea60f6ead Mon Sep 17 00:00:00 2001 From: Gustavo Halperin Date: Thu, 16 Aug 2012 17:16:32 -0300 Subject: [PATCH 12/17] Add FPPopover files from FPPopover open projec and implementation as well from PieChart. --- iOSPlot/FPPopover/FPPopoverController.h | 63 ++ iOSPlot/FPPopover/FPPopoverController.m | 540 ++++++++++++++++++ iOSPlot/FPPopover/FPPopoverView.h | 57 ++ iOSPlot/FPPopover/FPPopoverView.m | 464 +++++++++++++++ iOSPlot/FPPopover/FPTouchView.h | 24 + iOSPlot/FPPopover/FPTouchView.m | 66 +++ iOSPlot/PieChartPopover.h | 21 + iOSPlot/PieChartPopover.m | 59 ++ iOSPlot/PieChartPopover.xib | 309 ++++++++++ iOSPlot/PieChartViewController3.m | 24 +- iOSPlot/PlotCreator.xcodeproj/project.pbxproj | 36 ++ .../UserInterfaceState.xcuserstate | Bin 36295 -> 26986 bytes iOSPlot/Shared/PCPieChart.h | 11 +- iOSPlot/Shared/PCPieChart.m | 14 + 14 files changed, 1685 insertions(+), 3 deletions(-) create mode 100644 iOSPlot/FPPopover/FPPopoverController.h create mode 100644 iOSPlot/FPPopover/FPPopoverController.m create mode 100644 iOSPlot/FPPopover/FPPopoverView.h create mode 100644 iOSPlot/FPPopover/FPPopoverView.m create mode 100644 iOSPlot/FPPopover/FPTouchView.h create mode 100644 iOSPlot/FPPopover/FPTouchView.m create mode 100644 iOSPlot/PieChartPopover.h create mode 100644 iOSPlot/PieChartPopover.m create mode 100644 iOSPlot/PieChartPopover.xib diff --git a/iOSPlot/FPPopover/FPPopoverController.h b/iOSPlot/FPPopover/FPPopoverController.h new file mode 100644 index 0000000..9d7155d --- /dev/null +++ b/iOSPlot/FPPopover/FPPopoverController.h @@ -0,0 +1,63 @@ +// +// FPPopoverController.h +// +// Created by Alvise Susmel on 1/5/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + +#import +#import + +#import "FPPopoverView.h" +#import "FPTouchView.h" + +@class FPPopoverController; +@protocol FPPopoverControllerDelegate + +@optional +- (void)popoverControllerDidDismissPopover:(FPPopoverController *)popoverController; +- (void)presentedNewPopoverController:(FPPopoverController *)newPopoverController + shouldDismissVisiblePopover:(FPPopoverController*)visiblePopoverController; +@end + +@interface FPPopoverController : UIViewController +{ + FPTouchView *_touchView; + FPPopoverView *_contentView; + UIViewController *_viewController; + UIWindow *_window; + UIView *_parentView; + UIView *_fromView; + UIDeviceOrientation _deviceOrientation; +} +@property(nonatomic,assign) id delegate; +/** @brief FPPopoverArrowDirectionAny, FPPopoverArrowDirectionVertical or FPPopoverArrowDirectionHorizontal for automatic arrow direction. + **/ +@property(nonatomic,assign) FPPopoverArrowDirection arrowDirection; + +@property(nonatomic,assign) CGSize contentSize; +@property(nonatomic,assign) CGPoint origin; + +/** @brief The tint of the popover. **/ +@property(nonatomic,assign) FPPopoverTint tint; + +/** @brief Initialize the popover with the content view controller + **/ +-(id)initWithViewController:(UIViewController*)viewController; + +/** @brief Presenting the popover from a specified view **/ +-(void)presentPopoverFromView:(UIView*)fromView; + +/** @brief Presenting the popover from a specified point **/ +-(void)presentPopoverFromPoint:(CGPoint)fromPoint; + + +/** @brief Dismiss the popover **/ +-(void)dismissPopoverAnimated:(BOOL)animated; + + + + + +@end diff --git a/iOSPlot/FPPopover/FPPopoverController.m b/iOSPlot/FPPopover/FPPopoverController.m new file mode 100644 index 0000000..d8bafef --- /dev/null +++ b/iOSPlot/FPPopover/FPPopoverController.m @@ -0,0 +1,540 @@ +// +// FPPopoverController.m +// +// Created by Alvise Susmel on 1/5/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + + +#import "FPPopoverController.h" + +@interface FPPopoverController() +@property UIInterfaceOrientation interfaceOrientation; + +-(CGPoint)originFromView:(UIView*)fromView; + + +-(CGFloat)parentWidth; +-(CGFloat)parentHeight; + +#pragma mark Space management +/* This methods help the controller to found a proper way to display the view. + * If the "from point" will be on the left, the arrow will be on the left and the + * view will be move on the right of the from point. + */ +-(CGRect)bestViewFrameForFromPoint:(CGPoint)point; + +-(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v; + +@end + +@implementation FPPopoverController +@synthesize interfaceOrientation = _interfaceOrientation; +@synthesize delegate = _delegate; +@synthesize contentSize = _contentSize; +@synthesize origin = _origin; +@synthesize arrowDirection = _arrowDirection; +@synthesize tint = _tint; + +-(void)addObservers +{ + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(deviceOrientationDidChange:) + name:@"UIDeviceOrientationDidChangeNotification" + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(willPresentNewPopover:) name:@"FPNewPopoverPresented" object:nil]; + + _deviceOrientation = [UIDevice currentDevice].orientation; + +} + +-(void)removeObservers +{ + [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [_viewController removeObserver:self forKeyPath:@"title"]; +} + + +-(void)dealloc +{ + [self removeObservers]; + [_touchView release]; + [_viewController release]; + [_contentView release]; + [_window release]; + [_parentView release]; + self.delegate = nil; + [super dealloc]; +} + + +-(id)initWithViewController:(UIViewController*)viewController +{ + self = [super init]; + if(self) + { + _interfaceOrientation = [[UIDevice currentDevice] orientation]; + + self.arrowDirection = FPPopoverArrowDirectionAny; + self.view.userInteractionEnabled = YES; + _touchView = [[FPTouchView alloc] initWithFrame:self.view.bounds]; + _touchView.backgroundColor = [UIColor clearColor]; + _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _touchView.clipsToBounds = NO; + [self.view addSubview:_touchView]; + [_touchView setTouchedOutsideBlock:^{ + [self dismissPopoverAnimated:YES]; + }]; + + + self.contentSize = viewController.view.frame.size;//CGSizeMake(200, 300); //default size + + _contentView = [[FPPopoverView alloc] initWithFrame:CGRectMake(0, 0, + self.contentSize.width, self.contentSize.height)]; + + _viewController = [viewController retain]; + + [_touchView addSubview:_contentView]; + + [_contentView addContentView:_viewController.view]; + _viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.view.clipsToBounds = NO; + + _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _touchView.clipsToBounds = NO; + + //setting contentview + _contentView.title = _viewController.title; + _contentView.clipsToBounds = NO; + + [_viewController addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; + } + return self; +} + + +-(void)setTint:(FPPopoverTint)tint +{ + _contentView.tint = tint; + [_contentView setNeedsDisplay]; +} + +-(FPPopoverTint)tint +{ + return _contentView.tint; +} + +#pragma mark - View lifecycle + +-(void)setupView +{ + self.view.frame = CGRectMake(0, 0, [self parentWidth], [self parentHeight]); + _touchView.frame = self.view.bounds; + + //view position, size and best arrow direction + [self bestArrowDirectionAndFrameFromView:_fromView]; + + [_contentView setNeedsDisplay]; + [_touchView setNeedsDisplay]; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + //initialize and load the content view + [_contentView setArrowDirection:FPPopoverArrowDirectionUp]; + [_contentView addContentView:_viewController.view]; + + [self setupView]; + [self addObservers]; +} + +#pragma mark Orientation + +-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation +{ + return YES; +} + +#pragma mark presenting + +-(CGFloat)parentWidth +{ + return _parentView.bounds.size.width; + return UIDeviceOrientationIsPortrait(_deviceOrientation) ? _parentView.frame.size.width : _parentView.frame.size.height; +} +-(CGFloat)parentHeight +{ + return _parentView.bounds.size.height; + return UIDeviceOrientationIsPortrait(_deviceOrientation) ? _parentView.frame.size.height : _parentView.frame.size.width; +} + +-(void)presentPopoverFromPoint:(CGPoint)fromPoint +{ + self.origin = fromPoint; + _contentView.relativeOrigin = [_parentView convertPoint:fromPoint toView:_contentView]; + + [self.view removeFromSuperview]; + NSArray *windows = [UIApplication sharedApplication].windows; + if(windows.count > 0) + { + [_window release]; [_parentView release]; _parentView=nil; + _window = [[windows objectAtIndex:0] retain]; + //keep the first subview + if(_window.subviews.count > 0) + { + [_parentView release]; + _parentView = [[_window.subviews objectAtIndex:0] retain]; + [_parentView addSubview:self.view]; + } + + } + else + { + [self dismissPopoverAnimated:NO]; + } + + + + [self setupView]; + self.view.alpha = 0.0; + [UIView animateWithDuration:0.2 animations:^{ + + self.view.alpha = 1.0; + }]; + + [[NSNotificationCenter defaultCenter] postNotificationName:@"FPNewPopoverPresented" object:self]; +} + +-(CGPoint)originFromView:(UIView*)fromView +{ + CGPoint p; + if([_contentView arrowDirection] == FPPopoverArrowDirectionUp) + { + p.x = fromView.frame.origin.x + fromView.frame.size.width/2.0; + p.y = fromView.frame.origin.y + fromView.frame.size.height; + } + else if([_contentView arrowDirection] == FPPopoverArrowDirectionDown) + { + p.x = fromView.frame.origin.x + fromView.frame.size.width/2.0; + p.y = fromView.frame.origin.y; + } + else if([_contentView arrowDirection] == FPPopoverArrowDirectionLeft) + { + p.x = fromView.frame.origin.x + fromView.frame.size.width; + p.y = fromView.frame.origin.y + fromView.frame.size.height/2.0; + } + else if([_contentView arrowDirection] == FPPopoverArrowDirectionRight) + { + p.x = fromView.frame.origin.x; + p.y = fromView.frame.origin.y + fromView.frame.size.height/2.0; + } + + return p; +} + +-(void)presentPopoverFromView:(UIView*)fromView +{ + [_fromView release]; _fromView = [fromView retain]; + [self presentPopoverFromPoint:[self originFromView:_fromView]]; +} + +-(void)dismissPopover +{ + [self.view removeFromSuperview]; + if([self.delegate respondsToSelector:@selector(popoverControllerDidDismissPopover:)]) + { + [self.delegate popoverControllerDidDismissPopover:self]; + } + [_window release]; _window=nil; + [_parentView release]; _parentView=nil; +} + +-(void)dismissPopoverAnimated:(BOOL)animated +{ + if(animated) + { + [UIView animateWithDuration:0.2 animations:^{ + self.view.alpha = 0.0; + } completion:^(BOOL finished) { + [self dismissPopover]; + }]; + } + else + { + [self dismissPopover]; + } + +} + +-(void)setOrigin:(CGPoint)origin +{ + _origin = origin; +} + +#pragma mark observing + + + +-(void)deviceOrientationDidChange:(NSNotification*)notification +{ + if ([[UIDevice currentDevice] orientation] != _interfaceOrientation) { + [self dismissPopoverAnimated:YES]; + } + _deviceOrientation = [UIDevice currentDevice].orientation; + + [UIView animateWithDuration:0.2 animations:^{ + [self setupView]; + }]; +} + +-(void)willPresentNewPopover:(NSNotification*)notification +{ + if(notification.object != self) + { + if([self.delegate respondsToSelector:@selector(presentedNewPopoverController:shouldDismissVisiblePopover:)]) + { + [self.delegate presentedNewPopoverController:notification.object + shouldDismissVisiblePopover:self]; + } + } +} + +-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if(object == _viewController && [keyPath isEqualToString:@"title"]) + { + _contentView.title = _viewController.title; + [_contentView setNeedsDisplay]; + } +} + + +#pragma mark Space management +/* This methods helps the controller to found a proper way to display the view. + * If the "from point" will be on the left, the arrow will be on the left and the + * view will be move on the right of the from point. + * + * Consider only x direction + * + * |--lm--|-----s-----|--rm--| + * + * s is the frame of our view (s < screen width). + * if our origin point is in lm or rm we move s + * if the origin point is in s we move the arrow + */ +-(CGRect)bestViewFrameForFromPoint:(CGPoint)point +{ + //content view size + CGRect r; + r.size = self.contentSize; + r.size.width += 20; + r.size.height += 50; + + //size limits + CGFloat w = MIN(r.size.width, [self parentWidth]); + CGFloat h = MIN(r.size.height,[self parentHeight]); + + r.size.width = (w == [self parentWidth]) ? [self parentWidth]-50 : w; + r.size.height = (h == [self parentHeight]) ? [self parentHeight]-30 : h; + + CGFloat r_w = r.size.width; + CGFloat r_h = r.size.height; + + //lm + rm + CGFloat wm = [self parentWidth] - r_w; + CGFloat wm_l = wm/2.0; + CGFloat ws = r_w; + CGFloat rm_x = wm_l + ws; + + CGFloat hm = [self parentHeight] - r_h; + CGFloat hm_t = hm/2.0; //top + CGFloat hs = r_h; + CGFloat hm_b = hm_t + hs; //bottom + + if(wm > 0) + { + //s < lm + rm + //our content size is smaller then width + + //15px are the number of point from the border to the arrow when the + //arrow is totally at left + //I have considered a standard border of 2px + + if(point.x+15 <= wm_l) + { + //move the popup to the left, with the left side near the origin point + r.origin.x = point.x-15; + } + else if(point.x+15 >= rm_x) + { + //move the popup to the right, with the right side near the origin point + r.origin.x = point.x - ws + 22; + } + + else + { + //the point is in the "s" zone and then I will move only the arrow + //put in the x center the popup + r.origin.x = wm_l; + } + } + + + if(hm > 0) + { + //the point is on the top + //let's move up the view + if(point.y <= hm_t) + { + r.origin.y = point.y; + } + //the point is on the bottom, + //let's move down the view + else if(point.y > hm_b) + { + r.origin.y = point.y - hs; + } + + else + { + //we need to resize the content + r.origin.y = point.y; + r.size.height = MIN(self.contentSize.height,[self parentHeight] - point.y - 10); //resizing + } + } + + return r; +} + +-(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v +{ + CGPoint p = [v.superview convertPoint:v.frame.origin toView:self.view]; + + CGFloat ht = p.y; //available vertical space on top of the view + CGFloat hb = [self parentHeight] - (p.y + v.frame.size.height); //on the bottom + CGFloat wl = p.x; //on the left + CGFloat wr = [self parentWidth] - (p.x + v.frame.size.width); //on the right + + CGFloat best_h = MAX(ht, hb); //much space down or up ? + CGFloat best_w = MAX(wl, wr); + + CGRect r; + r.size = self.contentSize; + + FPPopoverArrowDirection bestDirection; + + //if the user wants vertical arrow, check if the content will fit vertically + if(FPPopoverArrowDirectionIsVertical(self.arrowDirection) || + (self.arrowDirection == FPPopoverArrowDirectionAny && best_h >= best_w)) + { + + //ok, will be vertical + if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown) + { + //on the top and arrow down + bestDirection = FPPopoverArrowDirectionDown; + + r.origin.x = p.x + v.frame.size.width/2.0 - r.size.width/2.0; + r.origin.y = p.y - r.size.height; + } + else + { + //on the bottom and arrow up + bestDirection = FPPopoverArrowDirectionUp; + + r.origin.x = p.x + v.frame.size.width/2.0 - r.size.width/2.0; + r.origin.y = p.y + v.frame.size.height; + } + + + } + + + else + { + //ok, will be horizontal + if(wl == best_w || self.arrowDirection == FPPopoverArrowDirectionRight) + { + //on the left and arrow right + bestDirection = FPPopoverArrowDirectionRight; + + r.origin.x = p.x - r.size.width; + r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; + + } + else + { + //on the right then arrow left + bestDirection = FPPopoverArrowDirectionLeft; + + r.origin.x = p.x + v.frame.size.width; + r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; + } + + + } + + + + //need to moved left ? + if(r.origin.x + r.size.width > [self parentWidth]) + { + r.origin.x = [self parentWidth] - r.size.width; + } + + //need to moved right ? + else if(r.origin.x < 0) + { + r.origin.x = 0; + } + + + //need to move up? + if(r.origin.y < 0) + { + CGFloat old_y = r.origin.y; + r.origin.y = 0; + r.size.height += old_y; + } + + //need to be resized horizontally ? + if(r.origin.x + r.size.width > [self parentWidth]) + { + r.size.width = [self parentWidth] - r.origin.x; + } + + //need to be resized vertically ? + if(r.origin.y + r.size.height > [self parentHeight]) + { + r.size.height = [self parentHeight] - r.origin.y; + } + + + if([[UIApplication sharedApplication] isStatusBarHidden] == NO) + { + if(r.origin.y <= 20) r.origin.y += 20; + } + + _contentView.arrowDirection = bestDirection; + _contentView.frame = r; + + self.origin = CGPointMake(p.x + v.frame.size.width/2.0, p.y + v.frame.size.height/2.0); + _contentView.relativeOrigin = [_parentView convertPoint:self.origin toView:_contentView]; + + return r; +} + + + + +@end diff --git a/iOSPlot/FPPopover/FPPopoverView.h b/iOSPlot/FPPopover/FPPopoverView.h new file mode 100644 index 0000000..a528f08 --- /dev/null +++ b/iOSPlot/FPPopover/FPPopoverView.h @@ -0,0 +1,57 @@ +// +// FPPopoverView.h +// +// Created by Alvise Susmel on 1/4/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + + +#import +#import + +typedef enum { + FPPopoverArrowDirectionUp = 1UL << 0, + FPPopoverArrowDirectionDown = 1UL << 1, + FPPopoverArrowDirectionLeft = 1UL << 2, + FPPopoverArrowDirectionRight = 1UL << 3, + + FPPopoverArrowDirectionVertical = FPPopoverArrowDirectionUp | FPPopoverArrowDirectionDown, + FPPopoverArrowDirectionHorizontal = FPPopoverArrowDirectionLeft | FPPopoverArrowDirectionRight, + + FPPopoverArrowDirectionAny = FPPopoverArrowDirectionUp | FPPopoverArrowDirectionDown | + FPPopoverArrowDirectionLeft | FPPopoverArrowDirectionRight + +} FPPopoverArrowDirection; + + +#define FPPopoverArrowDirectionIsVertical(direction) ((direction) == FPPopoverArrowDirectionVertical || (direction) == FPPopoverArrowDirectionUp || (direction) == FPPopoverArrowDirectionDown) + +#define FPPopoverArrowDirectionIsHorizontal(direction) ((direction) == FPPopoverArrowDirectionHorizontal || (direction) == FPPopoverArrowDirectionLeft || (direction) == FPPopoverArrowDirectionRight) + + +typedef enum { + FPPopoverBlackTint = 1UL << 0, // default + FPPopoverLightGrayTint = 1UL << 1, + FPPopoverGreenTint = 1UL << 2, + FPPopoverRedTint = 1UL << 3, + FPPopoverDefaultTint = FPPopoverBlackTint +} FPPopoverTint; + +@interface FPPopoverView : UIView +{ + //default FPPopoverArrowDirectionUp + FPPopoverArrowDirection _arrowDirection; + UIView *_contentView; + UILabel *_titleLabel; +} +@property(nonatomic,retain) NSString *title; +@property(nonatomic,assign) CGPoint relativeOrigin; +@property(nonatomic,assign) FPPopoverTint tint; + +-(void)setArrowDirection:(FPPopoverArrowDirection)arrowDirection; +-(FPPopoverArrowDirection)arrowDirection; + +-(void)addContentView:(UIView*)contentView; + +@end diff --git a/iOSPlot/FPPopover/FPPopoverView.m b/iOSPlot/FPPopover/FPPopoverView.m new file mode 100644 index 0000000..8461841 --- /dev/null +++ b/iOSPlot/FPPopover/FPPopoverView.m @@ -0,0 +1,464 @@ +// +// FPPopoverView.m +// +// Created by Alvise Susmel on 1/4/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + + +#import "FPPopoverView.h" + +#define FP_POPOVER_ARROW_HEIGHT 20.0 +#define FP_POPOVER_ARROW_BASE 20.0 +#define FP_POPOVER_RADIUS 10.0 + + +@interface FPPopoverView(Private) +-(void)setupViews; +@end + + +@implementation FPPopoverView +@synthesize title; +@synthesize relativeOrigin; +@synthesize tint = _tint; + +-(void)dealloc +{ + self.title = nil; + [_contentView release]; + [_titleLabel release]; + [super dealloc]; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + + //we need to set the background as clear to see the view below + self.backgroundColor = [UIColor clearColor]; + self.clipsToBounds = YES; + + self.layer.shadowOpacity = 0.7; + self.layer.shadowRadius = 5; + self.layer.shadowOffset = CGSizeMake(-3, 3); + + //to get working the animations + self.contentMode = UIViewContentModeRedraw; + + + _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _titleLabel.backgroundColor = [UIColor clearColor]; + _titleLabel.textColor = [UIColor whiteColor]; + _titleLabel.textAlignment = UITextAlignmentCenter; + _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:16]; + + self.tint = FPPopoverDefaultTint; + + [self addSubview:_titleLabel]; + [self setupViews]; + } + return self; +} + +#pragma mark setters +-(void)setArrowDirection:(FPPopoverArrowDirection)arrowDirection +{ + _arrowDirection = arrowDirection; + [self setNeedsDisplay]; +} + +-(FPPopoverArrowDirection)arrowDirection +{ + return _arrowDirection; +} +-(void)addContentView:(UIView *)contentView +{ + if(_contentView != contentView) + { + [_contentView removeFromSuperview]; + [_contentView release]; + _contentView = [contentView retain]; + [self addSubview:_contentView]; + } + [self setupViews]; +} + +#pragma mark drawing + +//the content with the arrow +-(CGPathRef)newContentPathWithBorderWidth:(CGFloat)borderWidth arrowDirection:(FPPopoverArrowDirection)direction +{ + CGFloat w = self.bounds.size.width; + CGFloat h = self.bounds.size.height; + CGFloat ah = FP_POPOVER_ARROW_HEIGHT; //is the height of the triangle of the arrow + CGFloat aw = FP_POPOVER_ARROW_BASE/2.0; //is the 1/2 of the base of the arrow + CGFloat radius = FP_POPOVER_RADIUS; + CGFloat b = borderWidth; + + CGRect rect; + if(direction == FPPopoverArrowDirectionUp) + { + + rect.size.width = w - 2*b; + rect.size.height = h - ah - 2*b; + rect.origin.x = b; + rect.origin.y = ah + b; + } + else if(direction == FPPopoverArrowDirectionDown) + { + rect.size.width = w - 2*b; + rect.size.height = h - ah - 2*b; + rect.origin.x = b; + rect.origin.y = b; + } + + + else if(direction == FPPopoverArrowDirectionRight) + { + rect.size.width = w - ah - 2*b; + rect.size.height = h - 2*b; + rect.origin.x = b; + rect.origin.y = b; + } + else + { + //Assuming direction == FPPopoverArrowDirectionLeft to suppress static analyzer warnings + rect.size.width = w - ah - 2*b; + rect.size.height = h - 2*b; + rect.origin.x = ah + b; + rect.origin.y = b; + } + + //the arrow will be near the origin + CGFloat ax = self.relativeOrigin.x - aw; //the start of the arrow when UP or DOWN + if(ax < aw + b) ax = aw + b; + else if (ax +2*aw + 2*b> self.bounds.size.width) ax = self.bounds.size.width - 2*aw - 2*b; + + CGFloat ay = self.relativeOrigin.y - aw; //the start of the arrow when RIGHT or LEFT + if(ay < aw + b) ay = aw + b; + else if (ay +2*aw + 2*b > self.bounds.size.height) ay = self.bounds.size.height - 2*aw - 2*b; + + + //ROUNDED RECT + // arrow UP + CGRect innerRect = CGRectInset(rect, radius, radius); + CGFloat inside_right = innerRect.origin.x + innerRect.size.width; + CGFloat outside_right = rect.origin.x + rect.size.width; + CGFloat inside_bottom = innerRect.origin.y + innerRect.size.height; + CGFloat outside_bottom = rect.origin.y + rect.size.height; + CGFloat inside_top = innerRect.origin.y; + CGFloat outside_top = rect.origin.y; + CGFloat outside_left = rect.origin.x; + + + //drawing the border with arrow + CGMutablePathRef path = CGPathCreateMutable(); + + CGPathMoveToPoint(path, NULL, innerRect.origin.x, outside_top); + + //top arrow + if(direction == FPPopoverArrowDirectionUp) + { + CGPathAddLineToPoint(path, NULL, ax, ah+b); + CGPathAddLineToPoint(path, NULL, ax+aw, b); + CGPathAddLineToPoint(path, NULL, ax+2*aw, ah+b); + + } + + + CGPathAddLineToPoint(path, NULL, inside_right, outside_top); + CGPathAddArcToPoint(path, NULL, outside_right, outside_top, outside_right, inside_top, radius); + + //right arrow + if(direction == FPPopoverArrowDirectionRight) + { + CGPathAddLineToPoint(path, NULL, outside_right, ay); + CGPathAddLineToPoint(path, NULL, outside_right + ah+b, ay + aw); + CGPathAddLineToPoint(path, NULL, outside_right, ay + 2*aw); + } + + + CGPathAddLineToPoint(path, NULL, outside_right, inside_bottom); + CGPathAddArcToPoint(path, NULL, outside_right, outside_bottom, inside_right, outside_bottom, radius); + + //down arrow + if(direction == FPPopoverArrowDirectionDown) + { + CGPathAddLineToPoint(path, NULL, ax+2*aw, outside_bottom); + CGPathAddLineToPoint(path, NULL, ax+aw, outside_bottom + ah); + CGPathAddLineToPoint(path, NULL, ax, outside_bottom); + } + + CGPathAddLineToPoint(path, NULL, innerRect.origin.x, outside_bottom); + CGPathAddArcToPoint(path, NULL, outside_left, outside_bottom, outside_left, inside_bottom, radius); + + //left arrow + if(direction == FPPopoverArrowDirectionLeft) + { + CGPathAddLineToPoint(path, NULL, outside_left, ay + 2*aw); + CGPathAddLineToPoint(path, NULL, outside_left - ah-b, ay + aw); + CGPathAddLineToPoint(path, NULL, outside_left, ay); + } + + + CGPathAddLineToPoint(path, NULL, outside_left, inside_top); + CGPathAddArcToPoint(path, NULL, outside_left, outside_top, innerRect.origin.x, outside_top, radius); + + + CGPathCloseSubpath(path); + + return path; +} + + + +-(CGGradientRef)newGradient +{ + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + + // make a gradient + CGFloat colors[8]; + + if(self.tint == FPPopoverBlackTint) + { + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + colors[0] = colors[1] = colors[2] = 0.6; + colors[4] = colors[5] = colors[6] = 0.1; + colors[3] = colors[7] = 1.0; + } + else + { + colors[0] = colors[1] = colors[2] = 0.4; + colors[4] = colors[5] = colors[6] = 0.1; + colors[3] = colors[7] = 1.0; + } + } + + else if(self.tint == FPPopoverLightGrayTint) + { + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + colors[0] = colors[1] = colors[2] = 0.8; + colors[4] = colors[5] = colors[6] = 0.3; + colors[3] = colors[7] = 1.0; + } + else + { + colors[0] = colors[1] = colors[2] = 0.6; + colors[4] = colors[5] = colors[6] = 0.1; + colors[3] = colors[7] = 1.0; + } + } + else if(self.tint == FPPopoverRedTint) + { + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + colors[0] = 0.72; colors[1] = 0.35; colors[2] = 0.32; + colors[4] = 0.36; colors[5] = 0.0; colors[6] = 0.09; + colors[3] = colors[7] = 1.0; + + } + else + { + colors[0] = 0.82; colors[1] = 0.45; colors[2] = 0.42; + colors[4] = 0.36; colors[5] = 0.0; colors[6] = 0.09; + colors[3] = colors[7] = 1.0; + } + } + + else if(self.tint == FPPopoverGreenTint) + { + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + colors[0] = 0.35; colors[1] = 0.72; colors[2] = 0.17; + colors[4] = 0.18; colors[5] = 0.30; colors[6] = 0.03; + colors[3] = colors[7] = 1.0; + + } + else + { + colors[0] = 0.45; colors[1] = 0.82; colors[2] = 0.27; + colors[4] = 0.18; colors[5] = 0.30; colors[6] = 0.03; + colors[3] = colors[7] = 1.0; + } + } + + + + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2); + + CFRelease(colorSpace); + return gradient; +} + + + +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + + CGGradientRef gradient = [self newGradient]; + + + CGContextRef ctx = UIGraphicsGetCurrentContext(); + CGContextSaveGState(ctx); + + //content fill + CGPathRef contentPath = [self newContentPathWithBorderWidth:2.0 arrowDirection:_arrowDirection]; + + CGContextAddPath(ctx, contentPath); + CGContextClip(ctx); + + // Draw a linear gradient from top to bottom + CGPoint start; + CGPoint end; + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + start = CGPointMake(self.bounds.size.width/2.0, 0); + end = CGPointMake(self.bounds.size.width/2.0,40); + } + else + { + start = CGPointMake(self.bounds.size.width/2.0, 0); + end = CGPointMake(self.bounds.size.width/2.0,20); + } + + + + CGContextDrawLinearGradient(ctx, gradient, start, end, 0); + + CGGradientRelease(gradient); + //fill the other part of path + if(self.tint == FPPopoverBlackTint) + { + CGContextSetRGBFillColor(ctx, 0.1, 0.1, 0.1, 1.0); + } + else if(self.tint == FPPopoverLightGrayTint) + { + CGContextSetRGBFillColor(ctx, 0.3, 0.3, 0.3, 1.0); + } + else if(self.tint == FPPopoverRedTint) + { + CGContextSetRGBFillColor(ctx, 0.36, 0.0, 0.09, 1.0); + } + else if(self.tint == FPPopoverGreenTint) + { + CGContextSetRGBFillColor(ctx, 0.18, 0.30, 0.03, 1.0); + } + + + CGContextFillRect(ctx, CGRectMake(0, end.y, self.bounds.size.width, self.bounds.size.height-end.y)); + //internal border + CGContextBeginPath(ctx); + CGContextAddPath(ctx, contentPath); + CGContextSetRGBStrokeColor(ctx, 0.7, 0.7, 0.7, 1.0); + CGContextSetLineWidth(ctx, 1); + CGContextSetLineCap(ctx,kCGLineCapRound); + CGContextSetLineJoin(ctx, kCGLineJoinRound); + CGContextStrokePath(ctx); + CGPathRelease(contentPath); + + //external border + CGPathRef externalBorderPath = [self newContentPathWithBorderWidth:1.0 arrowDirection:_arrowDirection]; + CGContextBeginPath(ctx); + CGContextAddPath(ctx, externalBorderPath); + CGContextSetRGBStrokeColor(ctx, 0.4, 0.4, 0.4, 1.0); + CGContextSetLineWidth(ctx, 1); + CGContextSetLineCap(ctx,kCGLineCapRound); + CGContextSetLineJoin(ctx, kCGLineJoinRound); + CGContextStrokePath(ctx); + CGPathRelease(externalBorderPath); + + //3D border of the content view + CGRect cvRect = _contentView.frame; + //firstLine + CGContextSetRGBStrokeColor(ctx, 0.7, 0.7, 0.7, 1.0); + CGContextStrokeRect(ctx, cvRect); + //secondLine + cvRect.origin.x -= 1; cvRect.origin.y -= 1; cvRect.size.height += 2; cvRect.size.width += 2; + CGContextSetRGBStrokeColor(ctx, 0.4, 0.4, 0.4, 1.0); + CGContextStrokeRect(ctx, cvRect); + + + + CGContextRestoreGState(ctx); +} + +-(void)setupViews +{ + //content posizion and size + CGRect contentRect = _contentView.frame; + + if(_arrowDirection == FPPopoverArrowDirectionUp) + { + contentRect.origin = CGPointMake(10, 60); + contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-70); + _titleLabel.frame = CGRectMake(10, 30, self.bounds.size.width-20, 20); + if (self.title==nil || self.title.length==0) { + contentRect.origin = CGPointMake(10, 30); + contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-40); + } + } + else if(_arrowDirection == FPPopoverArrowDirectionDown) + { + contentRect.origin = CGPointMake(10, 40); + contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-70); + _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); + if (self.title==nil || self.title.length==0) { + contentRect.origin = CGPointMake(10, 10); + contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-40); + } + } + + + else if(_arrowDirection == FPPopoverArrowDirectionRight) + { + contentRect.origin = CGPointMake(10, 40); + contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-50); + _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); + if (self.title==nil || self.title.length==0) { + contentRect.origin = CGPointMake(10, 10); + contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-20); + } + } + + else if(_arrowDirection == FPPopoverArrowDirectionLeft) + { + contentRect.origin = CGPointMake(10 + FP_POPOVER_ARROW_HEIGHT, 40); + contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-50); + _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); + if (self.title==nil || self.title.length==0) { + contentRect.origin = CGPointMake(10+ FP_POPOVER_ARROW_HEIGHT, 10); + contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-20); + } + } + + _contentView.frame = contentRect; + _titleLabel.text = self.title; + +} + + +-(void)layoutSubviews +{ + [super layoutSubviews]; + [self setupViews]; +} + +-(void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + [self setupViews]; +} + +-(void)setBounds:(CGRect)bounds +{ + [super setBounds:bounds]; + [self setupViews]; +} +@end diff --git a/iOSPlot/FPPopover/FPTouchView.h b/iOSPlot/FPPopover/FPTouchView.h new file mode 100644 index 0000000..824665c --- /dev/null +++ b/iOSPlot/FPPopover/FPTouchView.h @@ -0,0 +1,24 @@ +// +// FPTouchView.h +// +// Created by Alvise Susmel on 4/16/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + +#import + +typedef void (^FPTouchedOutsideBlock)(); +typedef void (^FPTouchedInsideBlock)(); + +@interface FPTouchView : UIView +{ + FPTouchedOutsideBlock _outsideBlock; + FPTouchedInsideBlock _insideBlock; +} + +-(void)setTouchedOutsideBlock:(FPTouchedOutsideBlock)outsideBlock; + +-(void)setTouchedInsideBlock:(FPTouchedInsideBlock)insideBlock; + +@end diff --git a/iOSPlot/FPPopover/FPTouchView.m b/iOSPlot/FPPopover/FPTouchView.m new file mode 100644 index 0000000..e5bd5c9 --- /dev/null +++ b/iOSPlot/FPPopover/FPTouchView.m @@ -0,0 +1,66 @@ +// +// FPTouchView.m +// +// Created by Alvise Susmel on 4/16/12. +// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. +// +// https://github.com/50pixels/FPPopover + +#import "FPTouchView.h" + +@implementation FPTouchView + +-(void)dealloc +{ + [_outsideBlock release]; + [_insideBlock release]; + [super dealloc]; +} + +-(void)setTouchedOutsideBlock:(FPTouchedOutsideBlock)outsideBlock +{ + [_outsideBlock release]; + _outsideBlock = [outsideBlock copy]; +} + +-(void)setTouchedInsideBlock:(FPTouchedInsideBlock)insideBlock +{ + [_insideBlock release]; + _insideBlock = [insideBlock copy]; +} + +-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + UIView *subview = [super hitTest:point withEvent:event]; + + if(UIEventTypeTouches == event.type) + { + BOOL touchedInside = subview != self; + if(!touchedInside) + { + for(UIView *s in self.subviews) + { + if(s == subview) + { + //touched inside + touchedInside = YES; + break; + } + } + } + + if(touchedInside && _insideBlock) + { + _insideBlock(); + } + else if(!touchedInside && _outsideBlock) + { + _outsideBlock(); + } + } + + return subview; +} + + +@end diff --git a/iOSPlot/PieChartPopover.h b/iOSPlot/PieChartPopover.h new file mode 100644 index 0000000..c990d87 --- /dev/null +++ b/iOSPlot/PieChartPopover.h @@ -0,0 +1,21 @@ +// +// PieChartPopover.h +// PlotCreator +// +// Created by gustavo halperin on 8/16/12. +// +// + +#import + +@interface PieChartPopover : UIViewController + +@property (strong, nonatomic) IBOutlet NSString *tittle; +@property (strong, nonatomic) IBOutlet NSString *subTittle; +@property (strong, nonatomic) IBOutlet NSString *content; + +@property (strong, nonatomic) IBOutlet UILabel *tittleLabel; +@property (strong, nonatomic) IBOutlet UILabel *subTittleLabel; +@property (strong, nonatomic) IBOutlet UITextView *contentTextView; + +@end diff --git a/iOSPlot/PieChartPopover.m b/iOSPlot/PieChartPopover.m new file mode 100644 index 0000000..5e72aff --- /dev/null +++ b/iOSPlot/PieChartPopover.m @@ -0,0 +1,59 @@ +// +// PieChartPopover.m +// PlotCreator +// +// Created by gustavo halperin on 8/16/12. +// +// + +#import "PieChartPopover.h" + +@interface PieChartPopover () + +@end + +@implementation PieChartPopover +@synthesize tittle = _tittle; +@synthesize subTittle = _subTittle; +@synthesize content = _content; +@synthesize tittleLabel = _tittleLabel; +@synthesize subTittleLabel = _subTittleLabel; +@synthesize contentTextView = _contentTextView; + +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil +{ + self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; + if (self) { + // Custom initialization + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. + self.tittleLabel.text = _tittle; + self.subTittleLabel.text = _subTittle; + self.contentTextView.text = _content; +} + +- (void)viewDidUnload +{ + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + [self setTittle:nil]; + [self setSubTittle:nil]; + [self setContent:nil]; + [self setTittleLabel:nil]; + [self setSubTittleLabel:nil]; + [self setContentTextView:nil]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +{ + return YES; +} + +@end diff --git a/iOSPlot/PieChartPopover.xib b/iOSPlot/PieChartPopover.xib new file mode 100644 index 0000000..a49837a --- /dev/null +++ b/iOSPlot/PieChartPopover.xib @@ -0,0 +1,309 @@ + + + + 1296 + 12A269 + 2549 + 1187 + 624.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 1498 + + + IBProxyObject + IBUILabel + IBUITextView + IBUIView + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + PluginDependencyRecalculationVersion + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 274 + + + + 306 + {{20, 20}, {475, 45}} + + + _NS:9 + NO + YES + 7 + NO + IBIPadFramework + Label + + 0 + 10 + + TrebuchetMS-Bold + Trebuchet MS + 2 + 40 + + + TrebuchetMS-Bold + 40 + 16 + + + + + 306 + {{20, 73}, {475, 45}} + + + _NS:9 + NO + YES + 7 + NO + IBIPadFramework + Label + + 0 + 10 + + TrebuchetMS-Bold + Trebuchet MS + 2 + 26 + + + TrebuchetMS-Bold + 26 + 16 + + + + + 306 + {{157, 126}, {338, 233}} + + + _NS:9 + + 1 + MSAxIDEAA + + YES + YES + IBIPadFramework + NO + NO + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + 1 + MCAwIDEAA + + + 2 + IBCocoaTouchFramework + + + TrebuchetMS + Trebuchet MS + 0 + 14 + + + TrebuchetMS + 14 + 16 + + + + {515, 379} + + + + 3 + MQA + + NO + + IBUISimulatedFreeformSizeMetricsSentinel + Freeform + + IBIPadFramework + + + + + + + view + + + + 3 + + + + TittleLabel + + + + 8 + + + + subTittleLabel + + + + 9 + + + + tittleLabel + + + + 10 + + + + contentTextView + + + + 11 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + + + + + + 4 + + + + + 5 + + + + + 7 + + + + + + + PieChartPopover + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 11 + + + + + PieChartPopover + UIViewController + + NSString + UITextView + NSString + UILabel + NSString + UILabel + + + + content + NSString + + + contentTextView + UITextView + + + subTittle + NSString + + + subTittleLabel + UILabel + + + tittle + NSString + + + tittleLabel + UILabel + + + + IBProjectSource + ./Classes/PieChartPopover.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + YES + 3 + 1498 + + diff --git a/iOSPlot/PieChartViewController3.m b/iOSPlot/PieChartViewController3.m index 3918f28..851cce3 100644 --- a/iOSPlot/PieChartViewController3.m +++ b/iOSPlot/PieChartViewController3.m @@ -8,6 +8,13 @@ #import "PieChartViewController3.h" #import "PCPieChart.h" +#import "PieChartPopover.h" + +@interface PieChartViewController3() + +-(UIViewController*)ViewController: (PCPieComponent*)pieComponent; + +@end @implementation PieChartViewController3 @@ -23,7 +30,7 @@ - (id)init int height = [self.view bounds].size.width/3*2.; // 220; int width = [self.view bounds].size.width; //320; PCPieChart *pieChart = [[PCPieChart alloc] initWithFrame:CGRectMake(([self.view bounds].size.width-width)/2,([self.view bounds].size.height-height)/2,width,height)]; - [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; + [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; [pieChart setDiameter:width/2]; [pieChart setSameColorLabel:YES]; @@ -46,6 +53,7 @@ - (id)init { NSDictionary *item = [[sampleInfo objectForKey:@"data"] objectAtIndex:i]; PCPieComponent *component = [PCPieComponent pieComponentWithTitle:[item objectForKey:@"title"] value:[[item objectForKey:@"value"] floatValue]]; + component.delegate = self; [components addObject:component]; if (i==0) @@ -95,7 +103,19 @@ - (void)viewDidUnload { // e.g. self.myOutlet = nil; } - +-(UIViewController*)ViewController: (PCPieComponent*)pieComponent +{ + PieChartPopover *pieChartPopover = [[PieChartPopover alloc] init]; + [pieChartPopover setTittle:pieComponent.title]; + [pieChartPopover setSubTittle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; + NSString *content = [NSString stringWithFormat:@"Content for chart %@ and value %f ", pieComponent.title, pieComponent.value]; + for (int i = 0; i < 10; i++) { + content = [content stringByAppendingString:content]; + } + [pieChartPopover setContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; + + return pieChartPopover; +} @end diff --git a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj index 83d66e7..ee8d437 100755 --- a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj +++ b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj @@ -15,6 +15,11 @@ 2860E32E111B888700E27156 /* AppDelegate_iPad.m in Sources */ = {isa = PBXBuildFile; fileRef = 2860E32C111B888700E27156 /* AppDelegate_iPad.m */; }; 2860E32F111B888700E27156 /* MainWindow_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2860E32D111B888700E27156 /* MainWindow_iPad.xib */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + C96DD05715DD35EC00939DC6 /* FPPopoverController.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05215DD35EC00939DC6 /* FPPopoverController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C96DD05815DD35EC00939DC6 /* FPPopoverView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05415DD35EC00939DC6 /* FPPopoverView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C96DD05915DD35EC00939DC6 /* FPTouchView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05615DD35EC00939DC6 /* FPTouchView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C96DD05E15DD39B000939DC6 /* PieChartPopover.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05C15DD39B000939DC6 /* PieChartPopover.m */; }; + C96DD05F15DD39B000939DC6 /* PieChartPopover.xib in Resources */ = {isa = PBXBuildFile; fileRef = C96DD05D15DD39B000939DC6 /* PieChartPopover.xib */; }; C9B46D8E15DAE7880069B114 /* PieChartViewController3.m in Sources */ = {isa = PBXBuildFile; fileRef = C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */; }; F832606A1363D49B0045F9DC /* ChartListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F83260691363D49B0045F9DC /* ChartListViewController.m */; }; F83260AA1363D8170045F9DC /* back_button.png in Resources */ = {isa = PBXBuildFile; fileRef = F83260A81363D8170045F9DC /* back_button.png */; }; @@ -45,6 +50,15 @@ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Shared/main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* PlotCreator_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlotCreator_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* PlotCreator-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "PlotCreator-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + C96DD05115DD35EC00939DC6 /* FPPopoverController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPPopoverController.h; sourceTree = ""; }; + C96DD05215DD35EC00939DC6 /* FPPopoverController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FPPopoverController.m; sourceTree = ""; }; + C96DD05315DD35EC00939DC6 /* FPPopoverView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPPopoverView.h; sourceTree = ""; }; + C96DD05415DD35EC00939DC6 /* FPPopoverView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FPPopoverView.m; sourceTree = ""; }; + C96DD05515DD35EC00939DC6 /* FPTouchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPTouchView.h; sourceTree = ""; }; + C96DD05615DD35EC00939DC6 /* FPTouchView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FPTouchView.m; sourceTree = ""; }; + C96DD05B15DD39B000939DC6 /* PieChartPopover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PieChartPopover.h; sourceTree = ""; }; + C96DD05C15DD39B000939DC6 /* PieChartPopover.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PieChartPopover.m; sourceTree = ""; }; + C96DD05D15DD39B000939DC6 /* PieChartPopover.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PieChartPopover.xib; sourceTree = ""; }; C9B46D8C15DAE7880069B114 /* PieChartViewController3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PieChartViewController3.h; sourceTree = ""; }; C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PieChartViewController3.m; sourceTree = ""; }; F83260681363D49B0045F9DC /* ChartListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChartListViewController.h; path = iPhone/ChartListViewController.h; sourceTree = ""; }; @@ -116,6 +130,7 @@ 28EEBF621118D79A00187D67 /* Shared */ = { isa = PBXGroup; children = ( + C96DD05015DD35EC00939DC6 /* FPPopover */, 3794799B13706BB200C0E457 /* iOSPlot */, F8C1B407136F7FB7002DDF6C /* JSONKit */, F897D6FE136311E60025FE6E /* PieChartViewController.h */, @@ -131,6 +146,9 @@ F88CC4D113684FD30096327F /* LineChartViewController.h */, F88CC4D213684FD30096327F /* LineChartViewController.m */, 8D1107310486CEB800E47090 /* PlotCreator-Info.plist */, + C96DD05B15DD39B000939DC6 /* PieChartPopover.h */, + C96DD05C15DD39B000939DC6 /* PieChartPopover.m */, + C96DD05D15DD39B000939DC6 /* PieChartPopover.xib */, ); name = Shared; sourceTree = ""; @@ -183,6 +201,19 @@ name = iOSPlot; sourceTree = ""; }; + C96DD05015DD35EC00939DC6 /* FPPopover */ = { + isa = PBXGroup; + children = ( + C96DD05115DD35EC00939DC6 /* FPPopoverController.h */, + C96DD05215DD35EC00939DC6 /* FPPopoverController.m */, + C96DD05315DD35EC00939DC6 /* FPPopoverView.h */, + C96DD05415DD35EC00939DC6 /* FPPopoverView.m */, + C96DD05515DD35EC00939DC6 /* FPTouchView.h */, + C96DD05615DD35EC00939DC6 /* FPTouchView.m */, + ); + path = FPPopover; + sourceTree = ""; + }; F897D6E513630F4B0025FE6E /* Sample Data */ = { isa = PBXGroup; children = ( @@ -259,6 +290,7 @@ F83260AA1363D8170045F9DC /* back_button.png in Resources */, F83260AB1363D8170045F9DC /* back_button@2x.png in Resources */, F8C1B41C136F8056002DDF6C /* sample_linechart_data.json in Resources */, + C96DD05F15DD39B000939DC6 /* PieChartPopover.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -282,6 +314,10 @@ F87DE41D1370D82D00347F69 /* HalfPieChartViewController.m in Sources */, F8B8196215D573FB0005945A /* JSONKit.m in Sources */, C9B46D8E15DAE7880069B114 /* PieChartViewController3.m in Sources */, + C96DD05715DD35EC00939DC6 /* FPPopoverController.m in Sources */, + C96DD05815DD35EC00939DC6 /* FPPopoverView.m in Sources */, + C96DD05915DD35EC00939DC6 /* FPTouchView.m in Sources */, + C96DD05E15DD39B000939DC6 /* PieChartPopover.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate b/iOSPlot/PlotCreator.xcodeproj/project.xcworkspace/xcuserdata/gustavohalperin.xcuserdatad/UserInterfaceState.xcuserstate index 83f78f0fb4973429dff6b833f51bb50abc2b3eb4..98d8bbfc61f4a3db69b41c4285f84f3537b939ae 100644 GIT binary patch literal 26986 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 literal 36295 zcmdtL30xD`6F9zalRY>DG(iPXkV8?qZ#)SQAaW$;;8KVP5yFu`LJ&~vuC=xHzU{4G zZMC-ATHD&z9@ZXeZ>_!TecHRVwYIg@-@IKmBq)CMYrnt$(a-lQ$!6Znym|9x=FNLM zZ&7=z)!CVp^cH~#l8_N{f+A?2Y@g|s(OnjY(`vU>M%x!PTk1QVRnc{h`X(zpHb!^a z+eZ=T()HU$l6Mdc!4e8WNdyz|L;{gWBoWC(3Xw{r5$Qw*kx66``GlG%APR{hLPwMn z6+|tuh^Qyp2peH1+6foYMJyqDiKWCP#AU=4#5Kf?#I3|_#5!UQ0Se56JNs1VI1$B^U5a59pNA!EsDWCEE? zrjeQCbaED%L*|hMq=qaZwWOXjk(K0pvX-nP8^}honQSB5NhjGw_K?fS7350t67n+g z3i4|5I`T$xEqNPxC%K;7K;A=cChsS=k=w~f$erYqs zEMAr*OO<8FvSl-6b7Z+PwX8^1EGv`ElNn_dvT9k4Y@w`PwpeDBwaV-=hs-7GmMxWC zB;#ePWUFPD%dV1LE4x8^2g;*$)A=#C*LD~NxoP9 ziu_gioALwlx8?8156eH0ACZ3}|5pB;{CoKi@*m|t$$ysrEⓈQhtgeC`6Hzj2cOe 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 If0xGpA8cZG*8l(j diff --git a/iOSPlot/Shared/PCPieChart.h b/iOSPlot/Shared/PCPieChart.h index 90ed3e7..ccbc3b2 100644 --- a/iOSPlot/Shared/PCPieChart.h +++ b/iOSPlot/Shared/PCPieChart.h @@ -34,12 +34,16 @@ #import #import "PCPieChart.h" +@class PCPieComponent; + +@protocol PCPieComponentDelegate; + @interface PCPieComponent : NSObject @property (nonatomic, assign) float value, startDeg, endDeg; @property (nonatomic, strong) UIColor *colour; @property (nonatomic, copy) NSString *title; -@property (nonatomic, copy) NSString *titlePopover; @property (nonatomic, copy) NSString *contentPopover; +@property (nonatomic, weak) id delegate; - (id)initWithTitle:(NSString*)title value:(float)value; + (id)pieComponentWithTitle:(NSString*)title value:(float)value; @end @@ -61,3 +65,8 @@ @property (nonatomic, assign) BOOL showArrow, sameColorLabel, showInnerCircle, showValuesInChart; @property (nonatomic, assign, getter = hasOutline) BOOL outline; @end + +@protocol PCPieComponentDelegate +@required +-(UIViewController*)ViewController: (PCPieComponent*)pieComponent; +@end \ No newline at end of file diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 6417321..3663904 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -32,6 +32,7 @@ */ #import "PCPieChart.h" +#import "FPPopoverController.h" @implementation PCPieComponent @@ -576,6 +577,19 @@ -(void)TapByUser:(id)sender if (angle > startDeg && angle < endDeg) { NSLog(@"Portion %@ with value %f%% and percent %.1f%% was touched", component.title, component.value, component.value/total*100.f); + if (component.delegate) { + UIViewController *viewController = [component.delegate ViewController:component]; + FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; + CGPoint point = CGPointMake(self.frame.origin.x + touchPointOnSelf.x, self.frame.origin.y + touchPointOnSelf.y); + //[popoverController presentPopoverFromPoint:point]; + UIView *view = [[UIView alloc] initWithFrame:CGRectMake(point.x-self.frame.origin.x, + point.y-self.frame.origin.y, + 1, + 1)]; + [self addSubview:view]; + [popoverController presentPopoverFromView:view]; + [view removeFromSuperview]; + } break; } startDeg = endDeg; From ce51ace26c7776cd079b2c30d6381fdf8861d008 Mon Sep 17 00:00:00 2001 From: gustavo halperin Date: Fri, 17 Aug 2012 18:58:37 -0300 Subject: [PATCH 13/17] partial commit. Was added a new PieChart example with animation. I have a bug regarding the moment that the chart need to stop. Was fixed a bug regarding the position of the percent in the chart so now is perfect centered. --- iOSPlot/.DS_Store | Bin 0 -> 6148 bytes iOSPlot/PieChartViewController4.h | 13 + iOSPlot/PieChartViewController4.m | 122 ++++++ iOSPlot/PlotCreator.xcodeproj/project.pbxproj | 6 + .../Sample Data/sample_piechart_data.plist | 4 +- iOSPlot/Shared/PCPieChart.h | 4 +- iOSPlot/Shared/PCPieChart.m | 409 +++++++++++------- iOSPlot/iPhone/ChartListViewController.m | 13 +- 8 files changed, 411 insertions(+), 160 deletions(-) create mode 100644 iOSPlot/.DS_Store create mode 100644 iOSPlot/PieChartViewController4.h create mode 100644 iOSPlot/PieChartViewController4.m diff --git a/iOSPlot/.DS_Store b/iOSPlot/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4b6cdc613a4bacae6d9e4e81b9acee367db2a0a2 GIT binary patch literal 6148 zcmeHK!AiqG5Pj43Q1H@=;Bmh|=pTd{??U|mB@sm$5=sgl^DBaX;V<}6zL{C2#axOY zqBF4bCc8VcI}ftE13*^0dI>B5%-Ix0jS7xJ8e4B+zf{(!HPJ z3LEaY$Nv7eIL8wz_Sej*V`eQLH}}hR)i#}_GI@DD&bw*LvflL-@OIriTZ|*tZrb`A z-rd9A&Zo&14;2gq1HnKr@GlwQovkuIaSR;{1OvgqCj)vuBsRq&_W^-Fqs*Cw_bHWi&Ws6nB9@Ce|C ho+D>A=;KLk&MPtwjv7V#&7Bwz0V5<-Fz^EmyaOELK<@wm literal 0 HcmV?d00001 diff --git a/iOSPlot/PieChartViewController4.h b/iOSPlot/PieChartViewController4.h new file mode 100644 index 0000000..495497b --- /dev/null +++ b/iOSPlot/PieChartViewController4.h @@ -0,0 +1,13 @@ +// +// PieChartViewController4 +// PlotCreator +// +// Created by Gustavo E Halperin on 8/17/12. +// +// + +#import + +@interface PieChartViewController4 : UIViewController + +@end diff --git a/iOSPlot/PieChartViewController4.m b/iOSPlot/PieChartViewController4.m new file mode 100644 index 0000000..f392840 --- /dev/null +++ b/iOSPlot/PieChartViewController4.m @@ -0,0 +1,122 @@ +// +// PieChartViewController4 +// PlotCreator +// +// Created by Gustavo E Halperin on 8/17/12. +// +// + +#import "PieChartViewController4.h" +#import "PCPieChart.h" +#import "PieChartPopover.h" + +@interface PieChartViewController4() + +-(UIViewController*)ViewController: (PCPieComponent*)pieComponent; + +@end + +@implementation PieChartViewController4 + +- (id)init +{ + self = [super init]; + if (self) + { + [self.view setBackgroundColor:[UIColor colorWithWhite:1 alpha:1]]; + [self setTitle:@"Pie Chart"]; + + + int height = [self.view bounds].size.width/3*2.; // 220; + int width = [self.view bounds].size.width; //320; + PCPieChart *pieChart = [[PCPieChart alloc] initWithFrame:CGRectMake(([self.view bounds].size.width-width)/2,([self.view bounds].size.height-height)/2,width,height)]; + [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; + [pieChart setDiameter:width/2]; + [pieChart setSameColorLabel:YES]; + + [pieChart setShowInnerCircle:YES]; + [pieChart setTitleInnerCircle:@"Center Title"]; + [pieChart setShowValuesInChart:YES]; + [pieChart setTouchAnimated:YES]; + + [self.view addSubview:pieChart]; + + if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad) + { + pieChart.titleFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:30]; + pieChart.percentageFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:50]; + } + + NSString *sampleFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"sample_piechart_data.plist"]; + NSDictionary *sampleInfo = [NSDictionary dictionaryWithContentsOfFile:sampleFile]; + NSMutableArray *components = [NSMutableArray array]; + for (int i=0; i<[[sampleInfo objectForKey:@"data"] count]; i++) + { + NSDictionary *item = [[sampleInfo objectForKey:@"data"] objectAtIndex:i]; + PCPieComponent *component = [PCPieComponent pieComponentWithTitle:[item objectForKey:@"title"] value:[[item objectForKey:@"value"] floatValue]]; + component.delegate = self; + [components addObject:component]; + + if (i==0) + { + [component setColour:PCColorYellow]; + } + else if (i==1) + { + [component setColour:PCColorGreen]; + } + else if (i==2) + { + [component setColour:PCColorOrange]; + } + else if (i==3) + { + [component setColour:PCColorRed]; + } + else if (i==4) + { + [component setColour:PCColorBlue]; + } + } + [pieChart setComponents:components]; + + } + return self; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Overriden to allow any orientation. + return YES; +} + + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc. that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + +-(UIViewController*)ViewController: (PCPieComponent*)pieComponent +{ + PieChartPopover *pieChartPopover = [[PieChartPopover alloc] init]; + [pieChartPopover setTittle:pieComponent.title]; + [pieChartPopover setSubTittle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; + NSString *content = [NSString stringWithFormat:@"Content for chart %@ and value %f ", pieComponent.title, pieComponent.value]; + for (int i = 0; i < 10; i++) { + content = [content stringByAppendingString:content]; + } + [pieChartPopover setContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; + + return pieChartPopover; +} + + +@end diff --git a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj index ee8d437..dd2f724 100755 --- a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj +++ b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 2860E32E111B888700E27156 /* AppDelegate_iPad.m in Sources */ = {isa = PBXBuildFile; fileRef = 2860E32C111B888700E27156 /* AppDelegate_iPad.m */; }; 2860E32F111B888700E27156 /* MainWindow_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2860E32D111B888700E27156 /* MainWindow_iPad.xib */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 929C6EC415DEF4AC008FD849 /* PieChartViewController4.m in Sources */ = {isa = PBXBuildFile; fileRef = 929C6EC315DEF4AC008FD849 /* PieChartViewController4.m */; }; C96DD05715DD35EC00939DC6 /* FPPopoverController.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05215DD35EC00939DC6 /* FPPopoverController.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C96DD05815DD35EC00939DC6 /* FPPopoverView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05415DD35EC00939DC6 /* FPPopoverView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C96DD05915DD35EC00939DC6 /* FPTouchView.m in Sources */ = {isa = PBXBuildFile; fileRef = C96DD05615DD35EC00939DC6 /* FPTouchView.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; @@ -50,6 +51,8 @@ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Shared/main.m; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* PlotCreator_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlotCreator_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* PlotCreator-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "PlotCreator-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 929C6EC215DEF4AC008FD849 /* PieChartViewController4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PieChartViewController4.h; sourceTree = ""; }; + 929C6EC315DEF4AC008FD849 /* PieChartViewController4.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PieChartViewController4.m; sourceTree = ""; }; C96DD05115DD35EC00939DC6 /* FPPopoverController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPPopoverController.h; sourceTree = ""; }; C96DD05215DD35EC00939DC6 /* FPPopoverController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FPPopoverController.m; sourceTree = ""; }; C96DD05315DD35EC00939DC6 /* FPPopoverView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FPPopoverView.h; sourceTree = ""; }; @@ -139,6 +142,8 @@ F83260C11363D91E0045F9DC /* PieChartViewController2.m */, C9B46D8C15DAE7880069B114 /* PieChartViewController3.h */, C9B46D8D15DAE7880069B114 /* PieChartViewController3.m */, + 929C6EC215DEF4AC008FD849 /* PieChartViewController4.h */, + 929C6EC315DEF4AC008FD849 /* PieChartViewController4.m */, F87DE41B1370D82D00347F69 /* HalfPieChartViewController.h */, F87DE41C1370D82D00347F69 /* HalfPieChartViewController.m */, F83260681363D49B0045F9DC /* ChartListViewController.h */, @@ -318,6 +323,7 @@ C96DD05815DD35EC00939DC6 /* FPPopoverView.m in Sources */, C96DD05915DD35EC00939DC6 /* FPTouchView.m in Sources */, C96DD05E15DD39B000939DC6 /* PieChartPopover.m in Sources */, + 929C6EC415DEF4AC008FD849 /* PieChartViewController4.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iOSPlot/Sample Data/sample_piechart_data.plist b/iOSPlot/Sample Data/sample_piechart_data.plist index 83f998d..9da8b85 100644 --- a/iOSPlot/Sample Data/sample_piechart_data.plist +++ b/iOSPlot/Sample Data/sample_piechart_data.plist @@ -20,13 +20,13 @@ title CCC value - 10 + 30 title DDD value - 30 + 10 title diff --git a/iOSPlot/Shared/PCPieChart.h b/iOSPlot/Shared/PCPieChart.h index ccbc3b2..4f549aa 100644 --- a/iOSPlot/Shared/PCPieChart.h +++ b/iOSPlot/Shared/PCPieChart.h @@ -39,7 +39,7 @@ @protocol PCPieComponentDelegate; @interface PCPieComponent : NSObject -@property (nonatomic, assign) float value, startDeg, endDeg; +@property (nonatomic, assign) float value; @property (nonatomic, strong) UIColor *colour; @property (nonatomic, copy) NSString *title; @property (nonatomic, copy) NSString *contentPopover; @@ -62,7 +62,7 @@ @property (nonatomic, strong) NSMutableArray *components; @property (nonatomic, strong) UIFont *titleFont, *percentageFont; @property (nonatomic, strong) NSString *titleInnerCircle; -@property (nonatomic, assign) BOOL showArrow, sameColorLabel, showInnerCircle, showValuesInChart; +@property (nonatomic, assign) BOOL showArrow, sameColorLabel, showInnerCircle, showValuesInChart, touchAnimated; @property (nonatomic, assign, getter = hasOutline) BOOL outline; @end diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 3663904..ba7f078 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -34,6 +34,12 @@ #import "PCPieChart.h" #import "FPPopoverController.h" +@interface PCPieComponent() + +@property float startDeg, endDeg; + +@end + @implementation PCPieComponent - (id)initWithTitle:(NSString*)title value:(float)value @@ -67,10 +73,17 @@ @interface PCPieChart() @property (strong, nonatomic) UITapGestureRecognizer *tapGesture; +@property (nonatomic, assign) float deltaRotation; @property (nonatomic, assign) int diameterInnerCircle; @property (nonatomic, strong) UIFont *titleFontInnerCircle; +- (void)drawCicleBackground: (CGPoint)center; +- (void)drawInnerCircle: (CGPoint)center; +- (void)drawChartPortions: (CGPoint)center; +- (void)drawPercentValuesOnChart: (CGPoint)center; + -(void)TapByUser:(id)sender; +-(void)addDeltaAngleTillCenter: (id)obj; @end @@ -93,10 +106,42 @@ - (id)initWithFrame:(CGRect)frame _tapGesture.numberOfTapsRequired=1; [self addGestureRecognizer:_tapGesture]; + self.deltaRotation = 0; + } return self; } +- (void)setDeltaRotation:(float)deltaRotation +{ + _deltaRotation = deltaRotation; + if (_deltaRotation >= 360.f) { + _deltaRotation = remainderf(_deltaRotation, 360.f); + } +} + +- (void)setComponents:(NSMutableArray *)components +{ + if (_components) { + _components = nil; + } + _components = components; + float total = 0; + for (PCPieComponent *component in self.components) + total += component.value; + + float nextStartDeg = _deltaRotation; + float endDeg = 0; + for (PCPieComponent *component in _components) { + float perc = [component value]/total; + endDeg = nextStartDeg+perc*360; + + [component setStartDeg:nextStartDeg]; + [component setEndDeg:endDeg]; + nextStartDeg = endDeg; + } +} + - (void)setShowArrow:(BOOL)showArrow { _showArrow = showArrow; @@ -113,31 +158,142 @@ - (void)setShowValuesInChart:(BOOL)showValuesInChart } } -#define LABEL_TOP_MARGIN 15 +#define MARGIN 15 #define ARROW_HEAD_LENGTH 6 #define ARROW_HEAD_WIDTH 4 +#pragma mark draw methods +- (void)drawCicleBackground: (CGPoint)center +{ + CGContextRef ctx = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(ctx); + CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); // white color + CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 15); + // a white filled circle with a diameter of 100 pixels, centered in (60, 60) + CGContextFillEllipseInRect(ctx, CGRectMake(center.x, center.y, self.diameter, self.diameter)); + UIGraphicsPopContext(); + CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 0); +} + +- (void)drawInnerCircle: (CGPoint)center +{ + float x_innerCircle = center.x - _diameterInnerCircle * 0.5f; + float y_innerCircle = center.y - _diameterInnerCircle * 0.5f; + CGContextRef ctx = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(ctx); + CGContextSetFillColorWithColor(ctx, [PCColorInnerCircle CGColor]); + CGContextSetShadow(ctx, CGSizeMake(0.3f, 0.2f), MARGIN); + CGContextFillEllipseInRect(ctx, + CGRectMake(x_innerCircle, + y_innerCircle, + _diameterInnerCircle, + _diameterInnerCircle)); + UIGraphicsPopContext(); + + if (_titleInnerCircle) { + float width = cosf(25) * _diameterInnerCircle; + if (width < 8) + width = 8; + float height = fabsf(sinf(25) * _diameterInnerCircle); + int fontSize = height; + _titleFontInnerCircle = [UIFont boldSystemFontOfSize:fontSize]; + + CGFloat text_x = x_innerCircle + (_diameterInnerCircle - width) * 0.5f; + CGFloat text_y = y_innerCircle + (_diameterInnerCircle - height) * 0.5f; + + + CGRect titleFrame = CGRectMake(text_x, text_y, width, height); + + UIGraphicsPushContext(ctx); + CGContextSetFillColorWithColor(ctx, [PCColorTextInnerCircle CGColor]); + [_titleInnerCircle drawInRect:titleFrame + withFont:_titleFontInnerCircle + lineBreakMode:UILineBreakModeWordWrap + alignment:UITextAlignmentCenter]; + UIGraphicsPopContext(); + } +} + +- (void)drawChartPortions: (CGPoint)center +{ + float radius = self.diameter * 0.5f; + float gap = 1; + CGContextRef ctx = UIGraphicsGetCurrentContext(); + for (PCPieComponent *component in _components) + { + //float perc = component.value / total; + //endDeg = nextStartDeg+perc*360; + + CGContextSetFillColorWithColor(ctx, [component.colour CGColor]); + CGContextMoveToPoint(ctx, center.x, center.y); + //CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); + CGContextAddArc(ctx, center.x, center.y, radius, + (component.startDeg-90+_deltaRotation)*M_PI/180.0, (component.endDeg-90+_deltaRotation)*M_PI/180.0, 0); + CGContextClosePath(ctx); + CGContextFillPath(ctx); + + CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); + CGContextSetLineWidth(ctx, gap); + CGContextMoveToPoint(ctx, center.x, center.y); + //CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); + CGContextAddArc(ctx, center.x, center.y, radius, + (component.startDeg-90+_deltaRotation)*M_PI/180.0, (component.endDeg-90+_deltaRotation)*M_PI/180.0, 0); + CGContextClosePath(ctx); + CGContextStrokePath(ctx); + + //nextStartDeg = endDeg; + } +} + +- (void)drawPercentValuesOnChart: (CGPoint)center +{ + float nextStartDeg; + float endDeg = 0; + float total = 0; + for (PCPieComponent *component in self.components) + total += component.value; + + CGContextRef ctx = UIGraphicsGetCurrentContext(); + for (PCPieComponent *component in _components) + { + nextStartDeg = component.startDeg + _deltaRotation; + endDeg = component.endDeg + _deltaRotation; + + float angle_rad = (-nextStartDeg - endDeg + 180)*0.5f / 180.f * M_PI; + float origin_x_label = cosf(angle_rad) * _diameter * 0.5f * 0.75f; + float origin_y_label = - sinf(angle_rad) * _diameter * 0.5f * 0.75f; + + CGContextSetShadow(ctx, CGSizeMake(1.f, 1.0f), .6f); + CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); + + //float text_x = x + 10; + NSString *percentageText = [NSString stringWithFormat:@"%.1f%%", component.value/total*100]; + CGSize optimumSize = [percentageText sizeWithFont:self.titleFont]; + CGRect percFrame = CGRectMake(center.x+origin_x_label - optimumSize.width * 0.5f, + center.y+origin_y_label - optimumSize.height * 0.5f, + optimumSize.width, + optimumSize.height); + [percentageText drawInRect:percFrame withFont:self.titleFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + } +} + - (void)drawRect:(CGRect)rect { - float margin = 15; if (self.diameter==0) { - self.diameter = MIN(rect.size.width, rect.size.height) - 2*margin; + self.diameter = MIN(rect.size.width, rect.size.height) - 2 * MARGIN; } - float x = (rect.size.width - self.diameter)/2; - float y = (rect.size.height - self.diameter)/2; - float gap = 1; - float radius = self.diameter/2; - float origin_x = x + self.diameter/2; - float origin_y = y + self.diameter/2; + float x = (rect.size.width - self.diameter) * 0.5f; + float y = (rect.size.height - self.diameter) * 0.5f; + float radius = self.diameter * 0.5f; + float origin_x = x + self.diameter * 0.5f; + float origin_y = y + self.diameter * 0.5f; _diameterInnerCircle = self.diameter / 3.f; - float x_innerCircle = x + radius - _diameterInnerCircle / 2.f; - float y_innerCircle = y + radius - _diameterInnerCircle / 2.f; // label stuff - float left_label_y = LABEL_TOP_MARGIN; - float right_label_y = LABEL_TOP_MARGIN; + float left_label_y = MARGIN; + float right_label_y = MARGIN; if ([self.components count]>0) { @@ -149,85 +305,43 @@ - (void)drawRect:(CGRect)rect } CGContextRef ctx = UIGraphicsGetCurrentContext(); - UIGraphicsPushContext(ctx); - CGContextSetRGBFillColor(ctx, 1.0f, 1.0f, 1.0f, 1.0f); // white color - CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), margin); - CGContextFillEllipseInRect(ctx, CGRectMake(x, y, self.diameter, self.diameter)); // a white filled circle with a diameter of 100 pixels, centered in (60, 60) - UIGraphicsPopContext(); - CGContextSetShadow(ctx, CGSizeMake(0.0f, 0.0f), 0); - - float nextStartDeg = 0; + + [self drawCicleBackground: CGPointMake(x, y)]; + + float nextStartDeg; float endDeg = 0; - NSMutableArray *tmpComponents = [NSMutableArray array]; - int last_insert = -1; - for (int i=0; i<[self.components count]; i++) - { - PCPieComponent *component = [self.components objectAtIndex:i]; - float perc = [component value]/total; - endDeg = nextStartDeg+perc*360; - - CGContextSetFillColorWithColor(ctx, [component.colour CGColor]); - CGContextMoveToPoint(ctx, origin_x, origin_y); - CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); - CGContextClosePath(ctx); - CGContextFillPath(ctx); - - CGContextSetRGBStrokeColor(ctx, 1, 1, 1, 1); - CGContextSetLineWidth(ctx, gap); - CGContextMoveToPoint(ctx, origin_x, origin_y); - CGContextAddArc(ctx, origin_x, origin_y, radius, (nextStartDeg-90)*M_PI/180.0, (endDeg-90)*M_PI/180.0, 0); - CGContextClosePath(ctx); - CGContextStrokePath(ctx); - - [component setStartDeg:nextStartDeg]; - [component setEndDeg:endDeg]; - if (nextStartDeg<180) - { - [tmpComponents addObject:component]; - } - else - { - if (last_insert==-1) - { - last_insert = i; - [tmpComponents addObject:component]; - } - else - { - [tmpComponents insertObject:component atIndex:last_insert]; - } - } - - nextStartDeg = endDeg; - } - - float max_text_width = x - 10; - for (int i=0; i<[tmpComponents count]; i++) - { - PCPieComponent *component = [tmpComponents objectAtIndex:i]; - nextStartDeg = component.startDeg; - endDeg = component.endDeg; - - if (_showValuesInChart) { - float angle_rad = (-nextStartDeg - endDeg + 180)*0.5f / 180.f * M_PI; - float origin_x_label = cosf(angle_rad) * _diameter * 0.5f * 0.75f; - float origin_y_label = - sinf(angle_rad) * _diameter * 0.5f * 0.75f; - - CGContextSetShadow(ctx, CGSizeMake(1.f, 1.0f), .6f); - CGContextSetRGBFillColor(ctx, 0.4f, 0.4f, 0.4f, 1.0f); - - //float text_x = x + 10; - NSString *percentageText = [NSString stringWithFormat:@"%.1f%%", component.value/total*100]; - CGSize optimumSize = [percentageText sizeWithFont:self.titleFont constrainedToSize:CGSizeMake(max_text_width,100)]; - CGRect percFrame = CGRectMake(origin_x+origin_x_label - _diameter * 0.25f - optimumSize.width * 0.5f, - origin_y+origin_y_label - optimumSize.height * 0.5f, - max_text_width, - optimumSize.height); - [percentageText drawInRect:percFrame withFont:self.titleFont lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentRight]; + + [self drawChartPortions: CGPointMake(origin_x, origin_y)]; + + float max_text_width = x - 10; + + + if (_showValuesInChart) { + [self drawPercentValuesOnChart:CGPointMake(origin_x, origin_y)]; + } + else { + + NSArray *sortedArray = [_components sortedArrayUsingComparator: ^(id obj1, id obj2) { + PCPieComponent *component1 = obj1; + PCPieComponent *component2 = obj2; + if (component1.startDeg < 180) { + if (component1.startDeg < component2.startDeg) + return (NSComparisonResult)NSOrderedAscending; + else + return (NSComparisonResult)NSOrderedDescending; + } + if (component1.startDeg > component2.startDeg) + return (NSComparisonResult)NSOrderedAscending; + else + return (NSComparisonResult)NSOrderedDescending; + }]; + + for (PCPieComponent *component in sortedArray) + { + nextStartDeg = component.startDeg + _deltaRotation; + endDeg = component.endDeg + _deltaRotation; - } - else { if (nextStartDeg > 180 || (nextStartDeg < 180 && endDeg> 270) ) { // left @@ -487,61 +601,24 @@ - (void)drawRect:(CGRect)rect right_label_y += optimumSize.height + 10; } } - } - - if (_showInnerCircle) { - CGContextRef ctx = UIGraphicsGetCurrentContext(); - UIGraphicsPushContext(ctx); - CGContextSetFillColorWithColor(ctx, [PCColorInnerCircle CGColor]); - CGContextSetShadow(ctx, CGSizeMake(0.3f, 0.2f), margin); - CGContextFillEllipseInRect(ctx, - CGRectMake(x_innerCircle, - y_innerCircle, - _diameterInnerCircle, - _diameterInnerCircle)); - UIGraphicsPopContext(); - - if (_titleInnerCircle) { - float width = cosf(25) * _diameterInnerCircle; - if (width < 8) - width = 8; - float height = fabsf(sinf(25) * _diameterInnerCircle); - int fontSize = height; - _titleFontInnerCircle = [UIFont boldSystemFontOfSize:fontSize]; - - CGFloat text_x = x_innerCircle + (_diameterInnerCircle - width) * 0.5f; - CGFloat text_y = y_innerCircle + (_diameterInnerCircle - height) * 0.5f; - - - CGRect titleFrame = CGRectMake(text_x, text_y, width, height); - - UIGraphicsPushContext(ctx); - CGContextSetFillColorWithColor(ctx, [PCColorTextInnerCircle CGColor]); - [_titleInnerCircle drawInRect:titleFrame - withFont:_titleFontInnerCircle - lineBreakMode:UILineBreakModeWordWrap - alignment:UITextAlignmentCenter]; - UIGraphicsPopContext(); - } } + if (_showInnerCircle) + [self drawInnerCircle: CGPointMake(origin_x, origin_y)]; } } +#pragma mark actions -(void)TapByUser:(id)sender { CGRect rect = self.frame; float x = (rect.size.width - self.diameter)/2; float y = (rect.size.height - self.diameter)/2; - //float gap = 1; - //float inner_radius = diameter/2; float origin_x = x + self.diameter/2; float origin_y = y + self.diameter/2; - //Find by what angle it has to rotate CGPoint touchPointOnSelf=[(UITapGestureRecognizer *)sender locationInView:self]; - if (_showInnerCircle && powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { NSLog(@"Touch inside Inner Circle"); @@ -556,46 +633,72 @@ -(void)TapByUser:(id)sender return; } - float angle=atan2f((touchPointOnSelf.y - origin_y), (touchPointOnSelf.x - origin_x)); - angle += M_PI * 0.5f; // Chart alligment. - + float angle=atan2f((touchPointOnSelf.y - origin_y), (touchPointOnSelf.x - origin_x)) * 180.f / M_PI; + angle += 90; // Chart alligment. if(angle<0) - angle+=2* M_PI; + angle += 360; float total = 0; for (PCPieComponent *component in self.components) - { total += component.value; + angle += _deltaRotation; + if (angle >= 360) { + angle -= 360; } - float startDeg = 0; - float endDeg = 0; - for (PCPieComponent *component in self.components) { - float perc = [component value]/total; - endDeg = startDeg+perc*2*M_PI; - if (angle > startDeg && angle < endDeg) { + if (angle > component.startDeg && angle < component.endDeg) { NSLog(@"Portion %@ with value %f%% and percent %.1f%% was touched", component.title, component.value, component.value/total*100.f); - if (component.delegate) { - UIViewController *viewController = [component.delegate ViewController:component]; - FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; - CGPoint point = CGPointMake(self.frame.origin.x + touchPointOnSelf.x, self.frame.origin.y + touchPointOnSelf.y); - //[popoverController presentPopoverFromPoint:point]; - UIView *view = [[UIView alloc] initWithFrame:CGRectMake(point.x-self.frame.origin.x, - point.y-self.frame.origin.y, - 1, - 1)]; - [self addSubview:view]; - [popoverController presentPopoverFromView:view]; - [view removeFromSuperview]; + if (_touchAnimated) { + [NSThread detachNewThreadSelector:@selector(addDeltaAngleTillCenter:) + toTarget:self + withObject:component]; + } + else { + if (component.delegate) { + UIViewController *viewController = [component.delegate ViewController:component]; + FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; + CGPoint point = CGPointMake(self.frame.origin.x + touchPointOnSelf.x, self.frame.origin.y + touchPointOnSelf.y); + CGRect frame = CGRectMake(point.x-self.frame.origin.x, point.y-self.frame.origin.y, 1, 1); + UIView *view = [[UIView alloc] initWithFrame:frame]; + [self addSubview:view]; + [popoverController presentPopoverFromView:view]; + [view removeFromSuperview]; + } } break; } - startDeg = endDeg; } } +-(void)addDeltaAngleTillCenter: (id)obj +{ + [NSThread sleepForTimeInterval:0.04f]; + PCPieComponent *component = obj; + float targetAngle = (component.startDeg + component.endDeg) * 0.5f; + if (ceilf(_deltaRotation) == ceilf(targetAngle)) { + /* + if (component.delegate) { + UIViewController *viewController = [component.delegate ViewController:component]; + FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; + CGPoint point = CGPointMake(self.frame.origin.x + touchPointOnSelf.x, self.frame.origin.y + touchPointOnSelf.y); + CGRect frame = CGRectMake(point.x-self.frame.origin.x, point.y-self.frame.origin.y, 1, 1); + UIView *view = [[UIView alloc] initWithFrame:frame]; + [self addSubview:view]; + [popoverController presentPopoverFromView:view]; + [view removeFromSuperview]; + } + */ + return; + } + self.deltaRotation = _deltaRotation + 1; + [self setNeedsDisplay]; + + [NSThread detachNewThreadSelector:@selector(addDeltaAngleTillCenter:) + toTarget:self + withObject:component]; +} @end diff --git a/iOSPlot/iPhone/ChartListViewController.m b/iOSPlot/iPhone/ChartListViewController.m index 9dc292c..5819b55 100644 --- a/iOSPlot/iPhone/ChartListViewController.m +++ b/iOSPlot/iPhone/ChartListViewController.m @@ -35,6 +35,7 @@ #import "PieChartViewController.h" #import "PieChartViewController2.h" #import "PieChartViewController3.h" +#import "PieChartViewController4.h" #import "LineChartViewController.h" #import "HalfPieChartViewController.h" @@ -71,7 +72,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. - return 5; + return 6; } @@ -101,9 +102,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell.textLabel setText:@"Pie Chart with innner circle"]; break; case 3: - [cell.textLabel setText:@"Half Pie Chart (not completed yet)"]; + [cell.textLabel setText:@"Pie Chart with innner circle animated"]; break; case 4: + [cell.textLabel setText:@"Half Pie Chart (not completed yet)"]; + break; + case 5: [cell.textLabel setText:@"Line Chart"]; break; @@ -131,9 +135,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath detailViewController = [[PieChartViewController3 alloc] init]; break; case 3: - detailViewController = [[HalfPieChartViewController alloc] init]; + detailViewController = [[PieChartViewController4 alloc] init]; break; case 4: + detailViewController = [[HalfPieChartViewController alloc] init]; + break; + case 5: detailViewController = [[LineChartViewController alloc] init]; break; From 2cd4edea360e32900c9142696aa3d3c468e21955 Mon Sep 17 00:00:00 2001 From: gustavo halperin Date: Sat, 18 Aug 2012 03:12:41 -0300 Subject: [PATCH 14/17] second partial commit Animation done but it is a bug at popover action. --- iOSPlot/PieChartViewController4.m | 9 +++-- iOSPlot/Shared/PCPieChart.m | 51 ++++++++++-------------- iOSPlot/iPhone/ChartListViewController.m | 4 +- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/iOSPlot/PieChartViewController4.m b/iOSPlot/PieChartViewController4.m index f392840..6aae3a7 100644 --- a/iOSPlot/PieChartViewController4.m +++ b/iOSPlot/PieChartViewController4.m @@ -27,11 +27,12 @@ - (id)init [self setTitle:@"Pie Chart"]; - int height = [self.view bounds].size.width/3*2.; // 220; - int width = [self.view bounds].size.width; //320; - PCPieChart *pieChart = [[PCPieChart alloc] initWithFrame:CGRectMake(([self.view bounds].size.width-width)/2,([self.view bounds].size.height-height)/2,width,height)]; + int width = [self.view bounds].size.width * 0.75f; //320; + int height = width / 3.f * 2.2f; // 220; + PCPieChart *pieChart = [[PCPieChart alloc] initWithFrame:CGRectMake(15,//([self.view bounds].size.width-width)/2, + ([self.view bounds].size.height-height)/2,width,height)]; [pieChart setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin]; - [pieChart setDiameter:width/2]; + [pieChart setDiameter: 374];// width/2]; [pieChart setSameColorLabel:YES]; [pieChart setShowInnerCircle:YES]; diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index ba7f078..5f2624c 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -281,7 +281,10 @@ - (void)drawRect:(CGRect)rect { if (self.diameter==0) { - self.diameter = MIN(rect.size.width, rect.size.height) - 2 * MARGIN; + //if (_touchAnimated) + // self.diameter = MIN(rect.size.width, rect.size.height) - 0.5f * MARGIN; + //else + self.diameter = MIN(rect.size.width, rect.size.height) - 2 * MARGIN; } float x = (rect.size.width - self.diameter) * 0.5f; float y = (rect.size.height - self.diameter) * 0.5f; @@ -611,45 +614,29 @@ - (void)drawRect:(CGRect)rect -(void)TapByUser:(id)sender { CGRect rect = self.frame; - float x = (rect.size.width - self.diameter)/2; - float y = (rect.size.height - self.diameter)/2; - float origin_x = x + self.diameter/2; - float origin_y = y + self.diameter/2; + float origin_x = rect.size.width*0.5f; + float origin_y = rect.size.height*0.5f; //Find by what angle it has to rotate CGPoint touchPointOnSelf=[(UITapGestureRecognizer *)sender locationInView:self]; - - if (_showInnerCircle - && powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { + if (_showInnerCircle && + powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameterInnerCircle*0.5f,2.f)) { NSLog(@"Touch inside Inner Circle"); return; } - - - if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) <= powf(_diameter*0.5f,2.f)) - NSLog(@"Touch inside"); - else { + if (powf(touchPointOnSelf.x-origin_x, 2.f) + powf(touchPointOnSelf.y-origin_y,2.f) > powf(_diameter*0.5f,2.f)){ NSLog(@"Touch outside"); return; } + NSLog(@"Touch inside"); float angle=atan2f((touchPointOnSelf.y - origin_y), (touchPointOnSelf.x - origin_x)) * 180.f / M_PI; + if(angle<0) angle += 360; angle += 90; // Chart alligment. - - if(angle<0) - angle += 360; - - float total = 0; - for (PCPieComponent *component in self.components) - total += component.value; - angle += _deltaRotation; - if (angle >= 360) { - angle -= 360; - } + angle -= _deltaRotation; + if (angle >= 360.f) angle = remainderf(angle, 360.f); for (PCPieComponent *component in self.components) { if (angle > component.startDeg && angle < component.endDeg) { - NSLog(@"Portion %@ with value %f%% and percent %.1f%% was touched", - component.title, component.value, component.value/total*100.f); if (_touchAnimated) { [NSThread detachNewThreadSelector:@selector(addDeltaAngleTillCenter:) toTarget:self @@ -675,22 +662,24 @@ -(void)TapByUser:(id)sender -(void)addDeltaAngleTillCenter: (id)obj { - [NSThread sleepForTimeInterval:0.04f]; + [NSThread sleepForTimeInterval:0.015f]; PCPieComponent *component = obj; - float targetAngle = (component.startDeg + component.endDeg) * 0.5f; + float targetAngle = 360 - (component.startDeg + component.endDeg) * 0.5f + 90; + if(targetAngle < 0) targetAngle += 360; + if (targetAngle >= 360.f) targetAngle = remainderf(targetAngle, 360.f); if (ceilf(_deltaRotation) == ceilf(targetAngle)) { - /* + if (component.delegate) { UIViewController *viewController = [component.delegate ViewController:component]; FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; - CGPoint point = CGPointMake(self.frame.origin.x + touchPointOnSelf.x, self.frame.origin.y + touchPointOnSelf.y); + CGPoint point = CGPointMake(self.frame.origin.x + _diameter * 0.5f, self.frame.origin.y + _diameter * 0.5f); CGRect frame = CGRectMake(point.x-self.frame.origin.x, point.y-self.frame.origin.y, 1, 1); UIView *view = [[UIView alloc] initWithFrame:frame]; [self addSubview:view]; [popoverController presentPopoverFromView:view]; [view removeFromSuperview]; } - */ + return; } self.deltaRotation = _deltaRotation + 1; diff --git a/iOSPlot/iPhone/ChartListViewController.m b/iOSPlot/iPhone/ChartListViewController.m index 5819b55..7dae651 100644 --- a/iOSPlot/iPhone/ChartListViewController.m +++ b/iOSPlot/iPhone/ChartListViewController.m @@ -99,10 +99,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell.textLabel setText:@"Pie Chart without arrows"]; break; case 2: - [cell.textLabel setText:@"Pie Chart with innner circle"]; + [cell.textLabel setText:@"Pie Chart with inner circle"]; break; case 3: - [cell.textLabel setText:@"Pie Chart with innner circle animated"]; + [cell.textLabel setText:@"Pie Chart with inner circle animated"]; break; case 4: [cell.textLabel setText:@"Half Pie Chart (not completed yet)"]; From 3face7ded93635eabd44e2ffd8e03f287121365d Mon Sep 17 00:00:00 2001 From: gustavo halperin Date: Sun, 19 Aug 2012 11:06:31 -0300 Subject: [PATCH 15/17] fix bug on animation and add popover at the rigth side. --- iOSPlot/PieChartPopover.h | 10 +-- iOSPlot/PieChartPopover.m | 26 ++++---- iOSPlot/PieChartPopover.xib | 62 ++++++++----------- iOSPlot/PieChartViewController3.m | 6 +- iOSPlot/PieChartViewController4.m | 6 +- iOSPlot/PlotCreator.xcodeproj/project.pbxproj | 6 +- iOSPlot/Shared/PCPieChart.m | 36 ++++++----- 7 files changed, 74 insertions(+), 78 deletions(-) diff --git a/iOSPlot/PieChartPopover.h b/iOSPlot/PieChartPopover.h index c990d87..57e0fcf 100644 --- a/iOSPlot/PieChartPopover.h +++ b/iOSPlot/PieChartPopover.h @@ -10,12 +10,12 @@ @interface PieChartPopover : UIViewController -@property (strong, nonatomic) IBOutlet NSString *tittle; -@property (strong, nonatomic) IBOutlet NSString *subTittle; -@property (strong, nonatomic) IBOutlet NSString *content; +@property (strong, nonatomic) IBOutlet NSString *chartTitle; +@property (strong, nonatomic) IBOutlet NSString *chartSubTitle; +@property (strong, nonatomic) IBOutlet NSString *chartContent; -@property (strong, nonatomic) IBOutlet UILabel *tittleLabel; -@property (strong, nonatomic) IBOutlet UILabel *subTittleLabel; +@property (strong, nonatomic) IBOutlet UILabel *titleLabel; +@property (strong, nonatomic) IBOutlet UILabel *subTitleLabel; @property (strong, nonatomic) IBOutlet UITextView *contentTextView; @end diff --git a/iOSPlot/PieChartPopover.m b/iOSPlot/PieChartPopover.m index 5e72aff..fc14b65 100644 --- a/iOSPlot/PieChartPopover.m +++ b/iOSPlot/PieChartPopover.m @@ -13,11 +13,11 @@ @interface PieChartPopover () @end @implementation PieChartPopover -@synthesize tittle = _tittle; -@synthesize subTittle = _subTittle; -@synthesize content = _content; -@synthesize tittleLabel = _tittleLabel; -@synthesize subTittleLabel = _subTittleLabel; +@synthesize chartTitle = _chartTitle; +@synthesize chartSubTitle = _chartSubTitle; +@synthesize chartContent = _chartContent; +@synthesize titleLabel = _titleLabel; +@synthesize subTitleLabel = _subTitleLabel; @synthesize contentTextView = _contentTextView; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil @@ -33,9 +33,9 @@ - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. - self.tittleLabel.text = _tittle; - self.subTittleLabel.text = _subTittle; - self.contentTextView.text = _content; + self.titleLabel.text = _chartTitle; + self.subTitleLabel.text = _chartSubTitle; + self.contentTextView.text = _chartContent; } - (void)viewDidUnload @@ -43,11 +43,11 @@ - (void)viewDidUnload [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; - [self setTittle:nil]; - [self setSubTittle:nil]; - [self setContent:nil]; - [self setTittleLabel:nil]; - [self setSubTittleLabel:nil]; + [self setChartTitle:nil]; + [self setChartSubTitle:nil]; + [self setChartContent:nil]; + [self setTitleLabel:nil]; + [self setSubTitleLabel:nil]; [self setContentTextView:nil]; } diff --git a/iOSPlot/PieChartPopover.xib b/iOSPlot/PieChartPopover.xib index a49837a..aed1c99 100644 --- a/iOSPlot/PieChartPopover.xib +++ b/iOSPlot/PieChartPopover.xib @@ -157,35 +157,27 @@ - TittleLabel + contentTextView - + - 8 + 12 - subTittleLabel + subTitleLabel - 9 + 13 - tittleLabel + titleLabel - 10 - - - - contentTextView - - - - 11 + 14 @@ -248,7 +240,7 @@ - 11 + 14 @@ -256,36 +248,36 @@ PieChartPopover UIViewController - NSString + NSString + NSString + NSString UITextView - NSString - UILabel - NSString - UILabel + UILabel + UILabel - - content + + chartContent + NSString + + + chartSubTitle + NSString + + + chartTitle NSString contentTextView UITextView - - subTittle - NSString - - - subTittleLabel + + subTitleLabel UILabel - - tittle - NSString - - - tittleLabel + + titleLabel UILabel diff --git a/iOSPlot/PieChartViewController3.m b/iOSPlot/PieChartViewController3.m index 851cce3..64ae165 100644 --- a/iOSPlot/PieChartViewController3.m +++ b/iOSPlot/PieChartViewController3.m @@ -106,13 +106,13 @@ - (void)viewDidUnload { -(UIViewController*)ViewController: (PCPieComponent*)pieComponent { PieChartPopover *pieChartPopover = [[PieChartPopover alloc] init]; - [pieChartPopover setTittle:pieComponent.title]; - [pieChartPopover setSubTittle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; + [pieChartPopover setChartTitle:pieComponent.title]; + [pieChartPopover setChartSubTitle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; NSString *content = [NSString stringWithFormat:@"Content for chart %@ and value %f ", pieComponent.title, pieComponent.value]; for (int i = 0; i < 10; i++) { content = [content stringByAppendingString:content]; } - [pieChartPopover setContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; + [pieChartPopover setChartContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; return pieChartPopover; } diff --git a/iOSPlot/PieChartViewController4.m b/iOSPlot/PieChartViewController4.m index 6aae3a7..df3c20e 100644 --- a/iOSPlot/PieChartViewController4.m +++ b/iOSPlot/PieChartViewController4.m @@ -108,13 +108,13 @@ - (void)viewDidUnload { -(UIViewController*)ViewController: (PCPieComponent*)pieComponent { PieChartPopover *pieChartPopover = [[PieChartPopover alloc] init]; - [pieChartPopover setTittle:pieComponent.title]; - [pieChartPopover setSubTittle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; + [pieChartPopover setChartTitle:pieComponent.title]; + [pieChartPopover setChartSubTitle:[NSString stringWithFormat:@"Chart Value %f", pieComponent.value]]; NSString *content = [NSString stringWithFormat:@"Content for chart %@ and value %f ", pieComponent.title, pieComponent.value]; for (int i = 0; i < 10; i++) { content = [content stringByAppendingString:content]; } - [pieChartPopover setContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; + [pieChartPopover setChartContent:[NSString stringWithFormat:@"THE CONTENT CAN BE SCROLLED DOWN.\n %@", content]]; return pieChartPopover; } diff --git a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj index dd2f724..571d502 100755 --- a/iOSPlot/PlotCreator.xcodeproj/project.pbxproj +++ b/iOSPlot/PlotCreator.xcodeproj/project.pbxproj @@ -136,6 +136,9 @@ C96DD05015DD35EC00939DC6 /* FPPopover */, 3794799B13706BB200C0E457 /* iOSPlot */, F8C1B407136F7FB7002DDF6C /* JSONKit */, + C96DD05B15DD39B000939DC6 /* PieChartPopover.h */, + C96DD05C15DD39B000939DC6 /* PieChartPopover.m */, + C96DD05D15DD39B000939DC6 /* PieChartPopover.xib */, F897D6FE136311E60025FE6E /* PieChartViewController.h */, F897D6FF136311E60025FE6E /* PieChartViewController.m */, F83260C01363D91E0045F9DC /* PieChartViewController2.h */, @@ -151,9 +154,6 @@ F88CC4D113684FD30096327F /* LineChartViewController.h */, F88CC4D213684FD30096327F /* LineChartViewController.m */, 8D1107310486CEB800E47090 /* PlotCreator-Info.plist */, - C96DD05B15DD39B000939DC6 /* PieChartPopover.h */, - C96DD05C15DD39B000939DC6 /* PieChartPopover.m */, - C96DD05D15DD39B000939DC6 /* PieChartPopover.xib */, ); name = Shared; sourceTree = ""; diff --git a/iOSPlot/Shared/PCPieChart.m b/iOSPlot/Shared/PCPieChart.m index 5f2624c..9cf75e0 100644 --- a/iOSPlot/Shared/PCPieChart.m +++ b/iOSPlot/Shared/PCPieChart.m @@ -34,6 +34,8 @@ #import "PCPieChart.h" #import "FPPopoverController.h" +#import "PieChartPopover.h" + @interface PCPieComponent() @property float startDeg, endDeg; @@ -281,10 +283,7 @@ - (void)drawRect:(CGRect)rect { if (self.diameter==0) { - //if (_touchAnimated) - // self.diameter = MIN(rect.size.width, rect.size.height) - 0.5f * MARGIN; - //else - self.diameter = MIN(rect.size.width, rect.size.height) - 2 * MARGIN; + self.diameter = MIN(rect.size.width, rect.size.height) - 2 * MARGIN; } float x = (rect.size.width - self.diameter) * 0.5f; float y = (rect.size.height - self.diameter) * 0.5f; @@ -660,6 +659,20 @@ -(void)TapByUser:(id)sender } +-(void)popovermethod: (PCPieComponent*)component +{ + + UIViewController *viewController = [component.delegate ViewController:component]; + FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; + CGPoint point = CGPointMake(self.frame.size.width * 0.5f + self.diameter * 0.5f, + self.frame.size.height * 0.5f); + CGRect frame = CGRectMake(point.x, point.y, 1, 1); + UIView *view = [[UIView alloc] initWithFrame:frame]; + [self addSubview:view]; + [popoverController presentPopoverFromView:view]; + [view removeFromSuperview]; +} + -(void)addDeltaAngleTillCenter: (id)obj { [NSThread sleepForTimeInterval:0.015f]; @@ -668,18 +681,9 @@ -(void)addDeltaAngleTillCenter: (id)obj if(targetAngle < 0) targetAngle += 360; if (targetAngle >= 360.f) targetAngle = remainderf(targetAngle, 360.f); if (ceilf(_deltaRotation) == ceilf(targetAngle)) { - - if (component.delegate) { - UIViewController *viewController = [component.delegate ViewController:component]; - FPPopoverController *popoverController = [[FPPopoverController alloc] initWithViewController:viewController]; - CGPoint point = CGPointMake(self.frame.origin.x + _diameter * 0.5f, self.frame.origin.y + _diameter * 0.5f); - CGRect frame = CGRectMake(point.x-self.frame.origin.x, point.y-self.frame.origin.y, 1, 1); - UIView *view = [[UIView alloc] initWithFrame:frame]; - [self addSubview:view]; - [popoverController presentPopoverFromView:view]; - [view removeFromSuperview]; - } - + if (component.delegate) + [self performSelectorOnMainThread:@selector(popovermethod:) + withObject:component waitUntilDone:NO]; return; } self.deltaRotation = _deltaRotation + 1; From 58b9a12b09f4cf65b09b43cef87750d432872892 Mon Sep 17 00:00:00 2001 From: honcheng Date: Tue, 21 Aug 2012 13:44:33 +0800 Subject: [PATCH 16/17] - removed FPPopover --- iOSPlot/.DS_Store | Bin 6148 -> 6148 bytes iOSPlot/FPPopover/FPPopoverController.h | 63 --- iOSPlot/FPPopover/FPPopoverController.m | 540 ------------------------ iOSPlot/FPPopover/FPPopoverView.h | 57 --- iOSPlot/FPPopover/FPPopoverView.m | 464 -------------------- iOSPlot/FPPopover/FPTouchView.h | 24 -- iOSPlot/FPPopover/FPTouchView.m | 66 --- 7 files changed, 1214 deletions(-) delete mode 100644 iOSPlot/FPPopover/FPPopoverController.h delete mode 100644 iOSPlot/FPPopover/FPPopoverController.m delete mode 100644 iOSPlot/FPPopover/FPPopoverView.h delete mode 100644 iOSPlot/FPPopover/FPPopoverView.m delete mode 100644 iOSPlot/FPPopover/FPTouchView.h delete mode 100644 iOSPlot/FPPopover/FPTouchView.m diff --git a/iOSPlot/.DS_Store b/iOSPlot/.DS_Store index 4b6cdc613a4bacae6d9e4e81b9acee367db2a0a2..ba8e33140e9d7f363780f747bd3ec96fb326cb37 100644 GIT binary patch delta 85 zcmZoMXffE}!N`;?J(-75Parqn#U-V*B$ -#import - -#import "FPPopoverView.h" -#import "FPTouchView.h" - -@class FPPopoverController; -@protocol FPPopoverControllerDelegate - -@optional -- (void)popoverControllerDidDismissPopover:(FPPopoverController *)popoverController; -- (void)presentedNewPopoverController:(FPPopoverController *)newPopoverController - shouldDismissVisiblePopover:(FPPopoverController*)visiblePopoverController; -@end - -@interface FPPopoverController : UIViewController -{ - FPTouchView *_touchView; - FPPopoverView *_contentView; - UIViewController *_viewController; - UIWindow *_window; - UIView *_parentView; - UIView *_fromView; - UIDeviceOrientation _deviceOrientation; -} -@property(nonatomic,assign) id delegate; -/** @brief FPPopoverArrowDirectionAny, FPPopoverArrowDirectionVertical or FPPopoverArrowDirectionHorizontal for automatic arrow direction. - **/ -@property(nonatomic,assign) FPPopoverArrowDirection arrowDirection; - -@property(nonatomic,assign) CGSize contentSize; -@property(nonatomic,assign) CGPoint origin; - -/** @brief The tint of the popover. **/ -@property(nonatomic,assign) FPPopoverTint tint; - -/** @brief Initialize the popover with the content view controller - **/ --(id)initWithViewController:(UIViewController*)viewController; - -/** @brief Presenting the popover from a specified view **/ --(void)presentPopoverFromView:(UIView*)fromView; - -/** @brief Presenting the popover from a specified point **/ --(void)presentPopoverFromPoint:(CGPoint)fromPoint; - - -/** @brief Dismiss the popover **/ --(void)dismissPopoverAnimated:(BOOL)animated; - - - - - -@end diff --git a/iOSPlot/FPPopover/FPPopoverController.m b/iOSPlot/FPPopover/FPPopoverController.m deleted file mode 100644 index d8bafef..0000000 --- a/iOSPlot/FPPopover/FPPopoverController.m +++ /dev/null @@ -1,540 +0,0 @@ -// -// FPPopoverController.m -// -// Created by Alvise Susmel on 1/5/12. -// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. -// -// https://github.com/50pixels/FPPopover - - -#import "FPPopoverController.h" - -@interface FPPopoverController() -@property UIInterfaceOrientation interfaceOrientation; - --(CGPoint)originFromView:(UIView*)fromView; - - --(CGFloat)parentWidth; --(CGFloat)parentHeight; - -#pragma mark Space management -/* This methods help the controller to found a proper way to display the view. - * If the "from point" will be on the left, the arrow will be on the left and the - * view will be move on the right of the from point. - */ --(CGRect)bestViewFrameForFromPoint:(CGPoint)point; - --(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v; - -@end - -@implementation FPPopoverController -@synthesize interfaceOrientation = _interfaceOrientation; -@synthesize delegate = _delegate; -@synthesize contentSize = _contentSize; -@synthesize origin = _origin; -@synthesize arrowDirection = _arrowDirection; -@synthesize tint = _tint; - --(void)addObservers -{ - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(deviceOrientationDidChange:) - name:@"UIDeviceOrientationDidChangeNotification" - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(willPresentNewPopover:) name:@"FPNewPopoverPresented" object:nil]; - - _deviceOrientation = [UIDevice currentDevice].orientation; - -} - --(void)removeObservers -{ - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [_viewController removeObserver:self forKeyPath:@"title"]; -} - - --(void)dealloc -{ - [self removeObservers]; - [_touchView release]; - [_viewController release]; - [_contentView release]; - [_window release]; - [_parentView release]; - self.delegate = nil; - [super dealloc]; -} - - --(id)initWithViewController:(UIViewController*)viewController -{ - self = [super init]; - if(self) - { - _interfaceOrientation = [[UIDevice currentDevice] orientation]; - - self.arrowDirection = FPPopoverArrowDirectionAny; - self.view.userInteractionEnabled = YES; - _touchView = [[FPTouchView alloc] initWithFrame:self.view.bounds]; - _touchView.backgroundColor = [UIColor clearColor]; - _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _touchView.clipsToBounds = NO; - [self.view addSubview:_touchView]; - [_touchView setTouchedOutsideBlock:^{ - [self dismissPopoverAnimated:YES]; - }]; - - - self.contentSize = viewController.view.frame.size;//CGSizeMake(200, 300); //default size - - _contentView = [[FPPopoverView alloc] initWithFrame:CGRectMake(0, 0, - self.contentSize.width, self.contentSize.height)]; - - _viewController = [viewController retain]; - - [_touchView addSubview:_contentView]; - - [_contentView addContentView:_viewController.view]; - _viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.view.clipsToBounds = NO; - - _touchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - _touchView.clipsToBounds = NO; - - //setting contentview - _contentView.title = _viewController.title; - _contentView.clipsToBounds = NO; - - [_viewController addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; - } - return self; -} - - --(void)setTint:(FPPopoverTint)tint -{ - _contentView.tint = tint; - [_contentView setNeedsDisplay]; -} - --(FPPopoverTint)tint -{ - return _contentView.tint; -} - -#pragma mark - View lifecycle - --(void)setupView -{ - self.view.frame = CGRectMake(0, 0, [self parentWidth], [self parentHeight]); - _touchView.frame = self.view.bounds; - - //view position, size and best arrow direction - [self bestArrowDirectionAndFrameFromView:_fromView]; - - [_contentView setNeedsDisplay]; - [_touchView setNeedsDisplay]; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - //initialize and load the content view - [_contentView setArrowDirection:FPPopoverArrowDirectionUp]; - [_contentView addContentView:_viewController.view]; - - [self setupView]; - [self addObservers]; -} - -#pragma mark Orientation - --(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation -{ - return YES; -} - -#pragma mark presenting - --(CGFloat)parentWidth -{ - return _parentView.bounds.size.width; - return UIDeviceOrientationIsPortrait(_deviceOrientation) ? _parentView.frame.size.width : _parentView.frame.size.height; -} --(CGFloat)parentHeight -{ - return _parentView.bounds.size.height; - return UIDeviceOrientationIsPortrait(_deviceOrientation) ? _parentView.frame.size.height : _parentView.frame.size.width; -} - --(void)presentPopoverFromPoint:(CGPoint)fromPoint -{ - self.origin = fromPoint; - _contentView.relativeOrigin = [_parentView convertPoint:fromPoint toView:_contentView]; - - [self.view removeFromSuperview]; - NSArray *windows = [UIApplication sharedApplication].windows; - if(windows.count > 0) - { - [_window release]; [_parentView release]; _parentView=nil; - _window = [[windows objectAtIndex:0] retain]; - //keep the first subview - if(_window.subviews.count > 0) - { - [_parentView release]; - _parentView = [[_window.subviews objectAtIndex:0] retain]; - [_parentView addSubview:self.view]; - } - - } - else - { - [self dismissPopoverAnimated:NO]; - } - - - - [self setupView]; - self.view.alpha = 0.0; - [UIView animateWithDuration:0.2 animations:^{ - - self.view.alpha = 1.0; - }]; - - [[NSNotificationCenter defaultCenter] postNotificationName:@"FPNewPopoverPresented" object:self]; -} - --(CGPoint)originFromView:(UIView*)fromView -{ - CGPoint p; - if([_contentView arrowDirection] == FPPopoverArrowDirectionUp) - { - p.x = fromView.frame.origin.x + fromView.frame.size.width/2.0; - p.y = fromView.frame.origin.y + fromView.frame.size.height; - } - else if([_contentView arrowDirection] == FPPopoverArrowDirectionDown) - { - p.x = fromView.frame.origin.x + fromView.frame.size.width/2.0; - p.y = fromView.frame.origin.y; - } - else if([_contentView arrowDirection] == FPPopoverArrowDirectionLeft) - { - p.x = fromView.frame.origin.x + fromView.frame.size.width; - p.y = fromView.frame.origin.y + fromView.frame.size.height/2.0; - } - else if([_contentView arrowDirection] == FPPopoverArrowDirectionRight) - { - p.x = fromView.frame.origin.x; - p.y = fromView.frame.origin.y + fromView.frame.size.height/2.0; - } - - return p; -} - --(void)presentPopoverFromView:(UIView*)fromView -{ - [_fromView release]; _fromView = [fromView retain]; - [self presentPopoverFromPoint:[self originFromView:_fromView]]; -} - --(void)dismissPopover -{ - [self.view removeFromSuperview]; - if([self.delegate respondsToSelector:@selector(popoverControllerDidDismissPopover:)]) - { - [self.delegate popoverControllerDidDismissPopover:self]; - } - [_window release]; _window=nil; - [_parentView release]; _parentView=nil; -} - --(void)dismissPopoverAnimated:(BOOL)animated -{ - if(animated) - { - [UIView animateWithDuration:0.2 animations:^{ - self.view.alpha = 0.0; - } completion:^(BOOL finished) { - [self dismissPopover]; - }]; - } - else - { - [self dismissPopover]; - } - -} - --(void)setOrigin:(CGPoint)origin -{ - _origin = origin; -} - -#pragma mark observing - - - --(void)deviceOrientationDidChange:(NSNotification*)notification -{ - if ([[UIDevice currentDevice] orientation] != _interfaceOrientation) { - [self dismissPopoverAnimated:YES]; - } - _deviceOrientation = [UIDevice currentDevice].orientation; - - [UIView animateWithDuration:0.2 animations:^{ - [self setupView]; - }]; -} - --(void)willPresentNewPopover:(NSNotification*)notification -{ - if(notification.object != self) - { - if([self.delegate respondsToSelector:@selector(presentedNewPopoverController:shouldDismissVisiblePopover:)]) - { - [self.delegate presentedNewPopoverController:notification.object - shouldDismissVisiblePopover:self]; - } - } -} - --(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if(object == _viewController && [keyPath isEqualToString:@"title"]) - { - _contentView.title = _viewController.title; - [_contentView setNeedsDisplay]; - } -} - - -#pragma mark Space management -/* This methods helps the controller to found a proper way to display the view. - * If the "from point" will be on the left, the arrow will be on the left and the - * view will be move on the right of the from point. - * - * Consider only x direction - * - * |--lm--|-----s-----|--rm--| - * - * s is the frame of our view (s < screen width). - * if our origin point is in lm or rm we move s - * if the origin point is in s we move the arrow - */ --(CGRect)bestViewFrameForFromPoint:(CGPoint)point -{ - //content view size - CGRect r; - r.size = self.contentSize; - r.size.width += 20; - r.size.height += 50; - - //size limits - CGFloat w = MIN(r.size.width, [self parentWidth]); - CGFloat h = MIN(r.size.height,[self parentHeight]); - - r.size.width = (w == [self parentWidth]) ? [self parentWidth]-50 : w; - r.size.height = (h == [self parentHeight]) ? [self parentHeight]-30 : h; - - CGFloat r_w = r.size.width; - CGFloat r_h = r.size.height; - - //lm + rm - CGFloat wm = [self parentWidth] - r_w; - CGFloat wm_l = wm/2.0; - CGFloat ws = r_w; - CGFloat rm_x = wm_l + ws; - - CGFloat hm = [self parentHeight] - r_h; - CGFloat hm_t = hm/2.0; //top - CGFloat hs = r_h; - CGFloat hm_b = hm_t + hs; //bottom - - if(wm > 0) - { - //s < lm + rm - //our content size is smaller then width - - //15px are the number of point from the border to the arrow when the - //arrow is totally at left - //I have considered a standard border of 2px - - if(point.x+15 <= wm_l) - { - //move the popup to the left, with the left side near the origin point - r.origin.x = point.x-15; - } - else if(point.x+15 >= rm_x) - { - //move the popup to the right, with the right side near the origin point - r.origin.x = point.x - ws + 22; - } - - else - { - //the point is in the "s" zone and then I will move only the arrow - //put in the x center the popup - r.origin.x = wm_l; - } - } - - - if(hm > 0) - { - //the point is on the top - //let's move up the view - if(point.y <= hm_t) - { - r.origin.y = point.y; - } - //the point is on the bottom, - //let's move down the view - else if(point.y > hm_b) - { - r.origin.y = point.y - hs; - } - - else - { - //we need to resize the content - r.origin.y = point.y; - r.size.height = MIN(self.contentSize.height,[self parentHeight] - point.y - 10); //resizing - } - } - - return r; -} - --(CGRect)bestArrowDirectionAndFrameFromView:(UIView*)v -{ - CGPoint p = [v.superview convertPoint:v.frame.origin toView:self.view]; - - CGFloat ht = p.y; //available vertical space on top of the view - CGFloat hb = [self parentHeight] - (p.y + v.frame.size.height); //on the bottom - CGFloat wl = p.x; //on the left - CGFloat wr = [self parentWidth] - (p.x + v.frame.size.width); //on the right - - CGFloat best_h = MAX(ht, hb); //much space down or up ? - CGFloat best_w = MAX(wl, wr); - - CGRect r; - r.size = self.contentSize; - - FPPopoverArrowDirection bestDirection; - - //if the user wants vertical arrow, check if the content will fit vertically - if(FPPopoverArrowDirectionIsVertical(self.arrowDirection) || - (self.arrowDirection == FPPopoverArrowDirectionAny && best_h >= best_w)) - { - - //ok, will be vertical - if(ht == best_h || self.arrowDirection == FPPopoverArrowDirectionDown) - { - //on the top and arrow down - bestDirection = FPPopoverArrowDirectionDown; - - r.origin.x = p.x + v.frame.size.width/2.0 - r.size.width/2.0; - r.origin.y = p.y - r.size.height; - } - else - { - //on the bottom and arrow up - bestDirection = FPPopoverArrowDirectionUp; - - r.origin.x = p.x + v.frame.size.width/2.0 - r.size.width/2.0; - r.origin.y = p.y + v.frame.size.height; - } - - - } - - - else - { - //ok, will be horizontal - if(wl == best_w || self.arrowDirection == FPPopoverArrowDirectionRight) - { - //on the left and arrow right - bestDirection = FPPopoverArrowDirectionRight; - - r.origin.x = p.x - r.size.width; - r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; - - } - else - { - //on the right then arrow left - bestDirection = FPPopoverArrowDirectionLeft; - - r.origin.x = p.x + v.frame.size.width; - r.origin.y = p.y + v.frame.size.height/2.0 - r.size.height/2.0; - } - - - } - - - - //need to moved left ? - if(r.origin.x + r.size.width > [self parentWidth]) - { - r.origin.x = [self parentWidth] - r.size.width; - } - - //need to moved right ? - else if(r.origin.x < 0) - { - r.origin.x = 0; - } - - - //need to move up? - if(r.origin.y < 0) - { - CGFloat old_y = r.origin.y; - r.origin.y = 0; - r.size.height += old_y; - } - - //need to be resized horizontally ? - if(r.origin.x + r.size.width > [self parentWidth]) - { - r.size.width = [self parentWidth] - r.origin.x; - } - - //need to be resized vertically ? - if(r.origin.y + r.size.height > [self parentHeight]) - { - r.size.height = [self parentHeight] - r.origin.y; - } - - - if([[UIApplication sharedApplication] isStatusBarHidden] == NO) - { - if(r.origin.y <= 20) r.origin.y += 20; - } - - _contentView.arrowDirection = bestDirection; - _contentView.frame = r; - - self.origin = CGPointMake(p.x + v.frame.size.width/2.0, p.y + v.frame.size.height/2.0); - _contentView.relativeOrigin = [_parentView convertPoint:self.origin toView:_contentView]; - - return r; -} - - - - -@end diff --git a/iOSPlot/FPPopover/FPPopoverView.h b/iOSPlot/FPPopover/FPPopoverView.h deleted file mode 100644 index a528f08..0000000 --- a/iOSPlot/FPPopover/FPPopoverView.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// FPPopoverView.h -// -// Created by Alvise Susmel on 1/4/12. -// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. -// -// https://github.com/50pixels/FPPopover - - -#import -#import - -typedef enum { - FPPopoverArrowDirectionUp = 1UL << 0, - FPPopoverArrowDirectionDown = 1UL << 1, - FPPopoverArrowDirectionLeft = 1UL << 2, - FPPopoverArrowDirectionRight = 1UL << 3, - - FPPopoverArrowDirectionVertical = FPPopoverArrowDirectionUp | FPPopoverArrowDirectionDown, - FPPopoverArrowDirectionHorizontal = FPPopoverArrowDirectionLeft | FPPopoverArrowDirectionRight, - - FPPopoverArrowDirectionAny = FPPopoverArrowDirectionUp | FPPopoverArrowDirectionDown | - FPPopoverArrowDirectionLeft | FPPopoverArrowDirectionRight - -} FPPopoverArrowDirection; - - -#define FPPopoverArrowDirectionIsVertical(direction) ((direction) == FPPopoverArrowDirectionVertical || (direction) == FPPopoverArrowDirectionUp || (direction) == FPPopoverArrowDirectionDown) - -#define FPPopoverArrowDirectionIsHorizontal(direction) ((direction) == FPPopoverArrowDirectionHorizontal || (direction) == FPPopoverArrowDirectionLeft || (direction) == FPPopoverArrowDirectionRight) - - -typedef enum { - FPPopoverBlackTint = 1UL << 0, // default - FPPopoverLightGrayTint = 1UL << 1, - FPPopoverGreenTint = 1UL << 2, - FPPopoverRedTint = 1UL << 3, - FPPopoverDefaultTint = FPPopoverBlackTint -} FPPopoverTint; - -@interface FPPopoverView : UIView -{ - //default FPPopoverArrowDirectionUp - FPPopoverArrowDirection _arrowDirection; - UIView *_contentView; - UILabel *_titleLabel; -} -@property(nonatomic,retain) NSString *title; -@property(nonatomic,assign) CGPoint relativeOrigin; -@property(nonatomic,assign) FPPopoverTint tint; - --(void)setArrowDirection:(FPPopoverArrowDirection)arrowDirection; --(FPPopoverArrowDirection)arrowDirection; - --(void)addContentView:(UIView*)contentView; - -@end diff --git a/iOSPlot/FPPopover/FPPopoverView.m b/iOSPlot/FPPopover/FPPopoverView.m deleted file mode 100644 index 8461841..0000000 --- a/iOSPlot/FPPopover/FPPopoverView.m +++ /dev/null @@ -1,464 +0,0 @@ -// -// FPPopoverView.m -// -// Created by Alvise Susmel on 1/4/12. -// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. -// -// https://github.com/50pixels/FPPopover - - -#import "FPPopoverView.h" - -#define FP_POPOVER_ARROW_HEIGHT 20.0 -#define FP_POPOVER_ARROW_BASE 20.0 -#define FP_POPOVER_RADIUS 10.0 - - -@interface FPPopoverView(Private) --(void)setupViews; -@end - - -@implementation FPPopoverView -@synthesize title; -@synthesize relativeOrigin; -@synthesize tint = _tint; - --(void)dealloc -{ - self.title = nil; - [_contentView release]; - [_titleLabel release]; - [super dealloc]; -} - -- (id)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - - //we need to set the background as clear to see the view below - self.backgroundColor = [UIColor clearColor]; - self.clipsToBounds = YES; - - self.layer.shadowOpacity = 0.7; - self.layer.shadowRadius = 5; - self.layer.shadowOffset = CGSizeMake(-3, 3); - - //to get working the animations - self.contentMode = UIViewContentModeRedraw; - - - _titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - _titleLabel.backgroundColor = [UIColor clearColor]; - _titleLabel.textColor = [UIColor whiteColor]; - _titleLabel.textAlignment = UITextAlignmentCenter; - _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:16]; - - self.tint = FPPopoverDefaultTint; - - [self addSubview:_titleLabel]; - [self setupViews]; - } - return self; -} - -#pragma mark setters --(void)setArrowDirection:(FPPopoverArrowDirection)arrowDirection -{ - _arrowDirection = arrowDirection; - [self setNeedsDisplay]; -} - --(FPPopoverArrowDirection)arrowDirection -{ - return _arrowDirection; -} --(void)addContentView:(UIView *)contentView -{ - if(_contentView != contentView) - { - [_contentView removeFromSuperview]; - [_contentView release]; - _contentView = [contentView retain]; - [self addSubview:_contentView]; - } - [self setupViews]; -} - -#pragma mark drawing - -//the content with the arrow --(CGPathRef)newContentPathWithBorderWidth:(CGFloat)borderWidth arrowDirection:(FPPopoverArrowDirection)direction -{ - CGFloat w = self.bounds.size.width; - CGFloat h = self.bounds.size.height; - CGFloat ah = FP_POPOVER_ARROW_HEIGHT; //is the height of the triangle of the arrow - CGFloat aw = FP_POPOVER_ARROW_BASE/2.0; //is the 1/2 of the base of the arrow - CGFloat radius = FP_POPOVER_RADIUS; - CGFloat b = borderWidth; - - CGRect rect; - if(direction == FPPopoverArrowDirectionUp) - { - - rect.size.width = w - 2*b; - rect.size.height = h - ah - 2*b; - rect.origin.x = b; - rect.origin.y = ah + b; - } - else if(direction == FPPopoverArrowDirectionDown) - { - rect.size.width = w - 2*b; - rect.size.height = h - ah - 2*b; - rect.origin.x = b; - rect.origin.y = b; - } - - - else if(direction == FPPopoverArrowDirectionRight) - { - rect.size.width = w - ah - 2*b; - rect.size.height = h - 2*b; - rect.origin.x = b; - rect.origin.y = b; - } - else - { - //Assuming direction == FPPopoverArrowDirectionLeft to suppress static analyzer warnings - rect.size.width = w - ah - 2*b; - rect.size.height = h - 2*b; - rect.origin.x = ah + b; - rect.origin.y = b; - } - - //the arrow will be near the origin - CGFloat ax = self.relativeOrigin.x - aw; //the start of the arrow when UP or DOWN - if(ax < aw + b) ax = aw + b; - else if (ax +2*aw + 2*b> self.bounds.size.width) ax = self.bounds.size.width - 2*aw - 2*b; - - CGFloat ay = self.relativeOrigin.y - aw; //the start of the arrow when RIGHT or LEFT - if(ay < aw + b) ay = aw + b; - else if (ay +2*aw + 2*b > self.bounds.size.height) ay = self.bounds.size.height - 2*aw - 2*b; - - - //ROUNDED RECT - // arrow UP - CGRect innerRect = CGRectInset(rect, radius, radius); - CGFloat inside_right = innerRect.origin.x + innerRect.size.width; - CGFloat outside_right = rect.origin.x + rect.size.width; - CGFloat inside_bottom = innerRect.origin.y + innerRect.size.height; - CGFloat outside_bottom = rect.origin.y + rect.size.height; - CGFloat inside_top = innerRect.origin.y; - CGFloat outside_top = rect.origin.y; - CGFloat outside_left = rect.origin.x; - - - //drawing the border with arrow - CGMutablePathRef path = CGPathCreateMutable(); - - CGPathMoveToPoint(path, NULL, innerRect.origin.x, outside_top); - - //top arrow - if(direction == FPPopoverArrowDirectionUp) - { - CGPathAddLineToPoint(path, NULL, ax, ah+b); - CGPathAddLineToPoint(path, NULL, ax+aw, b); - CGPathAddLineToPoint(path, NULL, ax+2*aw, ah+b); - - } - - - CGPathAddLineToPoint(path, NULL, inside_right, outside_top); - CGPathAddArcToPoint(path, NULL, outside_right, outside_top, outside_right, inside_top, radius); - - //right arrow - if(direction == FPPopoverArrowDirectionRight) - { - CGPathAddLineToPoint(path, NULL, outside_right, ay); - CGPathAddLineToPoint(path, NULL, outside_right + ah+b, ay + aw); - CGPathAddLineToPoint(path, NULL, outside_right, ay + 2*aw); - } - - - CGPathAddLineToPoint(path, NULL, outside_right, inside_bottom); - CGPathAddArcToPoint(path, NULL, outside_right, outside_bottom, inside_right, outside_bottom, radius); - - //down arrow - if(direction == FPPopoverArrowDirectionDown) - { - CGPathAddLineToPoint(path, NULL, ax+2*aw, outside_bottom); - CGPathAddLineToPoint(path, NULL, ax+aw, outside_bottom + ah); - CGPathAddLineToPoint(path, NULL, ax, outside_bottom); - } - - CGPathAddLineToPoint(path, NULL, innerRect.origin.x, outside_bottom); - CGPathAddArcToPoint(path, NULL, outside_left, outside_bottom, outside_left, inside_bottom, radius); - - //left arrow - if(direction == FPPopoverArrowDirectionLeft) - { - CGPathAddLineToPoint(path, NULL, outside_left, ay + 2*aw); - CGPathAddLineToPoint(path, NULL, outside_left - ah-b, ay + aw); - CGPathAddLineToPoint(path, NULL, outside_left, ay); - } - - - CGPathAddLineToPoint(path, NULL, outside_left, inside_top); - CGPathAddArcToPoint(path, NULL, outside_left, outside_top, innerRect.origin.x, outside_top, radius); - - - CGPathCloseSubpath(path); - - return path; -} - - - --(CGGradientRef)newGradient -{ - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - - // make a gradient - CGFloat colors[8]; - - if(self.tint == FPPopoverBlackTint) - { - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - colors[0] = colors[1] = colors[2] = 0.6; - colors[4] = colors[5] = colors[6] = 0.1; - colors[3] = colors[7] = 1.0; - } - else - { - colors[0] = colors[1] = colors[2] = 0.4; - colors[4] = colors[5] = colors[6] = 0.1; - colors[3] = colors[7] = 1.0; - } - } - - else if(self.tint == FPPopoverLightGrayTint) - { - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - colors[0] = colors[1] = colors[2] = 0.8; - colors[4] = colors[5] = colors[6] = 0.3; - colors[3] = colors[7] = 1.0; - } - else - { - colors[0] = colors[1] = colors[2] = 0.6; - colors[4] = colors[5] = colors[6] = 0.1; - colors[3] = colors[7] = 1.0; - } - } - else if(self.tint == FPPopoverRedTint) - { - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - colors[0] = 0.72; colors[1] = 0.35; colors[2] = 0.32; - colors[4] = 0.36; colors[5] = 0.0; colors[6] = 0.09; - colors[3] = colors[7] = 1.0; - - } - else - { - colors[0] = 0.82; colors[1] = 0.45; colors[2] = 0.42; - colors[4] = 0.36; colors[5] = 0.0; colors[6] = 0.09; - colors[3] = colors[7] = 1.0; - } - } - - else if(self.tint == FPPopoverGreenTint) - { - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - colors[0] = 0.35; colors[1] = 0.72; colors[2] = 0.17; - colors[4] = 0.18; colors[5] = 0.30; colors[6] = 0.03; - colors[3] = colors[7] = 1.0; - - } - else - { - colors[0] = 0.45; colors[1] = 0.82; colors[2] = 0.27; - colors[4] = 0.18; colors[5] = 0.30; colors[6] = 0.03; - colors[3] = colors[7] = 1.0; - } - } - - - - CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2); - - CFRelease(colorSpace); - return gradient; -} - - - -- (void)drawRect:(CGRect)rect -{ - [super drawRect:rect]; - - - CGGradientRef gradient = [self newGradient]; - - - CGContextRef ctx = UIGraphicsGetCurrentContext(); - CGContextSaveGState(ctx); - - //content fill - CGPathRef contentPath = [self newContentPathWithBorderWidth:2.0 arrowDirection:_arrowDirection]; - - CGContextAddPath(ctx, contentPath); - CGContextClip(ctx); - - // Draw a linear gradient from top to bottom - CGPoint start; - CGPoint end; - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - start = CGPointMake(self.bounds.size.width/2.0, 0); - end = CGPointMake(self.bounds.size.width/2.0,40); - } - else - { - start = CGPointMake(self.bounds.size.width/2.0, 0); - end = CGPointMake(self.bounds.size.width/2.0,20); - } - - - - CGContextDrawLinearGradient(ctx, gradient, start, end, 0); - - CGGradientRelease(gradient); - //fill the other part of path - if(self.tint == FPPopoverBlackTint) - { - CGContextSetRGBFillColor(ctx, 0.1, 0.1, 0.1, 1.0); - } - else if(self.tint == FPPopoverLightGrayTint) - { - CGContextSetRGBFillColor(ctx, 0.3, 0.3, 0.3, 1.0); - } - else if(self.tint == FPPopoverRedTint) - { - CGContextSetRGBFillColor(ctx, 0.36, 0.0, 0.09, 1.0); - } - else if(self.tint == FPPopoverGreenTint) - { - CGContextSetRGBFillColor(ctx, 0.18, 0.30, 0.03, 1.0); - } - - - CGContextFillRect(ctx, CGRectMake(0, end.y, self.bounds.size.width, self.bounds.size.height-end.y)); - //internal border - CGContextBeginPath(ctx); - CGContextAddPath(ctx, contentPath); - CGContextSetRGBStrokeColor(ctx, 0.7, 0.7, 0.7, 1.0); - CGContextSetLineWidth(ctx, 1); - CGContextSetLineCap(ctx,kCGLineCapRound); - CGContextSetLineJoin(ctx, kCGLineJoinRound); - CGContextStrokePath(ctx); - CGPathRelease(contentPath); - - //external border - CGPathRef externalBorderPath = [self newContentPathWithBorderWidth:1.0 arrowDirection:_arrowDirection]; - CGContextBeginPath(ctx); - CGContextAddPath(ctx, externalBorderPath); - CGContextSetRGBStrokeColor(ctx, 0.4, 0.4, 0.4, 1.0); - CGContextSetLineWidth(ctx, 1); - CGContextSetLineCap(ctx,kCGLineCapRound); - CGContextSetLineJoin(ctx, kCGLineJoinRound); - CGContextStrokePath(ctx); - CGPathRelease(externalBorderPath); - - //3D border of the content view - CGRect cvRect = _contentView.frame; - //firstLine - CGContextSetRGBStrokeColor(ctx, 0.7, 0.7, 0.7, 1.0); - CGContextStrokeRect(ctx, cvRect); - //secondLine - cvRect.origin.x -= 1; cvRect.origin.y -= 1; cvRect.size.height += 2; cvRect.size.width += 2; - CGContextSetRGBStrokeColor(ctx, 0.4, 0.4, 0.4, 1.0); - CGContextStrokeRect(ctx, cvRect); - - - - CGContextRestoreGState(ctx); -} - --(void)setupViews -{ - //content posizion and size - CGRect contentRect = _contentView.frame; - - if(_arrowDirection == FPPopoverArrowDirectionUp) - { - contentRect.origin = CGPointMake(10, 60); - contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-70); - _titleLabel.frame = CGRectMake(10, 30, self.bounds.size.width-20, 20); - if (self.title==nil || self.title.length==0) { - contentRect.origin = CGPointMake(10, 30); - contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-40); - } - } - else if(_arrowDirection == FPPopoverArrowDirectionDown) - { - contentRect.origin = CGPointMake(10, 40); - contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-70); - _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); - if (self.title==nil || self.title.length==0) { - contentRect.origin = CGPointMake(10, 10); - contentRect.size = CGSizeMake(self.bounds.size.width-20, self.bounds.size.height-40); - } - } - - - else if(_arrowDirection == FPPopoverArrowDirectionRight) - { - contentRect.origin = CGPointMake(10, 40); - contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-50); - _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); - if (self.title==nil || self.title.length==0) { - contentRect.origin = CGPointMake(10, 10); - contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-20); - } - } - - else if(_arrowDirection == FPPopoverArrowDirectionLeft) - { - contentRect.origin = CGPointMake(10 + FP_POPOVER_ARROW_HEIGHT, 40); - contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-50); - _titleLabel.frame = CGRectMake(10, 10, self.bounds.size.width-20, 20); - if (self.title==nil || self.title.length==0) { - contentRect.origin = CGPointMake(10+ FP_POPOVER_ARROW_HEIGHT, 10); - contentRect.size = CGSizeMake(self.bounds.size.width-40, self.bounds.size.height-20); - } - } - - _contentView.frame = contentRect; - _titleLabel.text = self.title; - -} - - --(void)layoutSubviews -{ - [super layoutSubviews]; - [self setupViews]; -} - --(void)setFrame:(CGRect)frame -{ - [super setFrame:frame]; - [self setupViews]; -} - --(void)setBounds:(CGRect)bounds -{ - [super setBounds:bounds]; - [self setupViews]; -} -@end diff --git a/iOSPlot/FPPopover/FPTouchView.h b/iOSPlot/FPPopover/FPTouchView.h deleted file mode 100644 index 824665c..0000000 --- a/iOSPlot/FPPopover/FPTouchView.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// FPTouchView.h -// -// Created by Alvise Susmel on 4/16/12. -// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. -// -// https://github.com/50pixels/FPPopover - -#import - -typedef void (^FPTouchedOutsideBlock)(); -typedef void (^FPTouchedInsideBlock)(); - -@interface FPTouchView : UIView -{ - FPTouchedOutsideBlock _outsideBlock; - FPTouchedInsideBlock _insideBlock; -} - --(void)setTouchedOutsideBlock:(FPTouchedOutsideBlock)outsideBlock; - --(void)setTouchedInsideBlock:(FPTouchedInsideBlock)insideBlock; - -@end diff --git a/iOSPlot/FPPopover/FPTouchView.m b/iOSPlot/FPPopover/FPTouchView.m deleted file mode 100644 index e5bd5c9..0000000 --- a/iOSPlot/FPPopover/FPTouchView.m +++ /dev/null @@ -1,66 +0,0 @@ -// -// FPTouchView.m -// -// Created by Alvise Susmel on 4/16/12. -// Copyright (c) 2012 Fifty Pixels Ltd. All rights reserved. -// -// https://github.com/50pixels/FPPopover - -#import "FPTouchView.h" - -@implementation FPTouchView - --(void)dealloc -{ - [_outsideBlock release]; - [_insideBlock release]; - [super dealloc]; -} - --(void)setTouchedOutsideBlock:(FPTouchedOutsideBlock)outsideBlock -{ - [_outsideBlock release]; - _outsideBlock = [outsideBlock copy]; -} - --(void)setTouchedInsideBlock:(FPTouchedInsideBlock)insideBlock -{ - [_insideBlock release]; - _insideBlock = [insideBlock copy]; -} - --(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event -{ - UIView *subview = [super hitTest:point withEvent:event]; - - if(UIEventTypeTouches == event.type) - { - BOOL touchedInside = subview != self; - if(!touchedInside) - { - for(UIView *s in self.subviews) - { - if(s == subview) - { - //touched inside - touchedInside = YES; - break; - } - } - } - - if(touchedInside && _insideBlock) - { - _insideBlock(); - } - else if(!touchedInside && _outsideBlock) - { - _outsideBlock(); - } - } - - return subview; -} - - -@end From 6bf6e2021ed9fd67b00e2f550a4734aff6b9a0e3 Mon Sep 17 00:00:00 2001 From: honcheng Date: Tue, 21 Aug 2012 14:32:11 +0800 Subject: [PATCH 17/17] - readied FPPopover as a submodule --- .gitmodules | 3 +++ iOSPlot/FPPopover | 1 + 2 files changed, 4 insertions(+) create mode 160000 iOSPlot/FPPopover diff --git a/.gitmodules b/.gitmodules index 41d3d09..b5bf6b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "iOSPlot/JSONKit"] path = iOSPlot/JSONKit url = git://github.com/johnezang/JSONKit.git +[submodule "iOSPlot/FPPopover"] + path = iOSPlot/FPPopover + url = https://github.com/50pixels/FPPopover.git diff --git a/iOSPlot/FPPopover b/iOSPlot/FPPopover new file mode 160000 index 0000000..9fbe74c --- /dev/null +++ b/iOSPlot/FPPopover @@ -0,0 +1 @@ +Subproject commit 9fbe74c1867ef45055e8740534478243f26e6221