From a88663af3977ce1ffd4383d7fd18c9551474117d Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 30 Nov 2017 18:23:10 +0800 Subject: [PATCH 01/11] Add support for horizontal bar chart. --- JHChartDemo.xcodeproj/project.pbxproj | 30 +- .../xcdebugger/Breakpoints_v2.xcbkptlist | 5 + .../xcschemes/xcschememanagement.plist | 14 + JHChartDemo/.DS_Store | Bin 8196 -> 10244 bytes JHChartDemo/Base.lproj/Main.storyboard | 16 +- JHChartDemo/JHChart/JHChart.h | 2 + JHChartDemo/JHChart/JHChart.m | 2 - JHChartDemo/JHChart/JHChartHeader.h | 1 + JHChartDemo/JHChart/JHColumnChart.h | 10 +- JHChartDemo/JHChart/JHColumnChart.m | 167 ++----- JHChartDemo/JHChart/JHRowChart.h | 115 +++++ JHChartDemo/JHChart/JHRowChart.m | 412 ++++++++++++++++++ JHChartDemo/JHChart/JHRowItem.h | 30 ++ JHChartDemo/JHChart/JHRowItem.m | 70 +++ JHChartDemo/JHShowController.m | 80 +++- JHChartDemo/ViewController.m | 2 +- 16 files changed, 786 insertions(+), 170 deletions(-) create mode 100644 JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 JHChartDemo/JHChart/JHRowChart.h create mode 100644 JHChartDemo/JHChart/JHRowChart.m create mode 100644 JHChartDemo/JHChart/JHRowItem.h create mode 100644 JHChartDemo/JHChart/JHRowItem.m diff --git a/JHChartDemo.xcodeproj/project.pbxproj b/JHChartDemo.xcodeproj/project.pbxproj index 5fa37d0..9e91052 100644 --- a/JHChartDemo.xcodeproj/project.pbxproj +++ b/JHChartDemo.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ E9D49A191E0927EC000453F0 /* 柱状图demo2.png in Resources */ = {isa = PBXBuildFile; fileRef = E9D49A181E0927EC000453F0 /* 柱状图demo2.png */; }; E9D49A1B1E092D21000453F0 /* 饼状图demo1.png in Resources */ = {isa = PBXBuildFile; fileRef = E9D49A1A1E092D21000453F0 /* 饼状图demo1.png */; }; E9DAFF3E1D6EB6E900D4E148 /* JHTableDataRowModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E9DAFF3D1D6EB6E900D4E148 /* JHTableDataRowModel.m */; }; + F1743D651FCFBB7300B2738A /* JHRowItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D641FCFBB7300B2738A /* JHRowItem.m */; }; + F1B4D44D1FCFF3020035E16D /* JHRowChart.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D611FCFBB0200B2738A /* JHRowChart.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -138,6 +140,10 @@ E9D49A1A1E092D21000453F0 /* 饼状图demo1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "饼状图demo1.png"; sourceTree = ""; }; E9DAFF3C1D6EB6E900D4E148 /* JHTableDataRowModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JHTableDataRowModel.h; sourceTree = ""; }; E9DAFF3D1D6EB6E900D4E148 /* JHTableDataRowModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JHTableDataRowModel.m; sourceTree = ""; }; + F1743D601FCFBB0200B2738A /* JHRowChart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHRowChart.h; sourceTree = ""; }; + F1743D611FCFBB0200B2738A /* JHRowChart.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHRowChart.m; sourceTree = ""; }; + F1743D631FCFBB7300B2738A /* JHRowItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHRowItem.h; sourceTree = ""; }; + F1743D641FCFBB7300B2738A /* JHRowItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHRowItem.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -265,6 +271,10 @@ 7DEA76341F09DD720060D893 /* JHColumnItem.m */, 7DEA76361F0A34200060D893 /* JHIndexPath.h */, 7DEA76371F0A34200060D893 /* JHIndexPath.m */, + F1743D601FCFBB0200B2738A /* JHRowChart.h */, + F1743D611FCFBB0200B2738A /* JHRowChart.m */, + F1743D631FCFBB7300B2738A /* JHRowItem.h */, + F1743D641FCFBB7300B2738A /* JHRowItem.m */, ); path = JHChart; sourceTree = ""; @@ -357,7 +367,7 @@ AA5E2BA61CBA298F00FC19EE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0920; ORGANIZATIONNAME = JH; TargetAttributes = { AA5E2BAD1CBA298F00FC19EE = { @@ -448,6 +458,7 @@ AA0031601CBCCFD500F4FDEB /* JHShowController.m in Sources */, E9135FE61D2B810B00ED9F6D /* JHRingChart.m in Sources */, AAA60A8F1CD8A81A0094D6E5 /* JHPieChart.m in Sources */, + F1B4D44D1FCFF3020035E16D /* JHRowChart.m in Sources */, E92CB03F1E0BA14900861E35 /* JHScatterChart.m in Sources */, AA57D8A91CD9C492003EA0A7 /* JHShowInfoView.m in Sources */, AAA60A911CD8A81A0094D6E5 /* JHPieItemsView.m in Sources */, @@ -462,6 +473,7 @@ AA5E2BB61CBA298F00FC19EE /* AppDelegate.m in Sources */, AAA60A901CD8A81A0094D6E5 /* JHPieForeBGView.m in Sources */, AA5E2BB31CBA298F00FC19EE /* main.m in Sources */, + F1743D651FCFBB7300B2738A /* JHRowItem.m in Sources */, E9DAFF3E1D6EB6E900D4E148 /* JHTableDataRowModel.m in Sources */, E90C3EB01D6D971A0019BE6A /* JHTableChart.m in Sources */, ); @@ -526,13 +538,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -569,13 +589,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; diff --git a/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcschemes/xcschememanagement.plist b/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..d40c537 --- /dev/null +++ b/JHChartDemo.xcodeproj/xcuserdata/Mayqiyue.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + JHChartDemo.xcscheme + + orderHint + 0 + + + + diff --git a/JHChartDemo/.DS_Store b/JHChartDemo/.DS_Store index 3de11bbd0e59f03cbcb2b3979474c4b6f67062ad..92d27e20dc29db9f7798f58cc52193d730428d1e 100644 GIT binary patch delta 643 zcmZp1XbF&DU|?W$DortDU{C-uIe-{M3-C-V6q~50$f&R}U^hRb!ekzSt&^JtOa|?iKfPm@ajYGQLMdoM`~?}vS_LNW6|k6m zP(T#TNWlY>_X$X#7}=vbd5?e;x{*L3G$R!ze-yBq{8d2Q0>zcmO>sb{ax=Iycrv&# z1TmyC6f@*Alrj`CBr~LASi-c+7-$JQgBODbgEK=0 zLn6@l5@f@BR6zlTsR9v9*j1o}8jAwLjLn52)0j6lWUvY{g9L%`#tkG~L2+<&#Cw?qnSok>K!O`cxPo+VEd0(qnO`N4gArmT!{m6Lshg*Y Hvoiw#WC0hB diff --git a/JHChartDemo/Base.lproj/Main.storyboard b/JHChartDemo/Base.lproj/Main.storyboard index 1803b36..c44d933 100644 --- a/JHChartDemo/Base.lproj/Main.storyboard +++ b/JHChartDemo/Base.lproj/Main.storyboard @@ -1,8 +1,12 @@ - - + + + + + - + + @@ -10,7 +14,7 @@ - + @@ -30,9 +34,9 @@ - + - + diff --git a/JHChartDemo/JHChart/JHChart.h b/JHChartDemo/JHChart/JHChart.h index 32a0cbf..eda60a5 100644 --- a/JHChartDemo/JHChart/JHChart.h +++ b/JHChartDemo/JHChart/JHChart.h @@ -11,6 +11,8 @@ #import #define P_M(x,y) CGPointMake(x, y) +#define G_W(r) CGRectGetWidth(r) +#define G_H(r) CGRectGetHeight(r) #define weakSelf(weakSelf) __weak typeof(self) weakself = self; #define XORYLINEMAXSIZE CGSizeMake(CGFLOAT_MAX,30) diff --git a/JHChartDemo/JHChart/JHChart.m b/JHChartDemo/JHChart/JHChart.m index d5e13fd..c3e84c8 100644 --- a/JHChartDemo/JHChart/JHChart.m +++ b/JHChartDemo/JHChart/JHChart.m @@ -155,8 +155,6 @@ - (void)drawPointWithRedius:(CGFloat)redius andColor:(UIColor *)color andPoint:( * @return 占用尺寸 */ - (CGSize)sizeOfStringWithMaxSize:(CGSize)maxSize textFont:(CGFloat)fontSize aimString:(NSString *)aimString{ - - return [[NSString stringWithFormat:@"%@",aimString] boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size; } diff --git a/JHChartDemo/JHChart/JHChartHeader.h b/JHChartDemo/JHChart/JHChartHeader.h index 4970660..64f3ad2 100644 --- a/JHChartDemo/JHChart/JHChartHeader.h +++ b/JHChartDemo/JHChart/JHChartHeader.h @@ -16,3 +16,4 @@ #import "JHTableChart.h" #import "JHRadarChart.h" #import "JHScatterChart.h" +#import "JHRowChart.h" diff --git a/JHChartDemo/JHChart/JHColumnChart.h b/JHChartDemo/JHChart/JHColumnChart.h index d34392a..6eef798 100644 --- a/JHChartDemo/JHChart/JHColumnChart.h +++ b/JHChartDemo/JHChart/JHColumnChart.h @@ -17,7 +17,6 @@ @interface JHColumnChart : JHChart - /** * Each histogram of the background color, if you do not set the default value for green. Setup must ensure that the number and type of the data source array are the same, otherwise the default is not set. */ @@ -36,15 +35,13 @@ */ @property (nonatomic, strong) NSArray * xShowInfoText; - /** * The background color of the content view */ @property (nonatomic, strong) UIColor * bgVewBackgoundColor; - /** - * Column spacing, non continuous, default is 5 + * Column spacing, non continuous, default is 15 */ @property (nonatomic, assign) CGFloat typeSpace; @@ -93,13 +90,11 @@ */ @property (nonatomic,assign) BOOL isShowLineChart; - /** * If isShowLineChart proprety is YES,we need this value array to draw chart */ @property (nonatomic,strong)NSArray * lineValueArray; - /** * If isShowLineChart proprety is Yes,we will draw path of this linechart with this color * Default is blue @@ -112,7 +107,4 @@ */ @property (nonatomic,strong)UIColor * lineChartValuePointColor; - - - @end diff --git a/JHChartDemo/JHChart/JHColumnChart.m b/JHChartDemo/JHChart/JHColumnChart.m index ff08944..710418a 100644 --- a/JHChartDemo/JHChart/JHColumnChart.m +++ b/JHChartDemo/JHChart/JHColumnChart.m @@ -9,6 +9,7 @@ #import "JHColumnChart.h" #import #import "JHColumnItem.h" + @interface JHColumnChart () //背景图 @@ -44,80 +45,55 @@ -(NSMutableArray *)drawLineValue{ } -(NSMutableArray *)showViewArr{ - - if (!_showViewArr) { _showViewArr = [NSMutableArray array]; } return _showViewArr; - } -(NSMutableArray *)layerArr{ - - if (!_layerArr) { _layerArr = [NSMutableArray array]; } - return _layerArr; } - -(UIScrollView *)BGScrollView{ - - if (!_BGScrollView) { - _BGScrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; _BGScrollView.showsHorizontalScrollIndicator = NO; _BGScrollView.backgroundColor = _bgVewBackgoundColor; [self addSubview:_BGScrollView]; } - return _BGScrollView; - - } - -(void)setBgVewBackgoundColor:(UIColor *)bgVewBackgoundColor{ - _bgVewBackgoundColor = bgVewBackgoundColor; self.BGScrollView.backgroundColor = _bgVewBackgoundColor; - } - -(NSMutableArray *)yLineDataArr{ - - if (!_yLineDataArr) { _yLineDataArr = [NSMutableArray array]; } return _yLineDataArr; - } -(instancetype)initWithFrame:(CGRect)frame{ - - if (self = [super initWithFrame:frame]) { - _needXandYLine = YES; _isShowYLine = YES; _lineChartPathColor = [UIColor blueColor]; _lineChartValuePointColor = [UIColor yellowColor]; } return self; - } -(void)setLineValueArray:(NSArray *)lineValueArray{ - if (!_isShowLineChart) { return; } @@ -143,8 +119,6 @@ -(void)setLineValueArray:(NSArray *)lineValueArray{ _maxHeight += 4; _perHeight = (CGRectGetHeight(self.frame) - 30 - _originSize.y)/_maxHeight; - - } -(void)setValueArr:(NSArray *)valueArr{ @@ -152,12 +126,12 @@ -(void)setValueArr:(NSArray *)valueArr{ _valueArr = valueArr; CGFloat max = 0; - + for (NSArray *arr in _valueArr) { for (id number in arr) { CGFloat currentNumber = 0; - + if ([number isKindOfClass:[NSArray class]]) { for (id sub in number) { currentNumber += [NSString stringWithFormat:@"%@",sub].floatValue; @@ -168,9 +142,7 @@ -(void)setValueArr:(NSArray *)valueArr{ if (currentNumber>max) { max = currentNumber; } - } - } if (max<5.0) { @@ -183,13 +155,11 @@ -(void)setValueArr:(NSArray *)valueArr{ _maxHeight += 4; _perHeight = (CGRectGetHeight(self.frame) - 30 - _originSize.y - self.contentInsets.top)/_maxHeight; - - } -(void)showAnimation{ - + [self clear]; _columnWidth = (_columnWidth<=0?30:_columnWidth); @@ -210,23 +180,17 @@ -(void)showAnimation{ UIBezierPath *bezier = [UIBezierPath bezierPath]; if (self.isShowYLine) { - [bezier moveToPoint:CGPointMake(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; - [bezier addLineToPoint:P_M(self.originSize.x, 20)]; + [bezier moveToPoint:P_M(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; + [bezier addLineToPoint:P_M(self.originSize.x, 20)]; } - - [bezier moveToPoint:CGPointMake(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; - - [bezier addLineToPoint:P_M(_maxWidth , CGRectGetHeight(self.frame) - self.originSize.y)]; - + [bezier moveToPoint:P_M(self.originSize.x, CGRectGetHeight(self.frame) - self.originSize.y)]; + [bezier addLineToPoint:P_M(_maxWidth, CGRectGetHeight(self.frame) - self.originSize.y)]; layer.path = bezier.CGPath; - layer.strokeColor = (_colorForXYLine==nil?([UIColor blackColor].CGColor):_colorForXYLine.CGColor); - - + CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; - basic.duration = self.isShowYLine?1.5:0.75; basic.fromValue = @(0); @@ -237,13 +201,10 @@ -(void)showAnimation{ basic.fillMode = kCAFillModeForwards; - [layer addAnimation:basic forKey:nil]; [self.BGScrollView.layer addSublayer:layer]; -// _maxHeight += 4; - /* 设置虚线辅助线 */ UIBezierPath *second = [UIBezierPath bezierPath]; for (NSInteger i = 0; i<5; i++) { @@ -251,11 +212,8 @@ -(void)showAnimation{ CGFloat height = _perHeight * (i+1)*pace; [second moveToPoint:P_M(_originSize.x, CGRectGetHeight(self.frame) - _originSize.y -height)]; [second addLineToPoint:P_M(_maxWidth, CGRectGetHeight(self.frame) - _originSize.y - height)]; - - - + CATextLayer *textLayer = [CATextLayer layer]; - textLayer.contentsScale = [UIScreen mainScreen].scale; NSString *text =[NSString stringWithFormat:@"%ld",(i + 1) * pace]; CGFloat be = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:text].width; @@ -273,44 +231,27 @@ -(void)showAnimation{ textLayer.foregroundColor = (_drawTextColorForX_Y==nil?[UIColor blackColor].CGColor:_drawTextColorForX_Y.CGColor); [_BGScrollView.layer addSublayer:textLayer]; [self.layerArr addObject:textLayer]; - } CAShapeLayer *shapeLayer = [CAShapeLayer layer]; - shapeLayer.path = second.CGPath; - shapeLayer.strokeColor = (_dashColor==nil?([UIColor darkGrayColor].CGColor):_dashColor.CGColor); - shapeLayer.lineWidth = 0.5; - [shapeLayer setLineDashPattern:@[@(3),@(3)]]; CABasicAnimation *basic2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; - - basic2.duration = 1.5; - basic2.fromValue = @(0); - basic2.toValue = @(1); - basic2.autoreverses = NO; - - - basic2.fillMode = kCAFillModeForwards; [shapeLayer addAnimation:basic2 forKey:nil]; [self.BGScrollView.layer addSublayer:shapeLayer]; [self.layerArr addObject:shapeLayer]; - } - - - /* 绘制X轴提示语 不管是否设置了是否绘制X、Y轴 提示语都应有 */ if (_xShowInfoText.count == _valueArr.count&&_xShowInfoText.count>0) { @@ -318,50 +259,28 @@ -(void)showAnimation{ for (NSInteger i = 0; i<_xShowInfoText.count; i++) { - - CATextLayer *textLayer = [CATextLayer layer]; - CGFloat wid = count * _columnWidth; - - - CGSize size = [_xShowInfoText[i] boundingRectWithSize:CGSizeMake(wid, MAXFLOAT) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:self.xDescTextFontSize]} context:nil].size; - textLayer.frame = CGRectMake( i * (count * _columnWidth + _typeSpace) + _typeSpace + _originSize.x+ _drawFromOriginX, CGRectGetHeight(self.frame) - _originSize.y+5,wid, size.height); textLayer.string = _xShowInfoText[i]; textLayer.contentsScale = [UIScreen mainScreen].scale; - UIFont *font = [UIFont systemFontOfSize:self.xDescTextFontSize]; - - + UIFont *font = [UIFont systemFontOfSize:self.xDescTextFontSize]; textLayer.fontSize = font.pointSize; - textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; - textLayer.alignmentMode = kCAAlignmentCenter; [_BGScrollView.layer addSublayer:textLayer]; - [self.layerArr addObject:textLayer]; - - } - - } - - - - - /* 动画展示 */ for (NSInteger i = 0; i<_valueArr.count; i++) { - NSArray *arr = _valueArr[i]; - + for (NSInteger j = 0; j + +@optional +- (void)rowChart:(JHRowChart *)chart rowItem:(UIView *)item didClickAtIndexRow:(NSIndexPath *)indexPath; //1.2.0 +- (void)rowChart:(JHRowChart *)chart rowItem:(JHRowItem *)item didClickAtIndexPath:(JHIndexPath *)indexPath;//1.2.1 +@end + +@interface JHRowChart : JHChart + +/** + * Each histogram of the background color, if you do not set the default value for green. Setup must ensure that the number and type of the data source array are the same, otherwise the default is not set. + */ +@property (nonatomic, strong) NSArray * rowBGcolorsArr; + +/// JHColumnDelegate的代理,用以监听柱状图某一项的点击事件 +@property (nonatomic , assign)id delegate; + +/** + * Data source array + */ +@property (nonatomic, strong) NSArray * valueArr; + +/** + * X axis classification of each icon + */ +@property (nonatomic, strong) NSArray * xShowInfoText; + + +/** + * The background color of the content view + */ +@property (nonatomic, strong) UIColor * bgVewBackgoundColor; + + +/** + * Row spacing, non continuous, default is 5 + */ +@property (nonatomic, assign) CGFloat typeSpace; + +/** + * The height of the Row, the default is 40 + */ +@property (nonatomic, assign) CGFloat rowHeight; + +/** + * Whether the need for Y, X axis, the default YES + */ +@property (nonatomic, assign) BOOL needXandYLine; + +/** + * Y, X axis line color + */ +@property (nonatomic, strong) UIColor * colorForXYLine; + +/** + * X, Y axis text description color + */ +@property (nonatomic, strong) UIColor * drawTextColorForX_Y; + +/** + * Dotted line guide color + */ +@property (nonatomic, strong) UIColor * dashColor; + +/** + * The starting point, can be understood as the origin of the left and top margins + */ +@property (nonatomic, assign) CGPoint originSize; + +/** + * Starting from the origin of the horizontal distance histogram + */ +@property (nonatomic, assign) CGFloat drawFromOriginX; + +/** + * Whether this chart show Y line or not .Default is Yes + */ +@property (nonatomic,assign) BOOL isShowYLine; + +/** + * Whether this chart show line or not.Default is NO; + */ +@property (nonatomic,assign) BOOL isShowLineChart; + + +/** + * If isShowLineChart proprety is YES,we need this value array to draw chart + */ +@property (nonatomic,strong)NSArray * lineValueArray; + + +/** + * If isShowLineChart proprety is Yes,we will draw path of this linechart with this color + * Default is blue + */ +@property (nonatomic,strong)UIColor * lineChartPathColor; + +/** + * if isShowLineChart proprety is Yes,we will draw this linechart valuepoint with this color + * Default is yellow + */ +@property (nonatomic,strong)UIColor * lineChartValuePointColor; + +@end diff --git a/JHChartDemo/JHChart/JHRowChart.m b/JHChartDemo/JHChart/JHRowChart.m new file mode 100644 index 0000000..5342c07 --- /dev/null +++ b/JHChartDemo/JHChart/JHRowChart.m @@ -0,0 +1,412 @@ +// +// JHRowChart.m +// JHChartDemo +// +// Created by Mayqiyue on 30/11/2017. +// Copyright © 2017 JH. All rights reserved. +// + +#import "JHRowChart.h" +#import +#import "JHRowItem.h" + +@interface JHRowChart () + +//背景图 +@property (nonatomic,strong)UIScrollView *BGScrollView; + +//峰值 +@property (nonatomic,assign) CGFloat maxHeight; + +//横向最大值 +@property (nonatomic,assign) CGFloat maxWidth; + +//Y轴辅助线数据源 +@property (nonatomic,strong)NSMutableArray * yLineDataArr; + +//所有的图层数组 +@property (nonatomic,strong)NSMutableArray * layerArr; + +//所有的柱状图数组 +@property (nonatomic,strong)NSMutableArray * showViewArr; + +@property (nonatomic,assign) CGFloat perWidth; + +@property (nonatomic , strong) NSMutableArray * drawLineValue; +@end + +@implementation JHRowChart + +-(NSMutableArray *)drawLineValue{ + if (!_drawLineValue) { + _drawLineValue = [NSMutableArray array]; + } + return _drawLineValue; +} + +-(NSMutableArray *)showViewArr{ + if (!_showViewArr) { + _showViewArr = [NSMutableArray array]; + } + + return _showViewArr; +} + +-(NSMutableArray *)layerArr{ + if (!_layerArr) { + _layerArr = [NSMutableArray array]; + } + return _layerArr; +} + +-(UIScrollView *)BGScrollView{ + if (!_BGScrollView) { + _BGScrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; + _BGScrollView.showsHorizontalScrollIndicator = NO; + _BGScrollView.backgroundColor = _bgVewBackgoundColor; + [self addSubview:_BGScrollView]; + + } + return _BGScrollView; +} + +-(void)setBgVewBackgoundColor:(UIColor *)bgVewBackgoundColor{ + _bgVewBackgoundColor = bgVewBackgoundColor; + self.BGScrollView.backgroundColor = _bgVewBackgoundColor; +} + + +-(NSMutableArray *)yLineDataArr{ + if (!_yLineDataArr) { + _yLineDataArr = [NSMutableArray array]; + } + return _yLineDataArr; +} + +-(instancetype)initWithFrame:(CGRect)frame{ + if (self = [super initWithFrame:frame]) { + + _needXandYLine = YES; + _isShowYLine = YES; + _lineChartPathColor = [UIColor blueColor]; + _lineChartValuePointColor = [UIColor yellowColor]; + } + return self; +} + +-(void)setLineValueArray:(NSArray *)lineValueArray{ + if (!_isShowLineChart) { + return; + } + + _lineValueArray = lineValueArray; + CGFloat max = 0; + + for (id number in _lineValueArray) { + CGFloat currentNumber = [NSString stringWithFormat:@"%@",number].floatValue; + max = MAX(max, currentNumber); + } + + if (max<5.0) { + max = 5.0; + } else if(max<10){ + max = 10; + } + max += 4; + _maxWidth = MAX(_maxWidth, max); + + _perWidth = (CGRectGetWidth(self.frame) - 30 - _originSize.x - self.contentInsets.right)/_maxWidth; +} + +-(void)setValueArr:(NSArray *)valueArr{ + _valueArr = valueArr; + CGFloat max = 0; + + for (NSArray *arr in _valueArr) { + CGFloat total= 0; + for (NSNumber *number in arr) { + total += number.floatValue; + } + max = MAX(total, max); + } + + if (max<5.0) { + max = 5.0; + } + else if(max<10) { + max = 10; + } + max += 4; + + _maxWidth = MAX(_maxWidth, max); + _perWidth = (CGRectGetWidth(self.frame) - 30 - _originSize.x)/_maxWidth; +} + +-(void)showAnimation{ + + [self clear]; + + _rowHeight = (_rowHeight<=0?30:_rowHeight); + _typeSpace = (_typeSpace<=0?15:_typeSpace); + _maxHeight = _originSize.y + _valueArr.count * _rowHeight + (_valueArr.count +1) * _typeSpace + 10; + self.BGScrollView.contentSize = CGSizeMake(_maxWidth, _maxHeight); + self.BGScrollView.backgroundColor = _bgVewBackgoundColor; + + /* 绘制X、Y轴 可以在此改动X、Y轴字体大小 */ + if (_needXandYLine) { + + UIBezierPath *bezier = [UIBezierPath bezierPath]; + if (self.isShowYLine) { + [bezier moveToPoint:_originSize]; + [bezier addLineToPoint:P_M(G_W(self.frame), _originSize.y)]; + } + [bezier moveToPoint:_originSize]; + [bezier addLineToPoint:P_M(self.originSize.x, _maxHeight)]; + + CAShapeLayer *layer = [CAShapeLayer layer]; + layer.path = bezier.CGPath; + layer.strokeColor = (_colorForXYLine==nil?([UIColor blackColor].CGColor):_colorForXYLine.CGColor); + + CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + basic.duration = self.isShowYLine?1.5:0.75; + basic.fromValue = @(0); + basic.toValue = @(1); + basic.autoreverses = NO; + basic.fillMode = kCAFillModeForwards; + + [layer addAnimation:basic forKey:nil]; + [self.layerArr addObject:layer]; + [self.BGScrollView.layer addSublayer:layer]; + + /* 设置虚线辅助线 */ + UIBezierPath *second = [UIBezierPath bezierPath]; + for (NSInteger i = 0; i<5; i++) { + NSInteger pace = (_maxWidth) / 5; + CGFloat width = _perWidth * (i+1)*pace; + [second moveToPoint:P_M(_originSize.x + width, _originSize.y)]; + [second addLineToPoint:P_M(_originSize.x + width, _maxHeight)]; + + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + NSString *text =[NSString stringWithFormat:@"%zd",(i + 1) * pace]; + CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:text]; + textLayer.frame = CGRectMake(_originSize.x + width - size.width/2.0, 0, _originSize.y - size.height/2.0, size.height); + + UIFont *font = [UIFont systemFontOfSize:self.yDescTextFontSize]; + CFStringRef fontName = (__bridge CFStringRef)font.fontName; + CGFontRef fontRef = CGFontCreateWithFontName(fontName); + textLayer.font = fontRef; + textLayer.fontSize = font.pointSize; + CGFontRelease(fontRef); + + textLayer.string = text; + + textLayer.foregroundColor = (_drawTextColorForX_Y==nil?[UIColor blackColor].CGColor:_drawTextColorForX_Y.CGColor); + [_BGScrollView.layer addSublayer:textLayer]; + [self.layerArr addObject:textLayer]; + } + + CAShapeLayer *shapeLayer = [CAShapeLayer layer]; + + shapeLayer.path = second.CGPath; + + shapeLayer.strokeColor = (_dashColor==nil?([UIColor darkGrayColor].CGColor):_dashColor.CGColor); + + shapeLayer.lineWidth = 0.5; + + [shapeLayer setLineDashPattern:@[@(3),@(3)]]; + + CABasicAnimation *basic2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + + + basic2.duration = 1.5; + + basic2.fromValue = @(0); + + basic2.toValue = @(1); + + basic2.autoreverses = NO; + + + + basic2.fillMode = kCAFillModeForwards; + + [shapeLayer addAnimation:basic2 forKey:nil]; + + [self.BGScrollView.layer addSublayer:shapeLayer]; + [self.layerArr addObject:shapeLayer]; + + } + + if (_xShowInfoText.count == _valueArr.count&&_xShowInfoText.count>0) { + for (NSInteger i = 0; i<_xShowInfoText.count; i++) { + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.frame = [_xShowInfoText[i] boundingRectWithSize:CGSizeMake(MAXFLOAT, _rowHeight) + options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine + attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:self.xDescTextFontSize]} + context:nil]; + textLayer.position = P_M(_originSize.x - textLayer.frame.size.width/2.0 -5, _originSize.y + (i +1) * (_rowHeight + _typeSpace) - _typeSpace - 0.5 * _rowHeight); + textLayer.string = _xShowInfoText[i]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + UIFont *font = [UIFont systemFontOfSize:self.xDescTextFontSize]; + + textLayer.fontSize = font.pointSize; + textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; + textLayer.alignmentMode = kCAAlignmentCenter; + + [_BGScrollView.layer addSublayer:textLayer]; + + [self.layerArr addObject:textLayer]; + } + } + + /* 动画展示 */ + for (NSInteger j = 0; j<_valueArr.count; j++) { + NSArray *arr = _valueArr[j]; + + NSArray *colors = nil; + CGFloat width = 0; + for (NSNumber *num in arr) { + width += num.floatValue; + } + if (j >= _rowBGcolorsArr.count) { + colors = _rowBGcolorsArr.lastObject; + } + else { + colors = _rowBGcolorsArr[j]; + } + + JHRowItem *itemsView = [[JHRowItem alloc] initWithFrame:CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, width * _perWidth, _rowHeight) + perWidth:_perWidth + valueArray:arr + colors:colors]; + itemsView.clipsToBounds = YES; + itemsView.delegate = self; + [self.showViewArr addObject:itemsView]; + itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, 0, _rowHeight); + + if (_isShowLineChart) { + NSString *value = [NSString stringWithFormat:@"%@",_lineValueArray[j]]; + NSValue *lineValue = [NSValue valueWithCGPoint:P_M(_originSize.x+_perWidth *value.floatValue, itemsView.center.y)]; + [self.drawLineValue addObject:lineValue]; + } + [self.BGScrollView addSubview:itemsView]; + + [UIView animateWithDuration:1 animations:^{ + itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, width * _perWidth, _rowHeight); + } completion:^(BOOL finished) { + /* 动画结束后添加提示文字 */ + if (finished) { + + CATextLayer *textLayer = [CATextLayer layer]; + + [self.layerArr addObject:textLayer]; + NSString *str = [NSString stringWithFormat:@"%0.2f", width]; + + CGSize size = [str boundingRectWithSize:CGSizeMake(MAXFLOAT, 20) + options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine + attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:9]} + context:nil].size; + textLayer.frame = CGRectMake(CGRectGetMaxX(itemsView.frame), CGRectGetMidY(itemsView.frame)-size.height/2.0f, size.width, size.height); + textLayer.string = str; + textLayer.fontSize = 9.0; + textLayer.alignmentMode = kCAAlignmentCenter; + textLayer.contentsScale = [UIScreen mainScreen].scale; + textLayer.foregroundColor = itemsView.backgroundColor.CGColor; + + [_BGScrollView.layer addSublayer:textLayer]; + + //添加折线图 + if (j==_valueArr.count - 1 && _isShowLineChart) { + UIBezierPath *path = [UIBezierPath bezierPath]; + + for (int32_t m=0;m<_lineValueArray.count;m++) { + NSLog(@"%@",_drawLineValue[m]); + if (m==0) { + [path moveToPoint:[_drawLineValue[m] CGPointValue]]; + + }else{ + [path addLineToPoint:[_drawLineValue[m] CGPointValue]]; + [path moveToPoint:[_drawLineValue[m] CGPointValue]]; + } + + } + + CAShapeLayer *shaper = [CAShapeLayer layer]; + shaper.path = path.CGPath; + shaper.frame = self.bounds; + shaper.lineWidth = 2.5; + shaper.strokeColor = _lineChartPathColor.CGColor; + + [self.layerArr addObject:shaper]; + + CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))]; + + basic.fromValue = @0; + basic.toValue = @1; + basic.duration = 1; + basic.delegate = self; + [shaper addAnimation:basic forKey:@"stokentoend"]; + [self.BGScrollView.layer addSublayer:shaper]; + } + } + }]; + } +} + +- (void)itemClick:(UITapGestureRecognizer *)sender{ +// if ([_delegate respondsToSelector:@selector(columnChart:columnItem:didClickAtIndexRow:)]) { +// [_delegate columnChart:self columnItem:sender.view didClickAtIndexRow:objc_getAssociatedObject(sender.view, "indexPath")]; +// } +} + +-(void)clear{ + for (CALayer *lay in self.layerArr) { + [lay removeAllAnimations]; + [lay removeFromSuperlayer]; + } + + for (UIView *subV in self.showViewArr) { + [subV removeFromSuperview]; + } +} + +-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ + + + if (flag) { + + if (_isShowLineChart) { + + + for (int32_t m=0;m<_lineValueArray.count;m++) { + NSLog(@"%@",_drawLineValue[m]); + + + + CAShapeLayer *roundLayer = [CAShapeLayer layer]; + UIBezierPath *roundPath = [UIBezierPath bezierPathWithArcCenter:[_drawLineValue[m] CGPointValue] radius:4.5 startAngle:M_PI_2 endAngle:M_PI_2 + M_PI * 2 clockwise:YES]; + roundLayer.path = roundPath.CGPath; + roundLayer.fillColor = _lineChartValuePointColor.CGColor; + [self.layerArr addObject:roundLayer]; + [self.BGScrollView.layer addSublayer:roundLayer]; + + + } + } + } +} + +-(void)rowItem:(JHRowItem *)item didClickAtIndexPath:(JHIndexPath *)indexPath { + if (_delegate) { + if ([_delegate respondsToSelector:@selector(rowChart:rowItem:didClickAtIndexRow:)]) { + [_delegate rowChart:self rowItem:item didClickAtIndexPath:indexPath]; + } + + if ([_delegate respondsToSelector:@selector(rowChart:rowItem:didClickAtIndexRow:)]) { + [_delegate rowChart:self rowItem:item didClickAtIndexRow:item.index]; + } + } +} +@end + diff --git a/JHChartDemo/JHChart/JHRowItem.h b/JHChartDemo/JHChart/JHRowItem.h new file mode 100644 index 0000000..66d1aa9 --- /dev/null +++ b/JHChartDemo/JHChart/JHRowItem.h @@ -0,0 +1,30 @@ +// +// JHRowItem.h +// JHChartDemo +// +// Created by Mayqiyue on 30/11/2017. +// Copyright © 2017 JH. All rights reserved. +// + +#import +@class JHIndexPath; +@class JHRowItem; + +@protocol JHRowItemActionDelegate + +- (void)rowItem:(JHRowItem *)item didClickAtIndexPath:(JHIndexPath *)indexPath; + +@end + +@interface JHRowItem : UIView + +@property (nonatomic , strong)NSIndexPath * index;//为兼容老版本所留 +@property (nonatomic , strong)JHIndexPath * indexPath; +@property (nonatomic , assign)id delegate; + +-(instancetype)initWithFrame:(CGRect)frame + perWidth:(CGFloat)perWidth + valueArray:(id)values + colors:(id)colors; + +@end diff --git a/JHChartDemo/JHChart/JHRowItem.m b/JHChartDemo/JHChart/JHRowItem.m new file mode 100644 index 0000000..2f98bad --- /dev/null +++ b/JHChartDemo/JHChart/JHRowItem.m @@ -0,0 +1,70 @@ +// +// JHRowItem.m +// JHChartDemo +// +// Created by Mayqiyue on 30/11/2017. +// Copyright © 2017 JH. All rights reserved. +// + +#import "JHRowItem.h" +#import "JHIndexPath.h" + +@interface JHRowItem() +@property(nonatomic,strong)NSArray *valueArray; + +@property (nonatomic , strong)id colors; + +@property (nonatomic , assign)CGFloat perWidth; + +@end + +@implementation JHRowItem + +-(instancetype)initWithFrame:(CGRect)frame perWidth:(CGFloat)perWidth valueArray:(id)values colors:(id)colors { + if (self = [super initWithFrame:frame]) { + if ([values isKindOfClass:[NSArray class]]) { + _valueArray = values; + _colors = colors; + _perWidth = perWidth; + [self configBaseView]; + }else{ + self.backgroundColor = colors; + self.tag = 0 ; + [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(itemsClick:)]]; + + } + } + return self; +} + + +- (void)configBaseView { + UIView *last = nil; + for (int i = 0; i < _valueArray.count; i++) { + UIView *item = [[UIView alloc] init]; + CGFloat width = [NSString stringWithFormat:@"%@",_valueArray[i]].floatValue * _perWidth; + item.translatesAutoresizingMaskIntoConstraints = NO; + [item addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(itemsClick:)]]; + item.tag = i; + if (!last) { + item.frame = CGRectMake(0, 0, width, CGRectGetHeight(self.frame)); + } + else { + item.frame = CGRectMake(CGRectGetMaxX(last.frame), 0, width, CGRectGetHeight(self.frame)); + } + last = item; + item.backgroundColor = _colors[i]; + [self addSubview:item]; + } +} + +- (void)itemsClick:(UITapGestureRecognizer *)sender{ + if (_delegate) { + if ([_delegate respondsToSelector:@selector(rowItem:didClickAtIndexPath:)]) { + JHIndexPath *index = [JHIndexPath indexPathWithSection:self.indexPath.section row:self.indexPath.row index:sender.view.tag]; + [_delegate rowItem:self didClickAtIndexPath:index]; + } + } +} +@end + diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index 41eae8e..c00d919 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -68,6 +68,10 @@ - (void)viewDidLoad { { [self showScatterChart]; }break; + case 10: + { + [self showRowChart]; + }break; default: break; } @@ -279,7 +283,7 @@ - (void)showColumnView{ JHColumnChart *column = [[JHColumnChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; /* Create an array of data sources, each array is a module data. For example, the first array can represent the average score of a class of different subjects, the next array represents the average score of different subjects in another class */ column.valueArr = @[ - @[@[@15,@10]],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | | + @[@[@15,@10],@[@8,@7]],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | | @[@[@15,@20]],//第二组元素 @[@[@10,@5]],//第三组元素 @[@[@21,@12]], @@ -310,7 +314,7 @@ - (void)showColumnView{ /* X, Y axis line color */ column.colorForXYLine = [UIColor darkGrayColor]; /* Each module of the color array, such as the A class of the language performance of the color is red, the color of the math achievement is green */ - column.columnBGcolorsArr = @[@[[UIColor redColor],[UIColor greenColor]],@[[UIColor redColor],[UIColor greenColor]],@[[UIColor redColor],[UIColor greenColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果 + column.columnBGcolorsArr = @[@[[UIColor redColor],[UIColor greenColor],[UIColor redColor], [UIColor blueColor]],@[[UIColor redColor],[UIColor blueColor]],@[[UIColor redColor],[UIColor greenColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果 /* Module prompt */ column.xShowInfoText = @[@"A班级",@"B班级",@"C班级",@"D班级",@"E班级",@"F班级",@"G班级",@"H班级",@"i班级",@"J班级",@"L班级",@"M班级",@"N班级"]; column.isShowLineChart = YES; @@ -514,6 +518,69 @@ - (void)showScatterChart{ [self.view addSubview:scatterChart]; } +- (void)showRowChart { + JHRowChart *column = [[JHRowChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; + /* Create an array of data sources, each array is a module data. For example, the first array can represent the average score of a class of different subjects, the next array represents the average score of different subjects in another class */ + column.valueArr = @[ + @[@15,@10,@8,@7],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | | + @[@15,@20],//第二组元素 + @[@10,@5],//第三组元素 + @[@21,@12], + @[@19], + @[@12], + @[@15], + @[@9], + @[@8], + @[@6], + @[@9], + @[@18], + @[@11], + ]; + column.rowBGcolorsArr=@[@[[UIColor redColor],[UIColor greenColor],[UIColor redColor], [UIColor blueColor]], + @[[UIColor redColor],[UIColor blueColor]], + @[[UIColor redColor],[UIColor greenColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果 + /* This point represents the distance from the lower left corner of the origin. */ + column.originSize = CGPointMake(30, 20); + /* The first column of the distance from the starting point */ + column.drawFromOriginX = 20; + column.backgroundColor = [UIColor yellowColor]; + column.typeSpace = 10; + column.isShowYLine = NO; + column.contentInsets = UIEdgeInsetsMake(5, 0, 0, 0); + /* Column width */ + column.rowHeight = 30; + /* Column backgroundColor */ + column.bgVewBackgoundColor = [UIColor grayColor]; + /* X, Y axis font color */ + column.drawTextColorForX_Y = [UIColor blackColor]; + /* X, Y axis line color */ + column.colorForXYLine = [UIColor darkGrayColor]; + /* Each module of the color array, such as the A class of the language performance of the color is red, the color of the math achievement is green */ + /* Module prompt */ + column.xShowInfoText = @[@"A班级",@"B班级",@"C班级",@"D班级",@"E班级",@"F班级",@"G班级",@"H班级",@"i班级",@"J班级",@"L班级",@"M班级",@"N班级"]; + column.isShowLineChart = YES; + column.lineValueArray = @[ + @6, + @12, + @10, + @1, + @9, + @5, + @9, + @9, + @5, + @6, + @4, + @8, + @11 + ]; + + column.delegate = self; + /* Start animation */ + [column showAnimation]; + [self.view addSubview:column]; +} + -(void)columnChart:(JHColumnChart*)chart columnItem:(UIView *)item didClickAtIndexRow:(NSIndexPath *)indexPath{ NSLog(@"%@",indexPath); @@ -551,13 +618,4 @@ -(UIView *)tableChart:(JHTableChart*)chart viewForTableHeaderWithContentSize:(CG } - - - - - - - - - @end diff --git a/JHChartDemo/ViewController.m b/JHChartDemo/ViewController.m index 2ac664b..5f7e7b8 100644 --- a/JHChartDemo/ViewController.m +++ b/JHChartDemo/ViewController.m @@ -22,7 +22,7 @@ - (void)viewDidLoad { self.view.backgroundColor = [UIColor whiteColor]; - _itemsArr = @[@"折线图-第一象限",@"折线图-第一二象限",@"折线图第一四象限",@"折线图-全象限",@"饼图",@"环状图",@"柱状图",@"表格",@"雷达图",@"散点图"]; + _itemsArr = @[@"折线图-第一象限",@"折线图-第一二象限",@"折线图第一四象限",@"折线图-全象限",@"饼图",@"环状图",@"柱状图",@"表格",@"雷达图",@"散点图", @"横向柱状图"]; _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height - 64) style:UITableViewStylePlain]; _tableView.dataSource = self; From 9b8c20b9c6f49b9e40537dfa49017d3b36df2561 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 30 Nov 2017 22:49:14 +0800 Subject: [PATCH 02/11] Fix the bug that line chart cannot fill issue. --- JHChartDemo/.DS_Store | Bin 10244 -> 10244 bytes JHChartDemo/JHChart/JHLineChart.m | 305 +++++++++++++----------------- JHChartDemo/JHShowController.m | 4 +- 3 files changed, 137 insertions(+), 172 deletions(-) diff --git a/JHChartDemo/.DS_Store b/JHChartDemo/.DS_Store index 92d27e20dc29db9f7798f58cc52193d730428d1e..36f5404683aaf61a829198bcd2fbc4d78856b371 100644 GIT binary patch delta 49 ocmZn(XbIRbQ;c!?hqrXJPFyTlZL)aE;4d-<^lYA^x-rn?YB diff --git a/JHChartDemo/JHChart/JHLineChart.m b/JHChartDemo/JHChart/JHLineChart.m index 5d9a610..754b7c6 100644 --- a/JHChartDemo/JHChart/JHLineChart.m +++ b/JHChartDemo/JHChart/JHLineChart.m @@ -40,7 +40,7 @@ -(instancetype)initWithFrame:(CGRect)frame andLineChartType:(JHLineChartType)lin self.backgroundColor = [UIColor whiteColor]; _lineType = lineChartType; _lineWidth = 0.5; - + _yLineDataArr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7"]; _xLineDataArr = @[@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7"]; _showXDescVertical = NO; @@ -90,7 +90,7 @@ -(void)clear{ */ - (void)configPerXAndPerY{ - + switch (_lineChartQuadrantType) { case JHLineChartQuadrantTypeFirstQuardrant: { @@ -115,8 +115,8 @@ - (void)configPerXAndPerY{ break; case JHLineChartQuadrantTypeAllQuardrant: { - _perXLen = (_xLength/2-kXandYSpaceForSuperView)/([_xLineDataArr[0] count]); - _perYlen = (_yLength/2-kXandYSpaceForSuperView)/[_yLineDataArr[0] count]; + _perXLen = (_xLength/2-kXandYSpaceForSuperView)/([_xLineDataArr[0] count]); + _perYlen = (_yLength/2-kXandYSpaceForSuperView)/[_yLineDataArr[0] count]; } break; @@ -167,7 +167,7 @@ -(void)setValueArr:(NSArray *)valueArr{ * 更新Y轴的刻度大小 */ - (void)updateYScale{ - switch (_lineChartQuadrantType) { + switch (_lineChartQuadrantType) { case JHLineChartQuadrantTypeFirstAndFouthQuardrant:{ NSInteger max = 0; @@ -186,47 +186,47 @@ - (void)updateYScale{ } - min = labs(min); - max = (min5) { - for (NSInteger i = 0; i<5; i++) { + if (max<=10&&max>5) { + for (NSInteger i = 0; i<5; i++) { - [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*2]]; - [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*2]]; - } + [arr addObject:[NSString stringWithFormat:@"%ld",(i+1)*2]]; + [minArr addObject:[NSString stringWithFormat:@"-%ld",(i+1)*2]]; + } + + }else if(max>10&&max<=100){ + + + for (NSInteger i = 0; i10&&max<=100){ - - - for (NSInteger i = 0; i0) { CGFloat xPace = (_xLength-kXandYSpaceForSuperView)/(_xLineDataArr.count-1); @@ -454,15 +454,15 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ label.numberOfLines = 0; label.transform = CGAffineTransformRotate(label.transform, _xDescriptionAngle); [self addSubview:label]; - + }else{ CGFloat len = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.xDescTextFontSize aimString:_xLineDataArr[i]].width; [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:self.xAndYLineColor]; - + [self drawText:[NSString stringWithFormat:@"%@",_xLineDataArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:self.xDescTextFontSize]; } } - + } @@ -493,10 +493,10 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ p = P_M(self.chartOrigin.x + _xLength, p.y); len = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:rightArray[i]].width; hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:rightArray[i]].height; - + [self drawText:[NSString stringWithFormat:@"%@",rightArray[i]] andContext:context atPoint:P_M(p.x + 3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; - + } } @@ -527,9 +527,9 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left, self.chartOrigin.y) andEndPoint:P_M(self.contentInsets.left+_xLength, self.chartOrigin.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; if (_showYLine) { - [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.chartOrigin.x,self.chartOrigin.y-_yLength) andIsDottedLine:NO andColor:self.xAndYLineColor]; + [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.chartOrigin.x,self.chartOrigin.y-_yLength) andIsDottedLine:NO andColor:self.xAndYLineColor]; } - + if (_xLineDataArr.count == 2) { NSArray * rightArr = _xLineDataArr[1]; NSArray * leftArr = _xLineDataArr[0]; @@ -548,9 +548,9 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ [self addSubview:label]; }else{ CGFloat len = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.xDescTextFontSize aimString:rightArr[i]].width; - + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:self.xAndYLineColor]; - + [self drawText:[NSString stringWithFormat:@"%@",rightArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:self.xDescTextFontSize]; } } @@ -580,13 +580,13 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ CGFloat len = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:_yLineDataArr[i]].width; CGFloat hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:_yLineDataArr[i]].height; if (_showYLevelLine) { - [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left, p.y) andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; + [self drawLineWithContext:context andStarPoint:P_M(self.contentInsets.left, p.y) andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; }else [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; [self drawText:[NSString stringWithFormat:@"%@",_yLineDataArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; } } - + }break; case JHLineChartQuadrantTypeFirstAndFouthQuardrant:{ [self drawLineWithContext:context andStarPoint:self.chartOrigin andEndPoint:P_M(self.contentInsets.left+_xLength, self.chartOrigin.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; @@ -611,11 +611,11 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ }else{ CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.xDescTextFontSize aimString:_xLineDataArr[i]].width; [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x , p.y-3) andIsDottedLine:NO andColor:self.xAndYLineColor]; - + if (i==0) { len = -2; } - + [self drawText:[NSString stringWithFormat:@"%@",_xLineDataArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:self.xDescTextFontSize]; } } @@ -632,7 +632,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:topArr[i]].width; CGFloat hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:topArr[i]].height; if (_showYLevelLine) { - [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; }else [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; [self drawText:[NSString stringWithFormat:@"%@",topArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; @@ -644,11 +644,11 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y + (i+1)*yPace); CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:bottomArr[i]].width; CGFloat hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:bottomArr[i]].height; - + if (_showYLevelLine) { - [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(self.contentInsets.left+_xLength, p.y) andIsDottedLine:YES andColor:self.xAndYLineColor]; }else{ - + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; } [self drawText:[NSString stringWithFormat:@"%@",bottomArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; @@ -656,7 +656,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ } - + }break; case JHLineChartQuadrantTypeAllQuardrant:{ [self drawLineWithContext:context andStarPoint:P_M(self.chartOrigin.x-_xLength/2, self.chartOrigin.y) andEndPoint:P_M(self.chartOrigin.x+_xLength/2, self.chartOrigin.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; @@ -686,7 +686,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ }else{ CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.xDescTextFontSize aimString:rightArr[i]].width; [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:self.xAndYLineColor]; - + [self drawText:[NSString stringWithFormat:@"%@",rightArr[i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:self.xDescTextFontSize]; } } @@ -703,13 +703,13 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ }else{ CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.xDescTextFontSize aimString:leftArr[i]].width; [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x, p.y-3) andIsDottedLine:NO andColor:self.xAndYLineColor]; - + [self drawText:[NSString stringWithFormat:@"%@",leftArr[leftArr.count-1-i]] andContext:context atPoint:P_M(p.x-len/2, p.y+2) WithColor:_xAndYNumberColor andFontSize:self.xDescTextFontSize]; } } } - + if (_yLineDataArr.count == 2) { @@ -721,7 +721,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y - (i+1)*yPace); CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:topArr[i]].width; CGFloat hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:topArr[i]].height; - + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; [self drawText:[NSString stringWithFormat:@"%@",topArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; @@ -732,7 +732,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ CGPoint p = P_M(self.chartOrigin.x, self.chartOrigin.y + (i+1)*yPace); CGFloat len = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:bottomArr[i]].width; CGFloat hei = [self sizeOfStringWithMaxSize:CGSizeMake(CGFLOAT_MAX, 30) textFont:self.yDescTextFontSize aimString:bottomArr[i]].height; - + [self drawLineWithContext:context andStarPoint:p andEndPoint:P_M(p.x+3, p.y) andIsDottedLine:NO andColor:self.xAndYLineColor]; [self drawText:[NSString stringWithFormat:@"%@",bottomArr[i]] andContext:context atPoint:P_M(p.x-len-3, p.y-hei / 2) WithColor:_xAndYNumberColor andFontSize:self.yDescTextFontSize]; } @@ -746,7 +746,7 @@ - (void)drawXAndYLineWithContext:(CGContextRef)context{ break; } - + } /** @@ -836,27 +836,27 @@ - (void)configValueDataArray{ for (NSArray *valueArr in _valueArr) { NSMutableArray *dataMArr = [NSMutableArray array]; - - - CGPoint p ; - for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { - p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i] floatValue]*_perValue); - [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - } - - for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { - p = P_M(self.chartOrigin.x+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); - [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - - } - + + + CGPoint p ; + for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { + p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i] floatValue]*_perValue); + [dataMArr addObject:[NSValue valueWithCGPoint:p]]; + } + + for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { + p = P_M(self.chartOrigin.x+i*_perXLen, self.contentInsets.top + _yLength - [valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); + [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - + } + + + [_drawDataArr addObject:[dataMArr copy]]; } - - + + }break; @@ -882,135 +882,105 @@ - (void)configValueDataArray{ _perValue = _perYlen/[[_yLineDataArr[0] firstObject] floatValue]; for (NSArray *valueArr in _valueArr) { NSMutableArray *dataMArr = [NSMutableArray array]; - - - CGPoint p ; - for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { - p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.chartOrigin.y-[valueArr[i] floatValue]*_perValue); - [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - } - - for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { - p = P_M(self.chartOrigin.x+i*_perXLen, self.chartOrigin.y-[valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); - [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - - } - + + + CGPoint p ; + for (NSInteger i = 0; i<[_xLineDataArr[0] count]; i++) { + p = P_M(self.contentInsets.left + kXandYSpaceForSuperView+i*_perXLen, self.chartOrigin.y-[valueArr[i] floatValue]*_perValue); + [dataMArr addObject:[NSValue valueWithCGPoint:p]]; + } + + for (NSInteger i = 0; i<[_xLineDataArr[1] count]; i++) { + p = P_M(self.chartOrigin.x+i*_perXLen, self.chartOrigin.y-[valueArr[i+[_xLineDataArr[0] count]] floatValue]*_perValue); + [dataMArr addObject:[NSValue valueWithCGPoint:p]]; - + } + + + [_drawDataArr addObject:[dataMArr copy]]; } - + }break; default: break; } - - - + + + } //执行动画 - (void)drawAnimation{ - [_shapeLayer removeFromSuperlayer]; _shapeLayer = [CAShapeLayer layer]; if (_drawDataArr.count==0) { return; } - - - + //第一、UIBezierPath绘制线段 [self configPerXAndPerY]; - for (NSInteger i = 0;i<_drawDataArr.count;i++) { - NSArray *dataArr = _drawDataArr[i]; - [self drawPathWithDataArr:dataArr andIndex:i]; - } - - - } - (CGPoint)centerOfFirstPoint:(CGPoint)p1 andSecondPoint:(CGPoint)p2{ - - return P_M((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0); } - - - (void)drawPathWithDataArr:(NSArray *)dataArr andIndex:(NSInteger )colorIndex{ UIBezierPath *firstPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 0, 0)]; - UIBezierPath *secondPath = [UIBezierPath bezierPath]; for (NSInteger i = 0; i 0) { [shapeLayer addAnimation:ani forKey:NSStringFromSelector(@selector(strokeEnd))]; - }else{ + } + else { ani = nil; } @@ -1042,22 +1009,19 @@ - (void)drawPathWithDataArr:(NSArray *)dataArr andIndex:(NSInteger )colorIndex{ weakSelf(weakSelf) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(ani.duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - CAShapeLayer *shaperLay = [CAShapeLayer layer]; shaperLay.frame = weakself.bounds; shaperLay.path = secondPath.CGPath; - if (weakself.contentFillColorArr.count == weakself.drawDataArr.count) { - + if (weakself.contentFillColorArr.count >= weakself.drawDataArr.count) { shaperLay.fillColor = [weakself.contentFillColorArr[colorIndex] CGColor]; - }else{ + } + else { shaperLay.fillColor = [UIColor clearColor].CGColor; } [weakself.layer addSublayer:shaperLay]; [_layerArr addObject:shaperLay]; }); - - } @@ -1088,13 +1052,13 @@ - (void)drawPositionLineWithContext:(CGContextRef)context{ positionLineColor = _positionLineColorArr[m]; }else positionLineColor = [UIColor orangeColor]; - + if (_showValueLeadingLine) { [self drawLineWithContext:context andStarPoint:P_M(self.chartOrigin.x, p.y) andEndPoint:p andIsDottedLine:YES andColor:positionLineColor]; [self drawLineWithContext:context andStarPoint:P_M(p.x, self.chartOrigin.y) andEndPoint:p andIsDottedLine:YES andColor:positionLineColor]; } - + if (!_showPointDescription) { continue; } @@ -1102,7 +1066,7 @@ - (void)drawPositionLineWithContext:(CGContextRef)context{ UIColor *pointNumberColor = (_pointNumberColorArr.count == _valueArr.count?(_pointNumberColorArr[m]):([UIColor orangeColor])); switch (_lineChartQuadrantType) { - + case JHLineChartQuadrantTypeFirstQuardrant: { @@ -1153,7 +1117,7 @@ - (void)drawPositionLineWithContext:(CGContextRef)context{ } } - _isEndAnimation = NO; + _isEndAnimation = NO; } @@ -1167,9 +1131,9 @@ -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ if (flag) { - + [self drawPoint]; - + } @@ -1230,3 +1194,4 @@ - (void)drawPoint{ @end + diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index c00d919..88d810d 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -120,9 +120,9 @@ - (void)showFirstQuardrant{ /* Dotted line color of the coordinate point */ lineChart.positionLineColorArr = @[[UIColor blueColor],[UIColor greenColor]]; /* Set whether to fill the content, the default is False */ - lineChart.contentFill = NO; + lineChart.contentFill = YES; /* Set whether the curve path */ - lineChart.pathCurve = YES; + lineChart.pathCurve = NO; /* Set fill color array */ lineChart.contentFillColorArr = @[[UIColor colorWithRed:0 green:1 blue:0 alpha:0.468],[UIColor colorWithRed:1 green:0 blue:0 alpha:0.468]]; [self.view addSubview:lineChart]; From 8df2d9c4eaa898f19dfedf1a333b7e3234da91a3 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Wed, 6 Dec 2017 19:50:06 +0800 Subject: [PATCH 03/11] Add support for dual bar --- JHChartDemo.xcodeproj/project.pbxproj | 6 + JHChartDemo/JHChart/JHChartHeader.h | 5 +- JHChartDemo/JHChart/JHDualBarChart.h | 130 ++++++++++ JHChartDemo/JHChart/JHDualBarChart.m | 338 ++++++++++++++++++++++++++ JHChartDemo/JHShowController.m | 23 +- JHChartDemo/ViewController.m | 4 +- 6 files changed, 499 insertions(+), 7 deletions(-) create mode 100644 JHChartDemo/JHChart/JHDualBarChart.h create mode 100644 JHChartDemo/JHChart/JHDualBarChart.m diff --git a/JHChartDemo.xcodeproj/project.pbxproj b/JHChartDemo.xcodeproj/project.pbxproj index 9e91052..04921b5 100644 --- a/JHChartDemo.xcodeproj/project.pbxproj +++ b/JHChartDemo.xcodeproj/project.pbxproj @@ -52,6 +52,7 @@ E9DAFF3E1D6EB6E900D4E148 /* JHTableDataRowModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E9DAFF3D1D6EB6E900D4E148 /* JHTableDataRowModel.m */; }; F1743D651FCFBB7300B2738A /* JHRowItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D641FCFBB7300B2738A /* JHRowItem.m */; }; F1B4D44D1FCFF3020035E16D /* JHRowChart.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D611FCFBB0200B2738A /* JHRowChart.m */; }; + F1E85A481FD7C91E00713875 /* JHDualBarChart.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E85A471FD7C91E00713875 /* JHDualBarChart.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -144,6 +145,8 @@ F1743D611FCFBB0200B2738A /* JHRowChart.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHRowChart.m; sourceTree = ""; }; F1743D631FCFBB7300B2738A /* JHRowItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHRowItem.h; sourceTree = ""; }; F1743D641FCFBB7300B2738A /* JHRowItem.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHRowItem.m; sourceTree = ""; }; + F1E85A461FD7C91E00713875 /* JHDualBarChart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHDualBarChart.h; sourceTree = ""; }; + F1E85A471FD7C91E00713875 /* JHDualBarChart.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHDualBarChart.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -275,6 +278,8 @@ F1743D611FCFBB0200B2738A /* JHRowChart.m */, F1743D631FCFBB7300B2738A /* JHRowItem.h */, F1743D641FCFBB7300B2738A /* JHRowItem.m */, + F1E85A461FD7C91E00713875 /* JHDualBarChart.h */, + F1E85A471FD7C91E00713875 /* JHDualBarChart.m */, ); path = JHChart; sourceTree = ""; @@ -465,6 +470,7 @@ 7DEA76351F09DD720060D893 /* JHColumnItem.m in Sources */, AAE935E81CBE0CCA002517EB /* JHWaveChart.m in Sources */, AA5E2BE71CBA2B3100FC19EE /* JHLineChart.m in Sources */, + F1E85A481FD7C91E00713875 /* JHDualBarChart.m in Sources */, E922F8051D82A8B0000C7C77 /* JHRadarChart.m in Sources */, 7DEA76381F0A34200060D893 /* JHIndexPath.m in Sources */, AA5E2BEA1CBA2CE700FC19EE /* JHChart.m in Sources */, diff --git a/JHChartDemo/JHChart/JHChartHeader.h b/JHChartDemo/JHChart/JHChartHeader.h index 64f3ad2..16aef55 100644 --- a/JHChartDemo/JHChart/JHChartHeader.h +++ b/JHChartDemo/JHChart/JHChartHeader.h @@ -6,14 +6,15 @@ // Copyright © 2016年 JH. All rights reserved. // - #import "JHChart.h" #import "JHLineChart.h" #import "JHWaveChart.h" #import "JHPieChart.h" #import "JHRingChart.h" #import "JHColumnChart.h" +#import "JHRowChart.h" +#import "JHRowChart.h" #import "JHTableChart.h" #import "JHRadarChart.h" #import "JHScatterChart.h" -#import "JHRowChart.h" +#import "JHDualBarChart.h" diff --git a/JHChartDemo/JHChart/JHDualBarChart.h b/JHChartDemo/JHChart/JHDualBarChart.h new file mode 100644 index 0000000..2fc7d07 --- /dev/null +++ b/JHChartDemo/JHChart/JHDualBarChart.h @@ -0,0 +1,130 @@ +// +// JHDualBarChart.h +// JHChartDemo +// +// Created by Mayqiyue on 06/12/2017. +// Copyright © 2017 JH. All rights reserved. +// + +#import "JHChart.h" + +@interface JHDualBarChart : JHChart + +/** + * Each histogram of the background color, if you do not set the default value for green. Setup must ensure that the number and type of the data source array are the same, otherwise the default is not set. + */ +@property (nonatomic, strong) NSArray *leftBarBGColors; + +@property (nonatomic, strong) NSArray *rightBarBGColors; + +/** + * Data source array + */ +@property (nonatomic, strong) NSArray *leftBarValues; +@property (nonatomic, strong) NSArray *rightBarValues; + +/** + * X axis classification of each icon + */ +@property (nonatomic, strong) NSArray *xTexts; + +@property (nonatomic, assign) NSUInteger levelLineNum; + +@property (nonatomic, assign) CGFloat yLeftRadix; + +@property (nonatomic, assign) CGFloat yRightRadix; + +@property (nonatomic, copy) UIFont *xTextFont; + +@property (nonatomic, copy) UIFont *yleftTextFont; + +@property (nonatomic, copy) UIFont *yRightTextFont; + +@property (nonatomic, copy) UIFont *barTextFont; + +/** + * Whether the need for Y, X axis, the default YES + */ +@property (nonatomic, assign) BOOL needXLine; + +@property (nonatomic, assign) BOOL needYLines; + +@property (nonatomic, assign) BOOL needLeftYTexts; + +@property (nonatomic, assign) BOOL needRightYTexts; + +@property (nonatomic, assign) CGFloat leftYTextesMargin; + +/** + * The background color of the content view + */ +@property (nonatomic, strong) UIColor *bgVewBackgoundColor; + +/** + * Column spacing, non continuous, default is 15 + */ +@property (nonatomic, assign) CGFloat barSpacing; + +/** + * The width of the column, the default is 40 + */ +@property (nonatomic, assign) CGFloat barWidth; + +/** + * Y, X axis line color + */ +@property (nonatomic, strong) UIColor *colorForXYLine; + +/** + * X, Y axis text description color + */ +@property (nonatomic, strong) UIColor *drawTextColorForX_Y; + +/** + * Dotted line guide color + */ +@property (nonatomic, strong) UIColor *levelLineColor; + +/** Controls whether text for x-axis be straight or rotate 45 degree. */ +@property (nonatomic) BOOL rotateForXAxisText; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * If isShowLineChart proprety is YES,we need this value array to draw chart + */ +/** + * Whether this chart show line or not.Default is NO; + */ +@property (nonatomic, assign) BOOL isShowLineChart; + + +@property (nonatomic, strong) NSArray *leftLineValues; + +/** + * If isShowLineChart proprety is Yes,we will draw path of this linechart with this color + * Default is blue + */ +@property (nonatomic, strong) UIColor *leftLinePathColor; + +/** + * if isShowLineChart proprety is Yes,we will draw this linechart valuepoint with this color + * Default is yellow + */ +@property (nonatomic, strong)UIColor *leftLinePointColor; + +@property (nonatomic, strong) NSArray *rightLineValues; + +/** + * If isShowLineChart proprety is Yes,we will draw path of this linechart with this color + * Default is blue + */ +@property (nonatomic, strong) UIColor *rightLinePathColor; + +/** + * if isShowLineChart proprety is Yes,we will draw this linechart valuepoint with this color + * Default is yellow + */ +@property (nonatomic, strong)UIColor *rightLinePointColor; + + +@end diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m new file mode 100644 index 0000000..2ff916a --- /dev/null +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -0,0 +1,338 @@ +// +// JHDualBarChart.m +// JHChartDemo +// +// Created by Mayqiyue on 06/12/2017. +// Copyright © 2017 JH. All rights reserved. +// + +#import "JHDualBarChart.h" +@interface JHDualBarChart () { + CGFloat _maxH, _maxW, lPerH, rPerH; +} + +@property (nonatomic, strong) UIScrollView *scrollView; + +@property (nonatomic, strong) NSMutableArray *leftBarViews; +@property (nonatomic, strong) NSMutableArray *rightBarViews; +@property (nonatomic, strong) NSMutableArray *layerArr; + +@property (nonatomic, strong) NSMutableArray *drawLineValue; + +@end + +@implementation JHDualBarChart + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + } + return self; +} + +- (void)commonInit { + [self addSubview:self.scrollView]; + self.scrollView.frame = self.bounds; + _needYLines = YES; + _needXLine = YES; + _needLeftYTexts = YES; + _needRightYTexts = YES; + _leftYTextesMargin = 5; + _xTextFont = [UIFont systemFontOfSize:8]; + _yRightTextFont = [UIFont systemFontOfSize:8]; + _yleftTextFont = [UIFont systemFontOfSize:8]; + _barTextFont = [UIFont systemFontOfSize:8]; + _drawTextColorForX_Y = [UIColor blackColor]; + _colorForXYLine = [UIColor blackColor]; + _levelLineColor = [UIColor blackColor]; + self.contentInsets = UIEdgeInsetsMake(10, 30, 0, 30); + self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height - 20); +} + +- (void)showAnimation { + NSAssert(self.leftBarValues.count == self.rightBarValues.count, @""); + NSAssert(self.leftBarBGColors.count > 0 || self.rightBarBGColors.count > 0, @""); + + [self clear]; + + _barWidth = _barWidth ? : 30; + _barSpacing = _barSpacing ?: 15; + _maxW = self.chartOrigin.x + _barWidth * (_leftBarValues.count + _rightBarValues.count) + (_barSpacing + 1) * _leftBarValues.count; + _maxH = self.chartOrigin.y; + lPerH = _maxH / (_levelLineNum * _yLeftRadix); + rPerH = _maxH / (_levelLineNum * _yRightRadix); + + self.scrollView.contentSize = CGSizeMake(_maxW, _maxH); + + CGPoint p = [self.scrollView convertPoint:self.chartOrigin toView:self]; + + [self drawXAndYAxis:p]; + [self drawLevelLines:p]; + [self drawDualYTexts:p]; + [self drawXTexts]; + [self drawBars]; +} + +- (void)drawXAndYAxis:(CGPoint)p { + if (_needXLine) { + UIBezierPath *bezier = [UIBezierPath bezierPath]; + [bezier moveToPoint:p]; + [bezier addLineToPoint:P_M(self.frame.size.width - p.x, p.y)]; + + if (_needYLines) { + [bezier moveToPoint:p]; + [bezier addLineToPoint:P_M(p.x, self.contentInsets.top)]; + [bezier moveToPoint:P_M(self.frame.size.width - p.x, p.y)]; + [bezier addLineToPoint:P_M(self.frame.size.width - p.x, self.contentInsets.top)]; + } + + CAShapeLayer *layer = [CAShapeLayer layer]; + layer.path = bezier.CGPath; + layer.strokeColor = _colorForXYLine.CGColor; + + [self.layer addSublayer:layer]; + [self.layerArr addObject:layer]; + } +} + +- (void)drawLevelLines:(CGPoint)p { + + UIBezierPath *path = [UIBezierPath bezierPath]; + for (NSInteger i = 1; i <_levelLineNum + 1; i++) { + CGFloat h = i * lPerH * _yLeftRadix; + [path moveToPoint:P_M(p.x, p.y - h)]; + [path addLineToPoint:P_M(self.frame.size.width - p.x, p.y - h)]; + } + + CABasicAnimation *basic2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + basic2.duration = 1.5; + basic2.fromValue = @(0); + basic2.toValue = @(1); + basic2.autoreverses = NO; + basic2.duration = 1.0; + basic2.fillMode = kCAFillModeForwards; + + CAShapeLayer *shapeLayer = [CAShapeLayer layer]; + shapeLayer.path = path.CGPath; + shapeLayer.strokeColor = _levelLineColor.CGColor; + shapeLayer.lineWidth = 0.5; + [shapeLayer setLineDashPattern:@[@(3),@(3)]]; + [shapeLayer addAnimation:basic2 forKey:nil]; + + [self.layer insertSublayer:shapeLayer atIndex:0]; + [self.layerArr addObject:shapeLayer]; +} + +- (void)drawXTexts { + /* Darw x texts*/ + for (NSInteger i = 0; i<_xTexts.count; i++) { + CATextLayer *textLayer = [CATextLayer layer]; + CGSize size = [self sizeOfStringWithMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) textFont:self.xTextFont.pointSize aimString:_xTexts[i]]; + textLayer.bounds = CGRectMake(0, 0, size.width, size.height); + textLayer.string = _xTexts[i]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + textLayer.fontSize = self.xTextFont.pointSize; + textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; + textLayer.alignmentMode = kCAAlignmentCenter; + if (_leftBarValues[i] && _rightBarValues[i]) { + textLayer.position = CGPointMake(self.chartOrigin.x + (_barWidth * 2 + _barSpacing) * (i + 1) - _barWidth, self.chartOrigin.y + size.height/2.0f + 5); + } + else { + textLayer.position = CGPointMake((_barWidth + _barSpacing) * (i + 1) - _barWidth/2.0, self.chartOrigin.y + size.height/2.0f + 5); + } + + if (self.rotateForXAxisText) { + CGFloat r = -45.0 / 180.0 * M_PI; + textLayer.transform = CATransform3DMakeRotation(r, 0.0, 0.0, 1.0); + textLayer.position = CGPointMake(textLayer.position.x - size.width/2.0 * cos(r), textLayer.position.y - size.width/2.0 * sin(r)); + } + else { + textLayer.transform = CATransform3DIdentity; + } + + [self.scrollView.layer addSublayer:textLayer]; + [self.layerArr addObject:textLayer]; + } +} + +- (void)drawDualYTexts:(CGPoint)p { + + for (NSInteger i = 1; i <_levelLineNum + 1; i++) { + CGFloat h = i * lPerH * _yLeftRadix; + + if (self.needLeftYTexts) { + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + NSString *text = @(i * _yLeftRadix).stringValue; + CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yleftTextFont.pointSize aimString:text]; + textLayer.bounds = CGRectMake(0, 0, size.width, size.height); + textLayer.position = CGPointMake(p.x - size.width/2.0 - _leftYTextesMargin, p.y - h); + CFStringRef fontName = (__bridge CFStringRef)self.yleftTextFont.fontName; + CGFontRef fontRef = CGFontCreateWithFontName(fontName); + textLayer.font = fontRef; + textLayer.fontSize = self.yleftTextFont.pointSize; + CGFontRelease(fontRef); + textLayer.string = text; + textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; + [self.layer addSublayer:textLayer]; + [self.layerArr addObject:textLayer]; + } + + if (self.needRightYTexts) { + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + NSString *text = @(i * _yRightRadix).stringValue; + CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yRightTextFont.pointSize aimString:text]; + textLayer.bounds = CGRectMake(0, 0, size.width, size.height); + textLayer.position = CGPointMake(self.frame.size.width - p.x + size.width/2.0 + _leftYTextesMargin, p.y - h); + CFStringRef fontName = (__bridge CFStringRef)self.yRightTextFont.fontName; + CGFontRef fontRef = CGFontCreateWithFontName(fontName); + textLayer.font = fontRef; + textLayer.fontSize = self.yRightTextFont.pointSize; + CGFontRelease(fontRef); + textLayer.string = text; + textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; + + [self.layer addSublayer:textLayer]; + [self.layerArr addObject:textLayer]; + } + } +} + + +- (void)drawBars { + for (NSUInteger i = 0; i < self.leftBarValues.count; i ++) { + UIView *left = [UIView new]; + left.backgroundColor = self.leftBarBGColors.count > i ? self.leftBarBGColors[i] : self.leftBarBGColors.firstObject; + left.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing, self.chartOrigin.y, _barWidth, 0); + + UIView *right = [UIView new]; + right.backgroundColor = self.rightBarBGColors.count > i ? self.rightBarBGColors[i] : self.rightBarBGColors.firstObject; + right.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing + _barWidth, self.chartOrigin.y, _barWidth, 0); + + [self.scrollView addSubview:left]; + [self.scrollView addSubview:right]; + [self.leftBarViews addObject:left]; + [self.rightBarViews addObject:right]; + + [UIView animateWithDuration:1 animations:^{ + CGRect frame = left.frame; + frame.size.height = self.leftBarValues[i].floatValue * lPerH; + frame.origin.y = self.chartOrigin.y - frame.size.height - 1; + left.frame = frame; + + frame = right.frame; + frame.size.height = self.rightBarValues[i].floatValue * rPerH; + frame.origin.y = self.chartOrigin.y - frame.size.height - 1; + right.frame = frame; + } completion:^(BOOL finished) { + if (!finished) { + return; + } + + /* 动画结束后添加提示文字 */ + void (^addTextBlock)(UIView *, UIFont *, NSString *) = ^(UIView *view, UIFont *font, NSString *str) { + CGSize size = [self sizeOfStringWithMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) textFont:font.pointSize aimString:str]; + + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.bounds = CGRectMake(0, 0, size.width, size.height); + textLayer.position = CGPointMake(CGRectGetMidX(view.frame), CGRectGetMinY(view.frame) - size.height - 3); + textLayer.string = str; + textLayer.fontSize = font.pointSize; + textLayer.alignmentMode = kCAAlignmentCenter; + textLayer.contentsScale = [UIScreen mainScreen].scale; + textLayer.foregroundColor = self.drawTextColorForX_Y.CGColor; + + [self.layerArr addObject:textLayer]; + [self.scrollView.layer addSublayer:textLayer]; + }; + + addTextBlock(left, self.barTextFont, self.leftBarValues[i].stringValue); + addTextBlock(right, self.barTextFont, self.rightBarValues[i].stringValue); + }]; + } +} + +- (void)clear { + [self.leftBarViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.rightBarViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.layerArr makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; +} + +#pragma mark - Geters and Setters + +- (void)setContentInsets:(UIEdgeInsets)contentInsets { + [super setContentInsets:contentInsets]; + self.scrollView.frame = CGRectMake(contentInsets.left, + contentInsets.top, + self.frame.size.width - contentInsets.left - contentInsets.right, + self.frame.size.height - contentInsets.top - contentInsets.bottom); +} + +- (void)setLeftBarValues:(NSArray *)leftBarValues { + NSAssert(_yLeftRadix > 0, nil); + + _leftBarValues = leftBarValues; + + CGFloat max = 0; + for (NSNumber *num in leftBarValues) { + max = MAX(num.floatValue, max); + } + CGFloat t = max/_yLeftRadix; + t = t - floor(t) > 0 ? t + 1 : t; + self.levelLineNum = MAX((NSUInteger)t, _levelLineNum); +} + +- (void)setRightBarValues:(NSArray *)rightBarValues { + NSAssert(_yRightRadix > 0, nil); + + _rightBarValues = rightBarValues; + + CGFloat max = 0; + for (NSNumber *num in rightBarValues) { + max = MAX(num.floatValue, max); + } + CGFloat t = max/_yRightRadix; + t = t - floor(t) > 0 ? t + 1 : t; + self.levelLineNum = MAX((NSUInteger)t, _levelLineNum); +} + +- (void)setLevelLineNum:(NSUInteger)levelLineNum { + _levelLineNum = MAX(_levelLineNum, levelLineNum); +} + +- (void)setBgVewBackgoundColor:(UIColor *)bgVewBackgoundColor { + _bgVewBackgoundColor = bgVewBackgoundColor; +} + +- (UIScrollView *)scrollView { + if (!_scrollView) { + _scrollView = [[UIScrollView alloc] init]; + _scrollView.showsHorizontalScrollIndicator = false; + _scrollView.backgroundColor = [UIColor clearColor]; + } + return _scrollView; +} + +- (NSMutableArray *)layerArr { + if (!_layerArr) { + _layerArr = [[NSMutableArray alloc] init]; + } + return _layerArr; +} + +- (NSMutableArray *)rightBarViews { + if (!_rightBarViews) { + _rightBarViews = [[NSMutableArray alloc] init]; + } + return _rightBarViews; +} + +- (NSMutableArray *)leftBarViews { + if (!_leftBarViews) { + _leftBarViews = [[NSMutableArray alloc] init]; + } + return _leftBarViews; +} +@end diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index 88d810d..106c586 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -72,12 +72,13 @@ - (void)viewDidLoad { { [self showRowChart]; }break; + case 11: { + [self showDualBarChart]; + } + break; default: break; } - - - } @@ -581,6 +582,22 @@ - (void)showRowChart { [self.view addSubview:column]; } +- (void)showDualBarChart { + JHDualBarChart *chart = [[JHDualBarChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; + chart.yLeftRadix = 10; + chart.yRightRadix = 50; + chart.leftBarValues = @[@(20),@(30),@(89),@(45),@(57)]; + chart.rightBarValues = @[@(200),@(345),@(100),@(110),@(50)]; + chart.xTexts = @[@"first",@"second",@"third", @"fourth", @"fiveth"]; + chart.leftBarBGColors = @[[UIColor redColor]]; + chart.rightBarBGColors = @[[UIColor yellowColor]]; + chart.backgroundColor = [UIColor grayColor]; + chart.bgVewBackgoundColor = [UIColor grayColor]; + chart.rotateForXAxisText = YES; + + [self.view addSubview:chart]; + [chart showAnimation]; +} -(void)columnChart:(JHColumnChart*)chart columnItem:(UIView *)item didClickAtIndexRow:(NSIndexPath *)indexPath{ NSLog(@"%@",indexPath); diff --git a/JHChartDemo/ViewController.m b/JHChartDemo/ViewController.m index 5f7e7b8..da07792 100644 --- a/JHChartDemo/ViewController.m +++ b/JHChartDemo/ViewController.m @@ -22,8 +22,8 @@ - (void)viewDidLoad { self.view.backgroundColor = [UIColor whiteColor]; - _itemsArr = @[@"折线图-第一象限",@"折线图-第一二象限",@"折线图第一四象限",@"折线图-全象限",@"饼图",@"环状图",@"柱状图",@"表格",@"雷达图",@"散点图", @"横向柱状图"]; - + _itemsArr = @[@"折线图-第一象限",@"折线图-第一二象限",@"折线图第一四象限",@"折线图-全象限",@"饼图",@"环状图",@"柱状图",@"表格",@"雷达图",@"散点图", @"横向柱状图", @"双列柱状图"]; + _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height - 64) style:UITableViewStylePlain]; _tableView.dataSource = self; _tableView.delegate =self; From 8dbfc96ccce30a8b8ca0e2767e0a31c49c94401c Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 7 Dec 2017 14:20:16 +0800 Subject: [PATCH 04/11] support for dual bar with random count. --- JHChartDemo/JHChart/JHDualBarChart.h | 15 +++-- JHChartDemo/JHChart/JHDualBarChart.m | 90 ++++++++++++++++++---------- JHChartDemo/JHShowController.m | 8 +-- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/JHChartDemo/JHChart/JHDualBarChart.h b/JHChartDemo/JHChart/JHDualBarChart.h index 2fc7d07..93e7594 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.h +++ b/JHChartDemo/JHChart/JHDualBarChart.h @@ -28,12 +28,15 @@ */ @property (nonatomic, strong) NSArray *xTexts; -@property (nonatomic, assign) NSUInteger levelLineNum; - @property (nonatomic, assign) CGFloat yLeftRadix; @property (nonatomic, assign) CGFloat yRightRadix; +/** + * X axis classification of each icon + */ +@property (nonatomic, assign) NSUInteger levelLineNum; + @property (nonatomic, copy) UIFont *xTextFont; @property (nonatomic, copy) UIFont *yleftTextFont; @@ -53,12 +56,12 @@ @property (nonatomic, assign) BOOL needRightYTexts; -@property (nonatomic, assign) CGFloat leftYTextesMargin; +@property (nonatomic, assign) CGFloat leftYTextsMargin; /** * The background color of the content view */ -@property (nonatomic, strong) UIColor *bgVewBackgoundColor; +@property (nonatomic, strong) UIColor *chartBackgroundColor; /** * Column spacing, non continuous, default is 15 @@ -85,7 +88,9 @@ */ @property (nonatomic, strong) UIColor *levelLineColor; -/** Controls whether text for x-axis be straight or rotate 45 degree. */ +/** + * Controls whether text for x-axis be straight or rotate 45 degree. + */ @property (nonatomic) BOOL rotateForXAxisText; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index 2ff916a..b6e1078 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -38,7 +38,7 @@ - (void)commonInit { _needXLine = YES; _needLeftYTexts = YES; _needRightYTexts = YES; - _leftYTextesMargin = 5; + _leftYTextsMargin = 5; _xTextFont = [UIFont systemFontOfSize:8]; _yRightTextFont = [UIFont systemFontOfSize:8]; _yleftTextFont = [UIFont systemFontOfSize:8]; @@ -51,14 +51,13 @@ - (void)commonInit { } - (void)showAnimation { - NSAssert(self.leftBarValues.count == self.rightBarValues.count, @""); NSAssert(self.leftBarBGColors.count > 0 || self.rightBarBGColors.count > 0, @""); [self clear]; _barWidth = _barWidth ? : 30; _barSpacing = _barSpacing ?: 15; - _maxW = self.chartOrigin.x + _barWidth * (_leftBarValues.count + _rightBarValues.count) + (_barSpacing + 1) * _leftBarValues.count; + _maxW = self.chartOrigin.x + _barWidth * (_leftBarValues.count + _rightBarValues.count) + (_barSpacing + 1) * MAX(_leftBarValues.count, _rightBarValues.count); _maxH = self.chartOrigin.y; lPerH = _maxH / (_levelLineNum * _yLeftRadix); rPerH = _maxH / (_levelLineNum * _yRightRadix); @@ -135,11 +134,12 @@ - (void)drawXTexts { textLayer.fontSize = self.xTextFont.pointSize; textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; textLayer.alignmentMode = kCAAlignmentCenter; - if (_leftBarValues[i] && _rightBarValues[i]) { + + if (_leftBarValues.count > i && _rightBarValues.count > i) { textLayer.position = CGPointMake(self.chartOrigin.x + (_barWidth * 2 + _barSpacing) * (i + 1) - _barWidth, self.chartOrigin.y + size.height/2.0f + 5); } else { - textLayer.position = CGPointMake((_barWidth + _barSpacing) * (i + 1) - _barWidth/2.0, self.chartOrigin.y + size.height/2.0f + 5); + textLayer.position = CGPointMake(self.chartOrigin.x + (i + MIN(_leftBarValues.count, _rightBarValues.count)) * _barWidth + (_barSpacing) * (i + 1) + _barWidth/2.0, self.chartOrigin.y + size.height/2.0f + 5); } if (self.rotateForXAxisText) { @@ -167,7 +167,7 @@ - (void)drawDualYTexts:(CGPoint)p { NSString *text = @(i * _yLeftRadix).stringValue; CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yleftTextFont.pointSize aimString:text]; textLayer.bounds = CGRectMake(0, 0, size.width, size.height); - textLayer.position = CGPointMake(p.x - size.width/2.0 - _leftYTextesMargin, p.y - h); + textLayer.position = CGPointMake(p.x - size.width/2.0 - _leftYTextsMargin, p.y - h); CFStringRef fontName = (__bridge CFStringRef)self.yleftTextFont.fontName; CGFontRef fontRef = CGFontCreateWithFontName(fontName); textLayer.font = fontRef; @@ -185,7 +185,7 @@ - (void)drawDualYTexts:(CGPoint)p { NSString *text = @(i * _yRightRadix).stringValue; CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yRightTextFont.pointSize aimString:text]; textLayer.bounds = CGRectMake(0, 0, size.width, size.height); - textLayer.position = CGPointMake(self.frame.size.width - p.x + size.width/2.0 + _leftYTextesMargin, p.y - h); + textLayer.position = CGPointMake(self.frame.size.width - p.x + size.width/2.0 + _leftYTextsMargin, p.y - h); CFStringRef fontName = (__bridge CFStringRef)self.yRightTextFont.fontName; CGFontRef fontRef = CGFontCreateWithFontName(fontName); textLayer.font = fontRef; @@ -202,30 +202,52 @@ - (void)drawDualYTexts:(CGPoint)p { - (void)drawBars { + + NSArray *moreArr = self.leftBarValues.count >= self.rightBarValues.count ? self.leftBarValues : self.rightBarValues; + for (NSUInteger i = 0; i < self.leftBarValues.count; i ++) { - UIView *left = [UIView new]; - left.backgroundColor = self.leftBarBGColors.count > i ? self.leftBarBGColors[i] : self.leftBarBGColors.firstObject; - left.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing, self.chartOrigin.y, _barWidth, 0); - - UIView *right = [UIView new]; - right.backgroundColor = self.rightBarBGColors.count > i ? self.rightBarBGColors[i] : self.rightBarBGColors.firstObject; - right.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing + _barWidth, self.chartOrigin.y, _barWidth, 0); + UIView *view = [UIView new]; + view.backgroundColor = self.leftBarBGColors.count > i ? self.leftBarBGColors[i] : self.leftBarBGColors.firstObject; + [self.scrollView addSubview:view]; + [self.leftBarViews addObject:view]; + } + + for (NSUInteger i = 0; i < self.rightBarValues.count; i ++) { + UIView *view = [UIView new]; + view.backgroundColor = self.rightBarBGColors.count > i ? self.rightBarBGColors[i] : self.rightBarBGColors.firstObject; + [self.scrollView addSubview:view]; + [self.rightBarViews addObject:view]; + } + + for (NSUInteger i = 0; i < moreArr.count; i ++) { + UIView *left = self.leftBarViews.count > i ? self.leftBarViews[i] : nil; + UIView *right = self.rightBarViews.count > i ? self.rightBarViews[i] : nil; - [self.scrollView addSubview:left]; - [self.scrollView addSubview:right]; - [self.leftBarViews addObject:left]; - [self.rightBarViews addObject:right]; + if (!left) { + right.frame = CGRectMake(self.chartOrigin.x + (self.leftBarViews.count + i) * _barWidth + (i + 1) * _barSpacing, self.chartOrigin.y, _barWidth, 0); + } + if (!right) { + left.frame = CGRectMake(self.chartOrigin.x + (self.rightBarViews.count + i) * _barWidth + (i + 1) * _barSpacing, self.chartOrigin.y, _barWidth, 0); + } + else { + left.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing, self.chartOrigin.y, _barWidth, 0); + right.frame = CGRectMake(self.chartOrigin.x + i * (_barWidth*2 + _barSpacing) + _barSpacing + _barWidth, self.chartOrigin.y, _barWidth, 0); + } [UIView animateWithDuration:1 animations:^{ - CGRect frame = left.frame; - frame.size.height = self.leftBarValues[i].floatValue * lPerH; - frame.origin.y = self.chartOrigin.y - frame.size.height - 1; - left.frame = frame; + if (left) { + CGRect frame = left.frame; + frame.size.height = self.leftBarValues[i].floatValue * lPerH; + frame.origin.y = self.chartOrigin.y - frame.size.height - 1; + left.frame = frame; + } + if (right) { + CGRect frame = right.frame; + frame.size.height = self.rightBarValues[i].floatValue * rPerH; + frame.origin.y = self.chartOrigin.y - frame.size.height - 1; + right.frame = frame; + } - frame = right.frame; - frame.size.height = self.rightBarValues[i].floatValue * rPerH; - frame.origin.y = self.chartOrigin.y - frame.size.height - 1; - right.frame = frame; } completion:^(BOOL finished) { if (!finished) { return; @@ -248,8 +270,12 @@ - (void)drawBars { [self.scrollView.layer addSublayer:textLayer]; }; - addTextBlock(left, self.barTextFont, self.leftBarValues[i].stringValue); - addTextBlock(right, self.barTextFont, self.rightBarValues[i].stringValue); + if (self.leftBarValues.count > i) { + addTextBlock(left, self.barTextFont, self.leftBarValues[i].stringValue); + } + if (self.rightBarValues.count > i) { + addTextBlock(right, self.barTextFont, self.rightBarValues[i].stringValue); + } }]; } } @@ -271,7 +297,7 @@ - (void)setContentInsets:(UIEdgeInsets)contentInsets { } - (void)setLeftBarValues:(NSArray *)leftBarValues { - NSAssert(_yLeftRadix > 0, nil); + NSAssert(_yLeftRadix > 0, @"You should set yLeftRadix first"); _leftBarValues = leftBarValues; @@ -285,7 +311,7 @@ - (void)setLeftBarValues:(NSArray *)leftBarValues { } - (void)setRightBarValues:(NSArray *)rightBarValues { - NSAssert(_yRightRadix > 0, nil); + NSAssert(_yRightRadix > 0, @"You should set yLeftRadix first"); _rightBarValues = rightBarValues; @@ -302,8 +328,8 @@ - (void)setLevelLineNum:(NSUInteger)levelLineNum { _levelLineNum = MAX(_levelLineNum, levelLineNum); } -- (void)setBgVewBackgoundColor:(UIColor *)bgVewBackgoundColor { - _bgVewBackgoundColor = bgVewBackgoundColor; +- (void)setChartBackgroundColor:(UIColor *)chartBackgroundColor { + _chartBackgroundColor = chartBackgroundColor; } - (UIScrollView *)scrollView { diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index 106c586..30f70d0 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -584,15 +584,15 @@ - (void)showRowChart { - (void)showDualBarChart { JHDualBarChart *chart = [[JHDualBarChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; - chart.yLeftRadix = 10; + chart.yLeftRadix = 25; chart.yRightRadix = 50; + chart.levelLineNum = 6; chart.leftBarValues = @[@(20),@(30),@(89),@(45),@(57)]; - chart.rightBarValues = @[@(200),@(345),@(100),@(110),@(50)]; chart.xTexts = @[@"first",@"second",@"third", @"fourth", @"fiveth"]; - chart.leftBarBGColors = @[[UIColor redColor]]; + chart.leftBarBGColors = @[[UIColor colorWithRed:191/255.0 green:215.0/255.0 blue:242.0/255.0 alpha:1]]; chart.rightBarBGColors = @[[UIColor yellowColor]]; chart.backgroundColor = [UIColor grayColor]; - chart.bgVewBackgoundColor = [UIColor grayColor]; + chart.chartBackgroundColor = [UIColor grayColor]; chart.rotateForXAxisText = YES; [self.view addSubview:chart]; From 80f21f06b3783ff727d79dcc6615640741c94497 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 7 Dec 2017 15:22:46 +0800 Subject: [PATCH 05/11] add support for dual lines and bars. --- JHChartDemo/JHChart/JHChart.h | 4 ++ JHChartDemo/JHChart/JHDualBarChart.h | 7 +-- JHChartDemo/JHChart/JHDualBarChart.m | 67 +++++++++++++++++++++++++++- JHChartDemo/JHShowController.m | 25 +++++++---- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/JHChartDemo/JHChart/JHChart.h b/JHChartDemo/JHChart/JHChart.h index eda60a5..17da662 100644 --- a/JHChartDemo/JHChart/JHChart.h +++ b/JHChartDemo/JHChart/JHChart.h @@ -14,8 +14,11 @@ #define G_W(r) CGRectGetWidth(r) #define G_H(r) CGRectGetHeight(r) +#define SAFE_ACCESS(a, i) (((a).count > i) ? (a)[i] : nil) + #define weakSelf(weakSelf) __weak typeof(self) weakself = self; #define XORYLINEMAXSIZE CGSizeMake(CGFLOAT_MAX,30) + @interface JHChart : UIView @@ -152,4 +155,5 @@ - (CGSize)sizeOfStringWithMaxSize:(CGSize)maxSize textFont:(CGFloat)fontSize aimString:(NSString *)aimString; + @end diff --git a/JHChartDemo/JHChart/JHDualBarChart.h b/JHChartDemo/JHChart/JHDualBarChart.h index 93e7594..628cd53 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.h +++ b/JHChartDemo/JHChart/JHDualBarChart.h @@ -94,13 +94,14 @@ @property (nonatomic) BOOL rotateForXAxisText; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** - * If isShowLineChart proprety is YES,we need this value array to draw chart + * If showLineChart proprety is YES,we need this value array to draw chart */ /** * Whether this chart show line or not.Default is NO; */ -@property (nonatomic, assign) BOOL isShowLineChart; +@property (nonatomic, assign) BOOL showLineChart; @property (nonatomic, strong) NSArray *leftLineValues; @@ -115,7 +116,7 @@ * if isShowLineChart proprety is Yes,we will draw this linechart valuepoint with this color * Default is yellow */ -@property (nonatomic, strong)UIColor *leftLinePointColor; +@property (nonatomic, strong) UIColor *leftLinePointColor; @property (nonatomic, strong) NSArray *rightLineValues; diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index b6e1078..af8e970 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -7,7 +7,8 @@ // #import "JHDualBarChart.h" -@interface JHDualBarChart () { +@interface JHDualBarChart () +{ CGFloat _maxH, _maxW, lPerH, rPerH; } @@ -46,6 +47,7 @@ - (void)commonInit { _drawTextColorForX_Y = [UIColor blackColor]; _colorForXYLine = [UIColor blackColor]; _levelLineColor = [UIColor blackColor]; + _showLineChart = false; self.contentInsets = UIEdgeInsetsMake(10, 30, 0, 30); self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height - 20); } @@ -276,16 +278,79 @@ - (void)drawBars { if (self.rightBarValues.count > i) { addTextBlock(right, self.barTextFont, self.rightBarValues[i].stringValue); } + + [self drawLineChart]; }]; } } +- (void)drawLineChart { + if (!self.showLineChart) { + return; + } + NSAssert(self.leftLineValues.count <= MAX(self.leftBarValues.count, self.rightBarValues.count), @""); + NSAssert(self.rightLineValues.count <= MAX(self.leftBarValues.count, self.rightBarValues.count), @""); + + void (^addLineBlock)(NSArray *, CGFloat, UIColor *, BOOL) = ^(NSArray *values, CGFloat h, UIColor *lineColor, BOOL isLeft) { + + UIBezierPath *path = [UIBezierPath bezierPath]; + for (NSUInteger i = 0; i < values.count; i ++) { + UIView *l = SAFE_ACCESS(self.leftBarViews, i); + UIView *r = SAFE_ACCESS(self.rightBarViews, i); + if (l && r) { + if (i == 0) { + [path moveToPoint:P_M(CGRectGetMidX((isLeft ? l : r).frame), self.chartOrigin.y - h * [values[i] floatValue])]; + } + else { + [path addLineToPoint:P_M(CGRectGetMidX((isLeft ? l : r).frame), self.chartOrigin.y - h * [values[i] floatValue])]; + } + } + else if (l || r) { + l = l ?: r; + if (i == 0) { + [path moveToPoint:P_M(CGRectGetMidX(l.frame), self.chartOrigin.y - h * [values[i] floatValue])]; + } + else { + [path addLineToPoint:P_M(CGRectGetMidX(l.frame), self.chartOrigin.y - h * [values[i] floatValue])]; + } + } + } + + CAShapeLayer *shaper = [CAShapeLayer layer]; + shaper.path = path.CGPath; + shaper.frame = self.scrollView.bounds; + shaper.lineWidth = 1.5; + shaper.fillColor = [UIColor clearColor].CGColor; + shaper.strokeColor = lineColor.CGColor; + + [self.layerArr addObject:shaper]; + + CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:NSStringFromSelector(@selector(strokeEnd))]; + + basic.fromValue = @0; + basic.toValue = @1; + basic.duration = 1; + basic.delegate = self; + [shaper addAnimation:basic forKey:@"stokentoend"]; + [self.scrollView.layer addSublayer:shaper]; + }; + + addLineBlock(self.leftLineValues, lPerH, self.leftLinePathColor, true); + addLineBlock(self.rightLineValues, rPerH, self.rightLinePathColor, false); +} + - (void)clear { [self.leftBarViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; [self.rightBarViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; [self.layerArr makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; } +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { + if (flag) { + // TODO: add line point + } +} + #pragma mark - Geters and Setters - (void)setContentInsets:(UIEdgeInsets)contentInsets { diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index 30f70d0..fff4ff0 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -584,16 +584,23 @@ - (void)showRowChart { - (void)showDualBarChart { JHDualBarChart *chart = [[JHDualBarChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; - chart.yLeftRadix = 25; - chart.yRightRadix = 50; - chart.levelLineNum = 6; - chart.leftBarValues = @[@(20),@(30),@(89),@(45),@(57)]; - chart.xTexts = @[@"first",@"second",@"third", @"fourth", @"fiveth"]; - chart.leftBarBGColors = @[[UIColor colorWithRed:191/255.0 green:215.0/255.0 blue:242.0/255.0 alpha:1]]; - chart.rightBarBGColors = @[[UIColor yellowColor]]; - chart.backgroundColor = [UIColor grayColor]; + chart.yLeftRadix = 25; + chart.yRightRadix = 50; + chart.levelLineNum = 6; + chart.leftBarValues = @[@(20),@(30),@(89),@(45),@(57)]; + chart.rightBarValues = @[@(100),@(200),@(287),@(34),@(30)]; + chart.leftLineValues = @[@(20),@(30),@(89),@(45),@(57)]; + chart.rightBarValues = @[@(100),@(200),@(287),@(34),@(30)]; + chart.rightLineValues = @[@(100),@(200),@(287),@(34),@(30)]; + chart.xTexts = @[@"first",@"second",@"third", @"fourth", @"fiveth"]; + chart.leftBarBGColors = @[[UIColor colorWithRed:23/255.0 green:93.0/255.0 blue:180.0/255.0 alpha:1]]; + chart.rightBarBGColors = @[[UIColor colorWithRed:191/255.0 green:215.0/255.0 blue:242.0/255.0 alpha:1]]; + chart.leftLinePathColor = [UIColor redColor]; + chart.rightLinePathColor = [UIColor yellowColor]; + chart.backgroundColor = [UIColor grayColor]; chart.chartBackgroundColor = [UIColor grayColor]; - chart.rotateForXAxisText = YES; + chart.showLineChart = true; + chart.rotateForXAxisText = YES; [self.view addSubview:chart]; [chart showAnimation]; From 0f127a02f39cdfeaac21f65fd012a46be4a16a9a Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 7 Dec 2017 17:24:33 +0800 Subject: [PATCH 06/11] support sub title. --- JHChartDemo/JHChart/JHChart.h | 2 + JHChartDemo/JHChart/JHChart.m | 8 +- JHChartDemo/JHChart/JHDualBarChart.h | 8 ++ JHChartDemo/JHChart/JHDualBarChart.m | 149 ++++++++++++++++++++------- JHChartDemo/JHShowController.m | 4 +- 5 files changed, 134 insertions(+), 37 deletions(-) diff --git a/JHChartDemo/JHChart/JHChart.h b/JHChartDemo/JHChart/JHChart.h index 17da662..603cf74 100644 --- a/JHChartDemo/JHChart/JHChart.h +++ b/JHChartDemo/JHChart/JHChart.h @@ -156,4 +156,6 @@ textFont:(CGFloat)fontSize aimString:(NSString *)aimString; +- (CGSize)sizeOfString:(NSString *)string withFont:(UIFont *)font; + @end diff --git a/JHChartDemo/JHChart/JHChart.m b/JHChartDemo/JHChart/JHChart.m index c3e84c8..6e69b34 100644 --- a/JHChartDemo/JHChart/JHChart.m +++ b/JHChartDemo/JHChart/JHChart.m @@ -156,9 +156,15 @@ - (void)drawPointWithRedius:(CGFloat)redius andColor:(UIColor *)color andPoint:( */ - (CGSize)sizeOfStringWithMaxSize:(CGSize)maxSize textFont:(CGFloat)fontSize aimString:(NSString *)aimString{ return [[NSString stringWithFormat:@"%@",aimString] boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size; - } +- (CGSize)sizeOfString:(NSString *)string withFont:(UIFont *)font { + return [string boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) + options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine + attributes:@{NSFontAttributeName:font} context:nil].size; +} + + -(void)dealloc{ #if DEBUG NSLog(@"%@ has dealloc",NSStringFromClass([self class])); diff --git a/JHChartDemo/JHChart/JHDualBarChart.h b/JHChartDemo/JHChart/JHDualBarChart.h index 628cd53..a15523f 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.h +++ b/JHChartDemo/JHChart/JHDualBarChart.h @@ -45,6 +45,14 @@ @property (nonatomic, copy) UIFont *barTextFont; +@property (nonatomic, copy) NSString *yLeftDetailText; + +@property (nonatomic, copy) NSString *yRightDetailText; + +@property (nonatomic, copy) UIFont *yDetailTextFont; + +@property (nonatomic, copy) UIFont *chartSubTitleFont; + /** * Whether the need for Y, X axis, the default YES */ diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index af8e970..6f208da 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -44,12 +44,14 @@ - (void)commonInit { _yRightTextFont = [UIFont systemFontOfSize:8]; _yleftTextFont = [UIFont systemFontOfSize:8]; _barTextFont = [UIFont systemFontOfSize:8]; + _yDetailTextFont = [UIFont systemFontOfSize:10]; + _chartSubTitleFont = [UIFont systemFontOfSize:16]; _drawTextColorForX_Y = [UIColor blackColor]; _colorForXYLine = [UIColor blackColor]; _levelLineColor = [UIColor blackColor]; _showLineChart = false; - self.contentInsets = UIEdgeInsetsMake(10, 30, 0, 30); - self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height - 20); + self.contentInsets = UIEdgeInsetsMake(50, 50, 0, 50); + self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height - 40); } - (void)showAnimation { @@ -67,7 +69,8 @@ - (void)showAnimation { self.scrollView.contentSize = CGSizeMake(_maxW, _maxH); CGPoint p = [self.scrollView convertPoint:self.chartOrigin toView:self]; - + + [self drawChartTitles]; [self drawXAndYAxis:p]; [self drawLevelLines:p]; [self drawDualYTexts:p]; @@ -75,6 +78,69 @@ - (void)showAnimation { [self drawBars]; } +- (void)drawChartTitles { + NSMutableArray *array = [NSMutableArray new]; + + if (self.leftBarValues.count > 0) { + CALayer *lump = [CALayer layer]; + lump.backgroundColor = self.leftBarBGColors.firstObject.CGColor; + lump.frame = CGRectMake(0, 0, 10, 10); + CATextLayer *l = [self createTextLayer:self.yLeftDetailText font:self.chartSubTitleFont color:self.leftBarBGColors.firstObject]; + CGRect f = l.frame; + f.size.width += 5; + l.frame = f; + + CALayer *container = [CALayer new]; + container.backgroundColor = [UIColor clearColor].CGColor; + container.frame = CGRectMake(0, 0, lump.frame.size.width + l.frame.size.width + 5, MAX(lump.frame.size.height, l.frame.size.height)); + + [container addSublayer:lump]; + [container addSublayer:l]; + + lump.position = P_M(lump.frame.size.width/2.0, container.frame.size.height/2.0); + l.position = P_M(lump.frame.size.width + 5 + l.frame.size.width/2.0, container.frame.size.height/2.0); + + [array addObject:container]; + } + if (self.rightBarValues.count > 0) { + CALayer *lump = [CALayer layer]; + lump.backgroundColor = self.rightBarBGColors.firstObject.CGColor; + lump.frame = CGRectMake(0, 0, 10, 10); + CATextLayer *l = [self createTextLayer:self.yRightDetailText font:self.chartSubTitleFont color:self.rightBarBGColors.firstObject]; + CGRect f = l.frame; + f.size.width += 5; + l.frame = f; + + + CALayer *container = [CALayer new]; + container.backgroundColor = [UIColor clearColor].CGColor; + container.frame = CGRectMake(0, 0, lump.frame.size.width + l.frame.size.width + 5, MAX(lump.frame.size.height, l.frame.size.height)); + + lump.position = P_M(lump.frame.size.width/2.0, container.frame.size.height/2.0); + l.position = P_M(lump.frame.size.width + 5 + l.frame.size.width/2.0, container.frame.size.height/2.0); + + [container addSublayer:lump]; + [container addSublayer:l]; + + [array addObject:container]; + } + + for (CALayer *l in array) { + [self.layerArr addObject:l]; + [self.layer addSublayer:l]; + } + + if (array.count == 1) { + array.firstObject.position = P_M(self.frame.size.width/2.0f, 30); + } + else if (array.count == 2) { + CGFloat h = 15; + CGFloat w = (self.frame.size.width - h - array.firstObject.frame.size.width - array[1].frame.size.width) / 2.0; + array.firstObject.position = P_M(w + array.firstObject.frame.size.width/2.0f, 30); + array[1].position = P_M(CGRectGetMaxX(array.firstObject.frame) + h + array[1].frame.size.width/2.0f, 30); + } +} + - (void)drawXAndYAxis:(CGPoint)p { if (_needXLine) { UIBezierPath *bezier = [UIBezierPath bezierPath]; @@ -159,47 +225,41 @@ - (void)drawXTexts { } - (void)drawDualYTexts:(CGPoint)p { - + for (NSInteger i = 1; i <_levelLineNum + 1; i++) { CGFloat h = i * lPerH * _yLeftRadix; if (self.needLeftYTexts) { - CATextLayer *textLayer = [CATextLayer layer]; - textLayer.contentsScale = [UIScreen mainScreen].scale; - NSString *text = @(i * _yLeftRadix).stringValue; - CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yleftTextFont.pointSize aimString:text]; - textLayer.bounds = CGRectMake(0, 0, size.width, size.height); - textLayer.position = CGPointMake(p.x - size.width/2.0 - _leftYTextsMargin, p.y - h); - CFStringRef fontName = (__bridge CFStringRef)self.yleftTextFont.fontName; - CGFontRef fontRef = CGFontCreateWithFontName(fontName); - textLayer.font = fontRef; - textLayer.fontSize = self.yleftTextFont.pointSize; - CGFontRelease(fontRef); - textLayer.string = text; - textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; - [self.layer addSublayer:textLayer]; - [self.layerArr addObject:textLayer]; + CATextLayer *layer = [self createTextLayer:@(i * _yLeftRadix).stringValue font:_yleftTextFont color:_drawTextColorForX_Y]; + layer.position = CGPointMake(p.x - layer.frame.size.width/2.0 - _leftYTextsMargin, p.y - h); + [self.layer addSublayer:layer]; + [self.layerArr addObject:layer]; } if (self.needRightYTexts) { - CATextLayer *textLayer = [CATextLayer layer]; - textLayer.contentsScale = [UIScreen mainScreen].scale; - NSString *text = @(i * _yRightRadix).stringValue; - CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yRightTextFont.pointSize aimString:text]; - textLayer.bounds = CGRectMake(0, 0, size.width, size.height); - textLayer.position = CGPointMake(self.frame.size.width - p.x + size.width/2.0 + _leftYTextsMargin, p.y - h); - CFStringRef fontName = (__bridge CFStringRef)self.yRightTextFont.fontName; - CGFontRef fontRef = CGFontCreateWithFontName(fontName); - textLayer.font = fontRef; - textLayer.fontSize = self.yRightTextFont.pointSize; - CGFontRelease(fontRef); - textLayer.string = text; - textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; - - [self.layer addSublayer:textLayer]; - [self.layerArr addObject:textLayer]; + CATextLayer *layer = [self createTextLayer:@(i * _yRightRadix).stringValue font:_yRightTextFont color:_drawTextColorForX_Y]; + layer.position = CGPointMake(self.frame.size.width - p.x + layer.frame.size.width/2.0 + _leftYTextsMargin, p.y - h); + [self.layer addSublayer:layer]; + [self.layerArr addObject:layer]; } } + + if (_needLeftYTexts) { + CATextLayer *layer = [self createTextLayer:_yLeftDetailText font:_yDetailTextFont color:_drawTextColorForX_Y]; + layer.position = CGPointMake(p.x - layer.frame.size.height/2.0 - 20, p.y - _maxH/2.0f); + layer.transform = CATransform3DMakeRotation(-M_PI_2, 0.0, 0.0, 1.0); + + [self.layer addSublayer:layer]; + [self.layerArr addObject:layer]; + } + if (self.needRightYTexts) { + CATextLayer *layer = [self createTextLayer:_yRightDetailText font:_yDetailTextFont color:_drawTextColorForX_Y]; + layer.position = CGPointMake(self.frame.size.width - p.x + layer.frame.size.height/2.0 + _leftYTextsMargin + 20, p.y - _maxH/2.0f); + layer.transform = CATransform3DMakeRotation(-M_PI_2, 0.0, 0.0, 1.0); + + [self.layer addSublayer:layer]; + [self.layerArr addObject:layer]; + } } @@ -426,4 +486,23 @@ - (NSMutableArray *)leftBarViews { } return _leftBarViews; } + +- (CATextLayer *)createTextLayer:(NSString *)text + font:(UIFont *)font + color:(UIColor *)textColor { + CATextLayer *textLayer = [CATextLayer layer]; + textLayer.contentsScale = [UIScreen mainScreen].scale; + CGSize size = [self sizeOfString:text withFont:font]; + textLayer.bounds = CGRectMake(0, 0, size.width, size.height); + CGFontRef fontRef = CGFontCreateWithFontName((__bridge CFStringRef)font.fontName); + textLayer.font = fontRef; + textLayer.fontSize = font.pointSize; + CGFontRelease(fontRef); + + textLayer.string = text; + textLayer.foregroundColor = textColor.CGColor; + return textLayer; +}; + + @end diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index fff4ff0..f01a580 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -583,7 +583,7 @@ - (void)showRowChart { } - (void)showDualBarChart { - JHDualBarChart *chart = [[JHDualBarChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; + JHDualBarChart *chart = [[JHDualBarChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; chart.yLeftRadix = 25; chart.yRightRadix = 50; chart.levelLineNum = 6; @@ -601,6 +601,8 @@ - (void)showDualBarChart { chart.chartBackgroundColor = [UIColor grayColor]; chart.showLineChart = true; chart.rotateForXAxisText = YES; + chart.yLeftDetailText = @"Number of photos"; + chart.yRightDetailText = @"Engagement per photo"; [self.view addSubview:chart]; [chart showAnimation]; From 76379cc7f1019d05d61a287e1930b9be93e9a11a Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Thu, 7 Dec 2017 18:13:08 +0800 Subject: [PATCH 07/11] Update UI --- JHChartDemo.xcodeproj/project.pbxproj | 4 +++- JHChartDemo/JHChart/JHDualBarChart.m | 18 +++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/JHChartDemo.xcodeproj/project.pbxproj b/JHChartDemo.xcodeproj/project.pbxproj index 04921b5..cd762b6 100644 --- a/JHChartDemo.xcodeproj/project.pbxproj +++ b/JHChartDemo.xcodeproj/project.pbxproj @@ -377,7 +377,7 @@ TargetAttributes = { AA5E2BAD1CBA298F00FC19EE = { CreatedOnToolsVersion = 7.2.1; - DevelopmentTeam = HRJA43XU8W; + DevelopmentTeam = A4ZY6X2WCR; }; AA5E2BC61CBA298F00FC19EE = { CreatedOnToolsVersion = 7.2.1; @@ -638,6 +638,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = A4ZY6X2WCR; INFOPLIST_FILE = JHChartDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -653,6 +654,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = A4ZY6X2WCR; INFOPLIST_FILE = JHChartDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index 6f208da..c8ab982 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -50,8 +50,8 @@ - (void)commonInit { _colorForXYLine = [UIColor blackColor]; _levelLineColor = [UIColor blackColor]; _showLineChart = false; - self.contentInsets = UIEdgeInsetsMake(50, 50, 0, 50); - self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height - 40); + self.contentInsets = UIEdgeInsetsMake(50, 50, 40, 50); + self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height-self.contentInsets.bottom); } - (void)showAnimation { @@ -61,13 +61,13 @@ - (void)showAnimation { _barWidth = _barWidth ? : 30; _barSpacing = _barSpacing ?: 15; - _maxW = self.chartOrigin.x + _barWidth * (_leftBarValues.count + _rightBarValues.count) + (_barSpacing + 1) * MAX(_leftBarValues.count, _rightBarValues.count); - _maxH = self.chartOrigin.y; + _maxW = self.chartOrigin.x + _barWidth * (_leftBarValues.count + _rightBarValues.count) + _barSpacing * (1 + MAX(_leftBarValues.count, _rightBarValues.count)); + _maxH = self.frame.size.height - self.contentInsets.top - self.contentInsets.bottom; lPerH = _maxH / (_levelLineNum * _yLeftRadix); rPerH = _maxH / (_levelLineNum * _yRightRadix); self.scrollView.contentSize = CGSizeMake(_maxW, _maxH); - + CGPoint p = [self.scrollView convertPoint:self.chartOrigin toView:self]; [self drawChartTitles]; @@ -87,7 +87,7 @@ - (void)drawChartTitles { lump.frame = CGRectMake(0, 0, 10, 10); CATextLayer *l = [self createTextLayer:self.yLeftDetailText font:self.chartSubTitleFont color:self.leftBarBGColors.firstObject]; CGRect f = l.frame; - f.size.width += 5; + f.size.width += 6; l.frame = f; CALayer *container = [CALayer new]; @@ -108,7 +108,7 @@ - (void)drawChartTitles { lump.frame = CGRectMake(0, 0, 10, 10); CATextLayer *l = [self createTextLayer:self.yRightDetailText font:self.chartSubTitleFont color:self.rightBarBGColors.firstObject]; CGRect f = l.frame; - f.size.width += 5; + f.size.width += 6; l.frame = f; @@ -416,9 +416,9 @@ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { - (void)setContentInsets:(UIEdgeInsets)contentInsets { [super setContentInsets:contentInsets]; self.scrollView.frame = CGRectMake(contentInsets.left, - contentInsets.top, + 0, self.frame.size.width - contentInsets.left - contentInsets.right, - self.frame.size.height - contentInsets.top - contentInsets.bottom); + self.frame.size.height); } - (void)setLeftBarValues:(NSArray *)leftBarValues { From 5ba8506d65c4b58432a273fa6425f23638018209 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Fri, 8 Dec 2017 11:19:58 +0800 Subject: [PATCH 08/11] Update file. --- JHChartDemo/JHChart/JHDualBarChart.m | 45 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index c8ab982..c90ba5b 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -24,6 +24,14 @@ @interface JHDualBarChart () @implementation JHDualBarChart +- (instancetype)init { + self = [super init]; + if (self) { + NSAssert(false, @"Please use initWithFrame"); + } + return self; +} + - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { @@ -34,24 +42,24 @@ - (instancetype)initWithFrame:(CGRect)frame { - (void)commonInit { [self addSubview:self.scrollView]; - self.scrollView.frame = self.bounds; - _needYLines = YES; - _needXLine = YES; - _needLeftYTexts = YES; - _needRightYTexts = YES; - _leftYTextsMargin = 5; - _xTextFont = [UIFont systemFontOfSize:8]; - _yRightTextFont = [UIFont systemFontOfSize:8]; - _yleftTextFont = [UIFont systemFontOfSize:8]; - _barTextFont = [UIFont systemFontOfSize:8]; - _yDetailTextFont = [UIFont systemFontOfSize:10]; - _chartSubTitleFont = [UIFont systemFontOfSize:16]; + + _needYLines = YES; + _needXLine = YES; + _needLeftYTexts = YES; + _needRightYTexts = YES; + _leftYTextsMargin = 5; + _xTextFont = [UIFont systemFontOfSize:8]; + _yRightTextFont = [UIFont systemFontOfSize:8]; + _yleftTextFont = [UIFont systemFontOfSize:8]; + _barTextFont = [UIFont systemFontOfSize:8]; + _yDetailTextFont = [UIFont systemFontOfSize:10]; + _chartSubTitleFont = [UIFont systemFontOfSize:16]; _drawTextColorForX_Y = [UIColor blackColor]; - _colorForXYLine = [UIColor blackColor]; - _levelLineColor = [UIColor blackColor]; - _showLineChart = false; - self.contentInsets = UIEdgeInsetsMake(50, 50, 40, 50); - self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height-self.contentInsets.bottom); + _colorForXYLine = [UIColor blackColor]; + _levelLineColor = [UIColor blackColor]; + _showLineChart = false; + self.contentInsets = UIEdgeInsetsMake(50, 50, 40, 50); + self.chartOrigin = CGPointMake(0, self.scrollView.frame.size.height-self.contentInsets.bottom); } - (void)showAnimation { @@ -460,8 +468,10 @@ - (void)setChartBackgroundColor:(UIColor *)chartBackgroundColor { - (UIScrollView *)scrollView { if (!_scrollView) { _scrollView = [[UIScrollView alloc] init]; + _scrollView.frame = self.bounds; _scrollView.showsHorizontalScrollIndicator = false; _scrollView.backgroundColor = [UIColor clearColor]; + _scrollView.clipsToBounds = true; } return _scrollView; } @@ -504,5 +514,4 @@ - (CATextLayer *)createTextLayer:(NSString *)text return textLayer; }; - @end From 6c15ce28e6015eed306f223de4aff3f3d3dbce41 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Mon, 11 Dec 2017 11:32:46 +0800 Subject: [PATCH 09/11] Update horizontal bar view . --- JHChartDemo.xcodeproj/project.pbxproj | 4 + JHChartDemo/.DS_Store | Bin 10244 -> 10244 bytes JHChartDemo/AppDelegate.m | 4 + .../UIDebuggingInformationOverlay+Enable.m | 99 ++++++++++++++++++ JHChartDemo/JHChart/JHDualBarChart.m | 2 +- JHChartDemo/JHChart/JHRowChart.h | 32 ++---- JHChartDemo/JHChart/JHRowChart.m | 12 +-- JHChartDemo/JHChart/JHRowItem.h | 8 +- JHChartDemo/JHShowController.m | 31 +++--- 9 files changed, 144 insertions(+), 48 deletions(-) create mode 100644 JHChartDemo/GIFResource/UIDebuggingInformationOverlay+Enable.m diff --git a/JHChartDemo.xcodeproj/project.pbxproj b/JHChartDemo.xcodeproj/project.pbxproj index cd762b6..42d6cad 100644 --- a/JHChartDemo.xcodeproj/project.pbxproj +++ b/JHChartDemo.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ E9D49A191E0927EC000453F0 /* 柱状图demo2.png in Resources */ = {isa = PBXBuildFile; fileRef = E9D49A181E0927EC000453F0 /* 柱状图demo2.png */; }; E9D49A1B1E092D21000453F0 /* 饼状图demo1.png in Resources */ = {isa = PBXBuildFile; fileRef = E9D49A1A1E092D21000453F0 /* 饼状图demo1.png */; }; E9DAFF3E1D6EB6E900D4E148 /* JHTableDataRowModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E9DAFF3D1D6EB6E900D4E148 /* JHTableDataRowModel.m */; }; + F133F98C1FDA476E0056E5A5 /* UIDebuggingInformationOverlay+Enable.m in Sources */ = {isa = PBXBuildFile; fileRef = F133F98B1FDA476D0056E5A5 /* UIDebuggingInformationOverlay+Enable.m */; }; F1743D651FCFBB7300B2738A /* JHRowItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D641FCFBB7300B2738A /* JHRowItem.m */; }; F1B4D44D1FCFF3020035E16D /* JHRowChart.m in Sources */ = {isa = PBXBuildFile; fileRef = F1743D611FCFBB0200B2738A /* JHRowChart.m */; }; F1E85A481FD7C91E00713875 /* JHDualBarChart.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E85A471FD7C91E00713875 /* JHDualBarChart.m */; }; @@ -141,6 +142,7 @@ E9D49A1A1E092D21000453F0 /* 饼状图demo1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "饼状图demo1.png"; sourceTree = ""; }; E9DAFF3C1D6EB6E900D4E148 /* JHTableDataRowModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JHTableDataRowModel.h; sourceTree = ""; }; E9DAFF3D1D6EB6E900D4E148 /* JHTableDataRowModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JHTableDataRowModel.m; sourceTree = ""; }; + F133F98B1FDA476D0056E5A5 /* UIDebuggingInformationOverlay+Enable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDebuggingInformationOverlay+Enable.m"; sourceTree = ""; }; F1743D601FCFBB0200B2738A /* JHRowChart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHRowChart.h; sourceTree = ""; }; F1743D611FCFBB0200B2738A /* JHRowChart.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JHRowChart.m; sourceTree = ""; }; F1743D631FCFBB7300B2738A /* JHRowItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JHRowItem.h; sourceTree = ""; }; @@ -287,6 +289,7 @@ AAF615181CBF9E7F00E066C3 /* GIFResource */ = { isa = PBXGroup; children = ( + F133F98B1FDA476D0056E5A5 /* UIDebuggingInformationOverlay+Enable.m */, 7D5EE57A1EE67E5500246792 /* 折线图demo-1.png */, 7D5EE5781EE67E4B00246792 /* 表格图demo-1.png */, E92CB0401E0BDBFF00861E35 /* 散点图demo1.png */, @@ -464,6 +467,7 @@ E9135FE61D2B810B00ED9F6D /* JHRingChart.m in Sources */, AAA60A8F1CD8A81A0094D6E5 /* JHPieChart.m in Sources */, F1B4D44D1FCFF3020035E16D /* JHRowChart.m in Sources */, + F133F98C1FDA476E0056E5A5 /* UIDebuggingInformationOverlay+Enable.m in Sources */, E92CB03F1E0BA14900861E35 /* JHScatterChart.m in Sources */, AA57D8A91CD9C492003EA0A7 /* JHShowInfoView.m in Sources */, AAA60A911CD8A81A0094D6E5 /* JHPieItemsView.m in Sources */, diff --git a/JHChartDemo/.DS_Store b/JHChartDemo/.DS_Store index 36f5404683aaf61a829198bcd2fbc4d78856b371..13919dc6bd19424201ab59d5d72748562d8ed012 100644 GIT binary patch delta 126 zcmZn(XbIS$Cp4K&NM^E^P##l%`s4{hQhd4jE-ophCCLm7*ZdFUPVNKB{uAP6hOsq- u`4}BGn+qo}Gc!wmn>!>=gQ+QQ@&q9%zTA8lmz2_yWCn(7u0WYSA(_elgt(buYz<*P wMuW}f!U@dGOuME}o+T#B?0Rbd +#import + + +/* + In iOS 11, Apple added additional checks to disable this overlay unless the + device is an internal device. To get around this, we swizzle out the + -[UIDebuggingInformationOverlay init] method (which returns nil now if + the device is non-internal) and +[UIDebuggingInformationOverlay prepareDebuggingOverlay] + method. + + Usage: + 1.Copy this file to your project. + 2.Add the following code to [AppDelegate application:didFinishLaunchingWithOptions:] + + #if DEBUG + id overlayClass = NSClassFromString(@"UIDebuggingInformationOverlay"); + [overlayClass performSelector:NSSelectorFromString(@"prepareDebuggingOverlay")]; + #endif + + */ + + +#if defined(DEBUG) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincomplete-implementation" +#pragma clang diagnostic ignored "-Wundeclared-selector" +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + +@interface UIWindow (PrivateMethods) +- (void)_setWindowControlsStatusBarOrientation:(BOOL)orientation; +@end + +@interface FakeWindowClass : UIWindow +@end + +@implementation FakeWindowClass + +- (instancetype)initSwizzled { + self = [super init]; + if (self) { + [self _setWindowControlsStatusBarOrientation:NO]; + } + return self; +} + +@end + +@implementation NSObject (UIDebuggingInformationOverlayEnable) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class cls = NSClassFromString(@"UIDebuggingInformationOverlay"); + [FakeWindowClass swizzleSelector:@selector(init) newSelector:@selector(initSwizzled) forClass:cls isClassMethod:NO]; + [self swizzleSelector:@selector(prepareDebuggingOverlay) newSelector:@selector(prepareDebuggingOverlaySwizzled) forClass:cls isClassMethod:YES]; + }); +} + ++ (void)swizzleSelector:(SEL)originalSelector newSelector:(SEL)swizzledSelector forClass:(Class)class isClassMethod:(BOOL)isClassMethod { + Method originalMethod = NULL; + Method swizzledMethod = NULL; + + if (isClassMethod) { + originalMethod = class_getClassMethod(class, originalSelector); + swizzledMethod = class_getClassMethod([self class], swizzledSelector); + } else { + originalMethod = class_getInstanceMethod(class, originalSelector); + swizzledMethod = class_getInstanceMethod([self class], swizzledSelector); + } + method_exchangeImplementations(originalMethod, swizzledMethod); +} + ++ (void)prepareDebuggingOverlaySwizzled { + id overlayClass = NSClassFromString(@"UIDebuggingInformationOverlayInvokeGestureHandler"); + id handler = [overlayClass performSelector:NSSelectorFromString(@"mainHandler")]; + + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:handler action:@selector(_handleActivationGesture:)]; + tapGesture.numberOfTouchesRequired = 2; + tapGesture.numberOfTapsRequired = 1; + tapGesture.delegate = handler; + + UIView *statusBarWindow = [[UIApplication sharedApplication] valueForKey:@"statusBarWindow"]; + [statusBarWindow addGestureRecognizer:tapGesture]; +} + +@end +#pragma clang diagnostic pop + +#endif diff --git a/JHChartDemo/JHChart/JHDualBarChart.m b/JHChartDemo/JHChart/JHDualBarChart.m index c90ba5b..c159f20 100644 --- a/JHChartDemo/JHChart/JHDualBarChart.m +++ b/JHChartDemo/JHChart/JHDualBarChart.m @@ -512,6 +512,6 @@ - (CATextLayer *)createTextLayer:(NSString *)text textLayer.string = text; textLayer.foregroundColor = textColor.CGColor; return textLayer; -}; +} @end diff --git a/JHChartDemo/JHChart/JHRowChart.h b/JHChartDemo/JHChart/JHRowChart.h index 0c1334b..cff5754 100644 --- a/JHChartDemo/JHChart/JHRowChart.h +++ b/JHChartDemo/JHChart/JHRowChart.h @@ -21,32 +21,29 @@ /** * Each histogram of the background color, if you do not set the default value for green. Setup must ensure that the number and type of the data source array are the same, otherwise the default is not set. */ -@property (nonatomic, strong) NSArray * rowBGcolorsArr; +@property (nonatomic, strong) NSArray *rowBGcolorsArr; -/// JHColumnDelegate的代理,用以监听柱状图某一项的点击事件 @property (nonatomic , assign)id delegate; /** * Data source array */ -@property (nonatomic, strong) NSArray * valueArr; +@property (nonatomic, strong) NSArray *valueArr; /** * X axis classification of each icon */ -@property (nonatomic, strong) NSArray * xShowInfoText; - +@property (nonatomic, strong) NSArray *xShowInfoText; /** * The background color of the content view */ -@property (nonatomic, strong) UIColor * bgVewBackgoundColor; - +@property (nonatomic, strong) UIColor *bgVewBackgoundColor; /** * Row spacing, non continuous, default is 5 */ -@property (nonatomic, assign) CGFloat typeSpace; +@property (nonatomic, assign) CGFloat rowSpacing; /** * The height of the Row, the default is 40 @@ -61,28 +58,23 @@ /** * Y, X axis line color */ -@property (nonatomic, strong) UIColor * colorForXYLine; +@property (nonatomic, strong) UIColor *colorForXYLine; /** * X, Y axis text description color */ -@property (nonatomic, strong) UIColor * drawTextColorForX_Y; +@property (nonatomic, strong) UIColor *drawTextColorForX_Y; /** * Dotted line guide color */ -@property (nonatomic, strong) UIColor * dashColor; +@property (nonatomic, strong) UIColor *dashColor; /** * The starting point, can be understood as the origin of the left and top margins */ @property (nonatomic, assign) CGPoint originSize; -/** - * Starting from the origin of the horizontal distance histogram - */ -@property (nonatomic, assign) CGFloat drawFromOriginX; - /** * Whether this chart show Y line or not .Default is Yes */ @@ -93,23 +85,21 @@ */ @property (nonatomic,assign) BOOL isShowLineChart; - /** * If isShowLineChart proprety is YES,we need this value array to draw chart */ -@property (nonatomic,strong)NSArray * lineValueArray; - +@property (nonatomic,strong)NSArray *lineValueArray; /** * If isShowLineChart proprety is Yes,we will draw path of this linechart with this color * Default is blue */ -@property (nonatomic,strong)UIColor * lineChartPathColor; +@property (nonatomic,strong)UIColor *lineChartPathColor; /** * if isShowLineChart proprety is Yes,we will draw this linechart valuepoint with this color * Default is yellow */ -@property (nonatomic,strong)UIColor * lineChartValuePointColor; +@property (nonatomic,strong)UIColor *lineChartValuePointColor; @end diff --git a/JHChartDemo/JHChart/JHRowChart.m b/JHChartDemo/JHChart/JHRowChart.m index 5342c07..615e71b 100644 --- a/JHChartDemo/JHChart/JHRowChart.m +++ b/JHChartDemo/JHChart/JHRowChart.m @@ -147,8 +147,8 @@ -(void)showAnimation{ [self clear]; _rowHeight = (_rowHeight<=0?30:_rowHeight); - _typeSpace = (_typeSpace<=0?15:_typeSpace); - _maxHeight = _originSize.y + _valueArr.count * _rowHeight + (_valueArr.count +1) * _typeSpace + 10; + _rowSpacing = (_rowSpacing<=0?15:_rowSpacing); + _maxHeight = _originSize.y + _valueArr.count * _rowHeight + (_valueArr.count +1) * _rowSpacing + 10; self.BGScrollView.contentSize = CGSizeMake(_maxWidth, _maxHeight); self.BGScrollView.backgroundColor = _bgVewBackgoundColor; @@ -245,7 +245,7 @@ -(void)showAnimation{ options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:self.xDescTextFontSize]} context:nil]; - textLayer.position = P_M(_originSize.x - textLayer.frame.size.width/2.0 -5, _originSize.y + (i +1) * (_rowHeight + _typeSpace) - _typeSpace - 0.5 * _rowHeight); + textLayer.position = P_M(_originSize.x - textLayer.frame.size.width/2.0 -5, _originSize.y + (i + 1) * (_rowHeight + _rowSpacing) - 0.5 * _rowHeight); textLayer.string = _xShowInfoText[i]; textLayer.contentsScale = [UIScreen mainScreen].scale; UIFont *font = [UIFont systemFontOfSize:self.xDescTextFontSize]; @@ -276,14 +276,14 @@ -(void)showAnimation{ colors = _rowBGcolorsArr[j]; } - JHRowItem *itemsView = [[JHRowItem alloc] initWithFrame:CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, width * _perWidth, _rowHeight) + JHRowItem *itemsView = [[JHRowItem alloc] initWithFrame:CGRectMake(_originSize.x+1, _originSize.y + (_rowSpacing + _rowHeight) *j, width * _perWidth, _rowHeight) perWidth:_perWidth valueArray:arr colors:colors]; itemsView.clipsToBounds = YES; itemsView.delegate = self; [self.showViewArr addObject:itemsView]; - itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, 0, _rowHeight); + itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + _rowSpacing + (_rowSpacing + _rowHeight) *j, 0, _rowHeight); if (_isShowLineChart) { NSString *value = [NSString stringWithFormat:@"%@",_lineValueArray[j]]; @@ -293,7 +293,7 @@ -(void)showAnimation{ [self.BGScrollView addSubview:itemsView]; [UIView animateWithDuration:1 animations:^{ - itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + (_typeSpace + _rowHeight) *j, width * _perWidth, _rowHeight); + itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + _rowSpacing + (_rowSpacing + _rowHeight) * j, width * _perWidth, _rowHeight); } completion:^(BOOL finished) { /* 动画结束后添加提示文字 */ if (finished) { diff --git a/JHChartDemo/JHChart/JHRowItem.h b/JHChartDemo/JHChart/JHRowItem.h index 66d1aa9..020f81f 100644 --- a/JHChartDemo/JHChart/JHRowItem.h +++ b/JHChartDemo/JHChart/JHRowItem.h @@ -22,9 +22,9 @@ @property (nonatomic , strong)JHIndexPath * indexPath; @property (nonatomic , assign)id delegate; --(instancetype)initWithFrame:(CGRect)frame - perWidth:(CGFloat)perWidth - valueArray:(id)values - colors:(id)colors; +- (instancetype)initWithFrame:(CGRect)frame + perWidth:(CGFloat)perWidth + valueArray:(id)values + colors:(id)colors; @end diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index f01a580..351e9ef 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -284,19 +284,19 @@ - (void)showColumnView{ JHColumnChart *column = [[JHColumnChart alloc] initWithFrame:CGRectMake(0, 64, k_MainBoundsWidth, 320)]; /* Create an array of data sources, each array is a module data. For example, the first array can represent the average score of a class of different subjects, the next array represents the average score of different subjects in another class */ column.valueArr = @[ - @[@[@15,@10],@[@8,@7]],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | | - @[@[@15,@20]],//第二组元素 - @[@[@10,@5]],//第三组元素 - @[@[@21,@12]], - @[@19], - @[@12], - @[@15], - @[@9], - @[@8], - @[@6], - @[@9], - @[@18], - @[@11], + @[@[@15,@10], @[@5]],//第一组元素 如果有多个元素,往该组添加,每一组只有一个元素,表示是单列柱状图| | | | | + @[@[@15,@20], @[@5]],//第二组元素 + @[@[@10,@5], @[@5]],//第三组元素 + @[@[@21,@12], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], + @[@[@19], @[@5]], ]; /* This point represents the distance from the lower left corner of the origin. */ column.originSize = CGPointMake(30, 20); @@ -543,10 +543,9 @@ - (void)showRowChart { /* This point represents the distance from the lower left corner of the origin. */ column.originSize = CGPointMake(30, 20); /* The first column of the distance from the starting point */ - column.drawFromOriginX = 20; column.backgroundColor = [UIColor yellowColor]; - column.typeSpace = 10; - column.isShowYLine = NO; + column.rowSpacing = 10; + column.isShowYLine = YES; column.contentInsets = UIEdgeInsetsMake(5, 0, 0, 0); /* Column width */ column.rowHeight = 30; From 4150b7fc1587dc35ea6b2919507276dc38367849 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Mon, 11 Dec 2017 14:54:20 +0800 Subject: [PATCH 10/11] Make x axis sticky --- JHChartDemo/JHChart/JHRowChart.h | 5 -- JHChartDemo/JHChart/JHRowChart.m | 108 +++++++++++++++---------------- JHChartDemo/JHShowController.m | 4 +- 3 files changed, 53 insertions(+), 64 deletions(-) diff --git a/JHChartDemo/JHChart/JHRowChart.h b/JHChartDemo/JHChart/JHRowChart.h index cff5754..feec321 100644 --- a/JHChartDemo/JHChart/JHRowChart.h +++ b/JHChartDemo/JHChart/JHRowChart.h @@ -70,11 +70,6 @@ */ @property (nonatomic, strong) UIColor *dashColor; -/** - * The starting point, can be understood as the origin of the left and top margins - */ -@property (nonatomic, assign) CGPoint originSize; - /** * Whether this chart show Y line or not .Default is Yes */ diff --git a/JHChartDemo/JHChart/JHRowChart.m b/JHChartDemo/JHChart/JHRowChart.m index 615e71b..b67d9f6 100644 --- a/JHChartDemo/JHChart/JHRowChart.m +++ b/JHChartDemo/JHChart/JHRowChart.m @@ -13,7 +13,7 @@ @interface JHRowChart () //背景图 -@property (nonatomic,strong)UIScrollView *BGScrollView; +@property (nonatomic,strong)UIScrollView *scrollView; //峰值 @property (nonatomic,assign) CGFloat maxHeight; @@ -33,6 +33,10 @@ @interface JHRowChart () @property (nonatomic,assign) CGFloat perWidth; @property (nonatomic , strong) NSMutableArray * drawLineValue; + +// 用来遮挡住scrollview 非显示区域 +@property (nonatomic , strong) CAShapeLayer *contentMaskLayer; + @end @implementation JHRowChart @@ -59,23 +63,23 @@ -(NSMutableArray *)layerArr{ return _layerArr; } --(UIScrollView *)BGScrollView{ - if (!_BGScrollView) { - _BGScrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; - _BGScrollView.showsHorizontalScrollIndicator = NO; - _BGScrollView.backgroundColor = _bgVewBackgoundColor; - [self addSubview:_BGScrollView]; +-(UIScrollView *)scrollView{ + if (!_scrollView) { + _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; + _scrollView.showsHorizontalScrollIndicator = NO; + _scrollView.backgroundColor = [UIColor clearColor]; + _scrollView.clipsToBounds = YES; + [self addSubview:_scrollView]; } - return _BGScrollView; + return _scrollView; } -(void)setBgVewBackgoundColor:(UIColor *)bgVewBackgoundColor{ _bgVewBackgoundColor = bgVewBackgoundColor; - self.BGScrollView.backgroundColor = _bgVewBackgoundColor; + self.backgroundColor = _bgVewBackgoundColor; } - -(NSMutableArray *)yLineDataArr{ if (!_yLineDataArr) { _yLineDataArr = [NSMutableArray array]; @@ -90,6 +94,7 @@ -(instancetype)initWithFrame:(CGRect)frame{ _isShowYLine = YES; _lineChartPathColor = [UIColor blueColor]; _lineChartValuePointColor = [UIColor yellowColor]; + self.clipsToBounds = YES; } return self; } @@ -115,7 +120,7 @@ -(void)setLineValueArray:(NSArray *)lineValueArray{ max += 4; _maxWidth = MAX(_maxWidth, max); - _perWidth = (CGRectGetWidth(self.frame) - 30 - _originSize.x - self.contentInsets.right)/_maxWidth; + _perWidth = (CGRectGetWidth(self.frame) - 30 - self.chartOrigin.x - self.contentInsets.right)/_maxWidth; } -(void)setValueArr:(NSArray *)valueArr{ @@ -139,58 +144,61 @@ -(void)setValueArr:(NSArray *)valueArr{ max += 4; _maxWidth = MAX(_maxWidth, max); - _perWidth = (CGRectGetWidth(self.frame) - 30 - _originSize.x)/_maxWidth; + _perWidth = (CGRectGetWidth(self.frame) - 30 - self.chartOrigin.x)/_maxWidth; } -(void)showAnimation{ [self clear]; - + _rowHeight = (_rowHeight<=0?30:_rowHeight); _rowSpacing = (_rowSpacing<=0?15:_rowSpacing); - _maxHeight = _originSize.y + _valueArr.count * _rowHeight + (_valueArr.count +1) * _rowSpacing + 10; - self.BGScrollView.contentSize = CGSizeMake(_maxWidth, _maxHeight); - self.BGScrollView.backgroundColor = _bgVewBackgoundColor; + _maxHeight = self.chartOrigin.y + _valueArr.count * _rowHeight + (_valueArr.count +1) * _rowSpacing + 10; + self.scrollView.frame = CGRectMake(0, self.chartOrigin.y, self.bounds.size.width, self.bounds.size.height - self.chartOrigin.y); + self.scrollView.contentSize = CGSizeMake(_maxWidth, _maxHeight); + self.scrollView.backgroundColor = _bgVewBackgoundColor; /* 绘制X、Y轴 可以在此改动X、Y轴字体大小 */ if (_needXandYLine) { UIBezierPath *bezier = [UIBezierPath bezierPath]; if (self.isShowYLine) { - [bezier moveToPoint:_originSize]; - [bezier addLineToPoint:P_M(G_W(self.frame), _originSize.y)]; + [bezier moveToPoint:self.chartOrigin]; + [bezier addLineToPoint:P_M(G_W(self.frame), self.chartOrigin.y)]; } - [bezier moveToPoint:_originSize]; - [bezier addLineToPoint:P_M(self.originSize.x, _maxHeight)]; + [bezier moveToPoint:self.chartOrigin]; + [bezier addLineToPoint:P_M(self.chartOrigin.x, _maxHeight)]; CAShapeLayer *layer = [CAShapeLayer layer]; layer.path = bezier.CGPath; layer.strokeColor = (_colorForXYLine==nil?([UIColor blackColor].CGColor):_colorForXYLine.CGColor); - CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; - basic.duration = self.isShowYLine?1.5:0.75; - basic.fromValue = @(0); - basic.toValue = @(1); - basic.autoreverses = NO; - basic.fillMode = kCAFillModeForwards; + /* + CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + basic.duration = self.isShowYLine?1.5:0.75; + basic.fromValue = @(0); + basic.toValue = @(1); + basic.autoreverses = NO; + basic.fillMode = kCAFillModeForwards; + [layer addAnimation:basic forKey:nil]; + */ - [layer addAnimation:basic forKey:nil]; [self.layerArr addObject:layer]; - [self.BGScrollView.layer addSublayer:layer]; + [self.layer addSublayer:layer]; /* 设置虚线辅助线 */ UIBezierPath *second = [UIBezierPath bezierPath]; for (NSInteger i = 0; i<5; i++) { NSInteger pace = (_maxWidth) / 5; CGFloat width = _perWidth * (i+1)*pace; - [second moveToPoint:P_M(_originSize.x + width, _originSize.y)]; - [second addLineToPoint:P_M(_originSize.x + width, _maxHeight)]; + [second moveToPoint:P_M(self.chartOrigin.x + width, self.chartOrigin.y)]; + [second addLineToPoint:P_M(self.chartOrigin.x + width, _maxHeight)]; CATextLayer *textLayer = [CATextLayer layer]; textLayer.contentsScale = [UIScreen mainScreen].scale; NSString *text =[NSString stringWithFormat:@"%zd",(i + 1) * pace]; CGSize size = [self sizeOfStringWithMaxSize:XORYLINEMAXSIZE textFont:self.yDescTextFontSize aimString:text]; - textLayer.frame = CGRectMake(_originSize.x + width - size.width/2.0, 0, _originSize.y - size.height/2.0, size.height); + textLayer.frame = CGRectMake(self.chartOrigin.x + width - size.width/2.0, 0, self.chartOrigin.y - size.height/2.0, size.height); UIFont *font = [UIFont systemFontOfSize:self.yDescTextFontSize]; CFStringRef fontName = (__bridge CFStringRef)font.fontName; @@ -202,7 +210,7 @@ -(void)showAnimation{ textLayer.string = text; textLayer.foregroundColor = (_drawTextColorForX_Y==nil?[UIColor blackColor].CGColor:_drawTextColorForX_Y.CGColor); - [_BGScrollView.layer addSublayer:textLayer]; + [self.layer addSublayer:textLayer]; [self.layerArr addObject:textLayer]; } @@ -217,25 +225,15 @@ -(void)showAnimation{ [shapeLayer setLineDashPattern:@[@(3),@(3)]]; CABasicAnimation *basic2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; - - basic2.duration = 1.5; - basic2.fromValue = @(0); - basic2.toValue = @(1); - basic2.autoreverses = NO; - - - basic2.fillMode = kCAFillModeForwards; - [shapeLayer addAnimation:basic2 forKey:nil]; - [self.BGScrollView.layer addSublayer:shapeLayer]; + [self.layer addSublayer:shapeLayer]; [self.layerArr addObject:shapeLayer]; - } if (_xShowInfoText.count == _valueArr.count&&_xShowInfoText.count>0) { @@ -245,7 +243,7 @@ -(void)showAnimation{ options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:self.xDescTextFontSize]} context:nil]; - textLayer.position = P_M(_originSize.x - textLayer.frame.size.width/2.0 -5, _originSize.y + (i + 1) * (_rowHeight + _rowSpacing) - 0.5 * _rowHeight); + textLayer.position = P_M(self.chartOrigin.x - textLayer.frame.size.width/2.0 -5, self.chartOrigin.y + (i + 1) * (_rowHeight + _rowSpacing) - 0.5 * _rowHeight); textLayer.string = _xShowInfoText[i]; textLayer.contentsScale = [UIScreen mainScreen].scale; UIFont *font = [UIFont systemFontOfSize:self.xDescTextFontSize]; @@ -254,7 +252,7 @@ -(void)showAnimation{ textLayer.foregroundColor = _drawTextColorForX_Y.CGColor; textLayer.alignmentMode = kCAAlignmentCenter; - [_BGScrollView.layer addSublayer:textLayer]; + [_scrollView.layer addSublayer:textLayer]; [self.layerArr addObject:textLayer]; } @@ -276,24 +274,24 @@ -(void)showAnimation{ colors = _rowBGcolorsArr[j]; } - JHRowItem *itemsView = [[JHRowItem alloc] initWithFrame:CGRectMake(_originSize.x+1, _originSize.y + (_rowSpacing + _rowHeight) *j, width * _perWidth, _rowHeight) + JHRowItem *itemsView = [[JHRowItem alloc] initWithFrame:CGRectMake(self.chartOrigin.x+1, (_rowSpacing + _rowHeight) *j, width * _perWidth, _rowHeight) perWidth:_perWidth valueArray:arr colors:colors]; itemsView.clipsToBounds = YES; itemsView.delegate = self; [self.showViewArr addObject:itemsView]; - itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + _rowSpacing + (_rowSpacing + _rowHeight) *j, 0, _rowHeight); + itemsView.frame = CGRectMake(self.chartOrigin.x+1, _rowSpacing + (_rowSpacing + _rowHeight) *j, 0, _rowHeight); if (_isShowLineChart) { NSString *value = [NSString stringWithFormat:@"%@",_lineValueArray[j]]; - NSValue *lineValue = [NSValue valueWithCGPoint:P_M(_originSize.x+_perWidth *value.floatValue, itemsView.center.y)]; + NSValue *lineValue = [NSValue valueWithCGPoint:P_M(self.chartOrigin.x+_perWidth *value.floatValue, itemsView.center.y)]; [self.drawLineValue addObject:lineValue]; } - [self.BGScrollView addSubview:itemsView]; + [self.scrollView addSubview:itemsView]; [UIView animateWithDuration:1 animations:^{ - itemsView.frame = CGRectMake(_originSize.x+1, _originSize.y + _rowSpacing + (_rowSpacing + _rowHeight) * j, width * _perWidth, _rowHeight); + itemsView.frame = CGRectMake(self.chartOrigin.x+1, _rowSpacing + (_rowSpacing + _rowHeight) * j, width * _perWidth, _rowHeight); } completion:^(BOOL finished) { /* 动画结束后添加提示文字 */ if (finished) { @@ -314,7 +312,7 @@ -(void)showAnimation{ textLayer.contentsScale = [UIScreen mainScreen].scale; textLayer.foregroundColor = itemsView.backgroundColor.CGColor; - [_BGScrollView.layer addSublayer:textLayer]; + [_scrollView.layer addSublayer:textLayer]; //添加折线图 if (j==_valueArr.count - 1 && _isShowLineChart) { @@ -347,7 +345,7 @@ -(void)showAnimation{ basic.duration = 1; basic.delegate = self; [shaper addAnimation:basic forKey:@"stokentoend"]; - [self.BGScrollView.layer addSublayer:shaper]; + [self.scrollView.layer addSublayer:shaper]; } } }]; @@ -382,16 +380,12 @@ -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ for (int32_t m=0;m<_lineValueArray.count;m++) { NSLog(@"%@",_drawLineValue[m]); - - CAShapeLayer *roundLayer = [CAShapeLayer layer]; UIBezierPath *roundPath = [UIBezierPath bezierPathWithArcCenter:[_drawLineValue[m] CGPointValue] radius:4.5 startAngle:M_PI_2 endAngle:M_PI_2 + M_PI * 2 clockwise:YES]; roundLayer.path = roundPath.CGPath; roundLayer.fillColor = _lineChartValuePointColor.CGColor; [self.layerArr addObject:roundLayer]; - [self.BGScrollView.layer addSublayer:roundLayer]; - - + [self.scrollView.layer addSublayer:roundLayer]; } } } diff --git a/JHChartDemo/JHShowController.m b/JHChartDemo/JHShowController.m index 351e9ef..006e60a 100644 --- a/JHChartDemo/JHShowController.m +++ b/JHChartDemo/JHShowController.m @@ -541,9 +541,9 @@ - (void)showRowChart { @[[UIColor redColor],[UIColor blueColor]], @[[UIColor redColor],[UIColor greenColor]]];//如果为复合型柱状图 即每个柱状图分段 需要传入如上颜色数组 达到同时指定复合型柱状图分段颜色的效果 /* This point represents the distance from the lower left corner of the origin. */ - column.originSize = CGPointMake(30, 20); + column.chartOrigin = CGPointMake(30, 20); /* The first column of the distance from the starting point */ - column.backgroundColor = [UIColor yellowColor]; + column.backgroundColor = [UIColor grayColor]; column.rowSpacing = 10; column.isShowYLine = YES; column.contentInsets = UIEdgeInsetsMake(5, 0, 0, 0); From ad4fd1e9da8376f989720ad684d0e7f8de0fe208 Mon Sep 17 00:00:00 2001 From: Mayqiyue Date: Mon, 11 Dec 2017 15:02:50 +0800 Subject: [PATCH 11/11] Remove useless codes. --- JHChartDemo/JHChart/JHRowChart.m | 3 --- 1 file changed, 3 deletions(-) diff --git a/JHChartDemo/JHChart/JHRowChart.m b/JHChartDemo/JHChart/JHRowChart.m index b67d9f6..1026719 100644 --- a/JHChartDemo/JHChart/JHRowChart.m +++ b/JHChartDemo/JHChart/JHRowChart.m @@ -34,9 +34,6 @@ @interface JHRowChart () @property (nonatomic , strong) NSMutableArray * drawLineValue; -// 用来遮挡住scrollview 非显示区域 -@property (nonatomic , strong) CAShapeLayer *contentMaskLayer; - @end @implementation JHRowChart