diff --git a/dr-charts/Classes/BarChart/BarChart.m b/dr-charts/Classes/BarChart/BarChart.m index 45d3c0a..1bfafc5 100644 --- a/dr-charts/Classes/BarChart/BarChart.m +++ b/dr-charts/Classes/BarChart/BarChart.m @@ -8,7 +8,7 @@ #import "BarChart.h" #import "DRScrollView.h" -#import "Constants.h" +#import "DrConstants.h" @interface BarChartDataRenderer : NSObject diff --git a/dr-charts/Classes/CircularChart/CircularChart.m b/dr-charts/Classes/CircularChart/CircularChart.m index 6a91e91..e127476 100644 --- a/dr-charts/Classes/CircularChart/CircularChart.m +++ b/dr-charts/Classes/CircularChart/CircularChart.m @@ -7,7 +7,7 @@ // #import "CircularChart.h" -#import "Constants.h" +#import "DrConstants.h" @interface CircularChartDataRenderer : NSObject @@ -306,4 +306,4 @@ - (instancetype)init{ } -@end \ No newline at end of file +@end diff --git a/dr-charts/Classes/Constants.h b/dr-charts/Classes/DrConstants.h similarity index 100% rename from dr-charts/Classes/Constants.h rename to dr-charts/Classes/DrConstants.h diff --git a/dr-charts/Classes/DrGraphs.h b/dr-charts/Classes/DrGraphs.h index 642e9eb..bcfae81 100644 --- a/dr-charts/Classes/DrGraphs.h +++ b/dr-charts/Classes/DrGraphs.h @@ -15,6 +15,6 @@ #import "BarChart.h" #import "CircularChart.h" #import "LegendView.h" -#import "Constants.h" +#import "DrConstants.h" #endif /* DrGraphs_h */ diff --git a/dr-charts/Classes/HorizontalStackChart/HorizontalStackBarChart.m b/dr-charts/Classes/HorizontalStackChart/HorizontalStackBarChart.m index d44fa89..5b94cdc 100644 --- a/dr-charts/Classes/HorizontalStackChart/HorizontalStackBarChart.m +++ b/dr-charts/Classes/HorizontalStackChart/HorizontalStackBarChart.m @@ -7,7 +7,7 @@ // #import "HorizontalStackBarChart.h" -#import "Constants.h" +#import "DrConstants.h" @interface HorizontalStackBarData : NSObject @@ -347,4 +347,4 @@ - (instancetype)init{ return self; } -@end \ No newline at end of file +@end diff --git a/dr-charts/Classes/Legend/LegendView.m b/dr-charts/Classes/Legend/LegendView.m index f47a89c..ea4a2a7 100644 --- a/dr-charts/Classes/Legend/LegendView.m +++ b/dr-charts/Classes/Legend/LegendView.m @@ -7,7 +7,7 @@ // #import "LegendView.h" -#import "Constants.h" +#import "DrConstants.h" @implementation LegendView diff --git a/dr-charts/Classes/LineChart/LineGraphMarker.m b/dr-charts/Classes/LineChart/LineGraphMarker.m index acd7465..f77e827 100644 --- a/dr-charts/Classes/LineChart/LineGraphMarker.m +++ b/dr-charts/Classes/LineChart/LineGraphMarker.m @@ -7,7 +7,7 @@ // #import "LineGraphMarker.h" -#import "Constants.h" +#import "DrConstants.h" @interface LineGraphMarker() @@ -60,4 +60,4 @@ - (void)drawAtPoint:(CGPoint)point{ [self setFrame:CGRectMake(x, point.y - (HEIGHT(self.markerLabel) + 10), WIDTH(self.markerLabel) + 10, HEIGHT(self.markerLabel) + 10)]; } -@end \ No newline at end of file +@end diff --git a/dr-charts/Classes/LineChart/MultiLineGraphView.h b/dr-charts/Classes/LineChart/MultiLineGraphView.h index 9f29b4c..848f4ef 100644 --- a/dr-charts/Classes/LineChart/MultiLineGraphView.h +++ b/dr-charts/Classes/LineChart/MultiLineGraphView.h @@ -65,10 +65,19 @@ typedef enum { //Set xData for Line on Line Graph for corresponding yData //If LineType is LineParallelYAxis, Set xData for the Line on Line Graph +- (NSMutableArray *)dataForXAxisForAllLines; +//Set xData for All Line on Line Graph for corresponding yData + @optional - (UIView *)customViewForLineChartTouchWithXValue:(id)xValue andYValue:(id)yValue; //Set Custom View for touch on each item in a Line Chart +- (NSString *)customYAxisFormat:(float)yAxisValue; +//Set Custom Format for yAxix Value + +- (NSString *)customXAxisFormat:(NSString *)xAxisValue; +//Set Custom Format for xAxix Value + @end @interface MultiLineGraphView : UIView @@ -105,6 +114,19 @@ typedef enum { //Set LEGEND TYPE Horizontal or Vertical @property (nonatomic) LegendType legendViewType; //Default is LegendTypeVertical i.e. VERTICAL +//Set step number for xAxis display value +@property (nonatomic) int xAixsStepNumber; +//Set step number for yAxis display value +@property (nonatomic) int yAixsStepNumber; +//Set animation duration time +@property (nonatomic) float animationDuration; +//Set default min value for yAxis +@property (nonatomic) float yAixsDefaultMin; +//Set default max value for yAxis +@property (nonatomic) float yAixsDefaultMax; +//Set axis Line color (not same with gridLineColor) +@property (nonatomic, strong) UIColor *axisLineColor; + //To draw the graph - (void)drawGraph; diff --git a/dr-charts/Classes/LineChart/MultiLineGraphView.m b/dr-charts/Classes/LineChart/MultiLineGraphView.m index e38b972..528c4f3 100644 --- a/dr-charts/Classes/LineChart/MultiLineGraphView.m +++ b/dr-charts/Classes/LineChart/MultiLineGraphView.m @@ -9,7 +9,7 @@ #import "MultiLineGraphView.h" #import "LineGraphMarker.h" #import "DRScrollView.h" -#import "Constants.h" +#import "DrConstants.h" @interface LineChartDataRenderer : NSObject @@ -30,6 +30,9 @@ @interface LineChartDataRenderer : NSObject @interface MultiLineGraphView()<UIScrollViewDelegate>{ float stepY; float stepX; + float yAxisMinValue; + float yAxisMaxValue; + NSString *selectedXData; NSString *selectedYData; @@ -54,6 +57,8 @@ @interface MultiLineGraphView()<UIScrollViewDelegate>{ @property (nonatomic, strong) NSMutableArray *legendArray; @property (nonatomic, strong) NSMutableArray *lineDataArray; +@property (nonatomic, copy) NSString *axisAlignmentMode; + @end @implementation MultiLineGraphView @@ -66,6 +71,7 @@ - (instancetype)initWithFrame:(CGRect)frame{ self.gridLineColor = [UIColor lightGrayColor]; self.gridLineWidth = 0.3; + self.axisLineColor = self.gridLineColor; self.textFontSize = 11; self.textColor = [UIColor blackColor]; @@ -82,6 +88,13 @@ - (instancetype)initWithFrame:(CGRect)frame{ self.showCustomMarkerView = FALSE; + self.xAixsStepNumber = 5; + self.yAixsStepNumber = 5; + self.animationDuration = ANIMATION_DURATION; + self.yAixsDefaultMin = -5; + self.yAixsDefaultMax = 5; + self.axisAlignmentMode = kCAAlignmentCenter; + scaleHeight = 0; lastScale = 1; } @@ -111,12 +124,11 @@ - (void)getDataFromDataSource{ [data setLegendText:lineData.graphName]; [data setLegendColor:lineData.lineColor]; [self.legendArray addObject:data]; - - if (self.xAxisArray.count < lineData.xAxisArray.count) { - [self.xAxisArray removeAllObjects]; - [self.xAxisArray addObjectsFromArray:lineData.xAxisArray]; - } } + + [self.xAxisArray removeAllObjects]; + [self.xAxisArray addObjectsFromArray:[self.dataSource dataForXAxisForAllLines]]; + } #pragma mark Draw Graph @@ -172,8 +184,8 @@ - (void)drawGraph{ #pragma Draw Shape Layer - (void)createYAxisLine{ - float minY = 0.0; - float maxY = 0.0; + float minY = _yAixsDefaultMin; + float maxY = _yAixsDefaultMax; for (LineChartDataRenderer *lineData in self.lineDataArray) { @@ -194,15 +206,18 @@ - (void)createYAxisLine{ } } - int gridYCount = 5; + int gridYCount = _yAixsStepNumber; if (scaleHeight > height) { gridYCount = ceil(gridYCount * lastScale); } float step = (maxY - minY) / gridYCount; + yAxisMinValue = minY; + yAxisMaxValue = maxY; stepY = (HEIGHT(self.graphView) - (OFFSET_Y * 2)) / (maxY - minY); + self.axisAlignmentMode = kCAAlignmentRight; for (int i = 0; i <= gridYCount; i++) { int y = (i * step) * stepY; @@ -212,6 +227,9 @@ - (void)createYAxisLine{ CGPoint endPoint = CGPointMake(WIDTH(self.graphView) - OFFSET_X, HEIGHT(self.graphView) - (y + OFFSET_Y)); NSString *numberString = [NSString stringWithFormat:@"%.1f",value]; + if ([self.dataSource respondsToSelector:@selector(customYAxisFormat:)]) { + numberString = [self.dataSource customYAxisFormat:value]; + } BOOL drawGrid = TRUE; if (self.drawGridY) { @@ -228,7 +246,7 @@ - (void)createYAxisLine{ NSAttributedString *attrString = [LegendView getAttributedString:numberString withFont:self.textFont]; CGSize size = [attrString boundingRectWithSize:CGSizeMake(WIDTH(self) - LEGEND_VIEW, MAXFLOAT) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin context:nil].size; - [self drawLineForGridWithStartPoint:startPoint endPoint:endPoint text:numberString textFrame:CGRectMake(OFFSET_PADDING, HEIGHT(self.graphView) - (y + OFFSET_Y + size.height/2), size.width , size.height) drawGrid:drawGrid]; + [self drawLineForGridWithStartPoint:startPoint endPoint:endPoint text:numberString textFrame:CGRectMake(startPoint.x - size.width - 1, HEIGHT(self.graphView) - (y + OFFSET_Y + size.height/2), size.width , size.height) drawGrid:drawGrid isAxisLine:i == 0]; } } @@ -236,8 +254,8 @@ - (void)createXAxisLine{ float step = 0; NSInteger maxStep = [self.xAxisArray count]; - if ([self.xAxisArray count] > 5) { - int stepCount = 5; + if ([self.xAxisArray count] > _xAixsStepNumber) { + int stepCount = _xAixsStepNumber; if (widht > WIDTH(self)) { stepCount = ceil(stepCount * lastScale); @@ -245,7 +263,7 @@ - (void)createXAxisLine{ NSInteger count = [self.xAxisArray count] - 1; - for (int i = 4; i < 8; i++) { + for (int i = _xAixsStepNumber - 1; i < (_xAixsStepNumber - 1) * 2; i++) { if (count % i == 0) { stepCount = i; break; @@ -259,6 +277,7 @@ - (void)createXAxisLine{ } stepX = (WIDTH(self.graphView) - (OFFSET_X * 2)) / (self.xAxisArray.count - 1); + self.axisAlignmentMode = kCAAlignmentCenter; for (int i = 0; i <= maxStep; i++) { int x = (i * step) * stepX; @@ -288,10 +307,15 @@ - (void)createXAxisLine{ drawGrid = FALSE; } } - NSAttributedString *attrString = [LegendView getAttributedString:[self.xAxisArray objectAtIndex:index] withFont:self.textFont]; + + NSString *xAxisValue = [self.xAxisArray objectAtIndex:index]; + if ([self.dataSource respondsToSelector:@selector(customXAxisFormat:)]) { + xAxisValue = [self.dataSource customXAxisFormat:xAxisValue]; + } + NSAttributedString *attrString = [LegendView getAttributedString:xAxisValue withFont:self.textFont]; CGSize size = [attrString boundingRectWithSize:CGSizeMake(WIDTH(self) - LEGEND_VIEW, MAXFLOAT) options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin context:nil].size; - [self drawLineForGridWithStartPoint:startPoint endPoint:endPoint text:[self.xAxisArray objectAtIndex:index] textFrame:CGRectMake(x + size.width/2, HEIGHT(self.graphView) - (size.height + INNER_PADDING), size.width, size.height) drawGrid:drawGrid]; + [self drawLineForGridWithStartPoint:startPoint endPoint:endPoint text:xAxisValue textFrame:CGRectMake(x + size.width/2, HEIGHT(self.graphView) - (size.height + INNER_PADDING), size.width, size.height) drawGrid:drawGrid isAxisLine:i == 0]; } } @@ -306,7 +330,7 @@ - (void)createGraph{ NSInteger itemIndex = [self.xAxisArray indexOfObject:[lineData.xAxisArray objectAtIndex:0]]; x = itemIndex * stepX; - y = [[lineData.yAxisArray objectAtIndex:0] floatValue] * stepY; + y = ([[lineData.yAxisArray objectAtIndex:0] floatValue] - yAxisMinValue) * stepY; CGPoint startPoint = CGPointMake(x + OFFSET_X, HEIGHT(self.graphView) - (OFFSET_Y + y)); CGPoint firstPoint = startPoint; @@ -322,7 +346,7 @@ - (void)createGraph{ for (int i = 1; i < lineData.yAxisArray.count; i++){ NSInteger xIndex = [self.xAxisArray indexOfObject:[lineData.xAxisArray objectAtIndex:i]]; x = xIndex * stepX; - y = [[lineData.yAxisArray objectAtIndex:i] floatValue] * stepY; + y = ([[lineData.yAxisArray objectAtIndex:i] floatValue] - yAxisMinValue) * stepY; endPoint = CGPointMake(x + OFFSET_X, HEIGHT(self.graphView) - ( y + OFFSET_Y)); @@ -348,7 +372,7 @@ - (void)createGraph{ [shapeLayer setContentsScale:[[UIScreen mainScreen] scale]]; CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; - [pathAnimation setDuration:ANIMATION_DURATION]; + [pathAnimation setDuration:_animationDuration]; [pathAnimation setFromValue:[NSNumber numberWithFloat:0.0f]]; [pathAnimation setToValue:[NSNumber numberWithFloat:1.0f]]; [shapeLayer addAnimation:pathAnimation forKey:@"strokeEnd"]; @@ -371,7 +395,7 @@ - (void)createGraph{ int y = 0; for (int i = 0; i < lineData.yAxisArray.count; i++){ - y = [[lineData.yAxisArray objectAtIndex:i] floatValue] * stepY; + y = ([[lineData.yAxisArray objectAtIndex:i] floatValue] - yAxisMinValue) * stepY; CGPoint startPoint = CGPointMake(OFFSET_X, HEIGHT(self.graphView) - (OFFSET_Y + y)); CGPoint endPoint = CGPointMake(WIDTH(self.graphView) - OFFSET_X, HEIGHT(self.graphView) - (OFFSET_Y + y)); @@ -389,10 +413,10 @@ - (void)createGraph{ if (lineData.fillGraph) { - y = [[lineData.yAxisArray firstObject] floatValue] * stepY; + y = ([[lineData.yAxisArray firstObject] floatValue] - yAxisMinValue) * stepY; CGPoint point1 = CGPointMake(OFFSET_X, HEIGHT(self.graphView) - (OFFSET_Y + y)); - y = [[lineData.yAxisArray lastObject] floatValue] * stepY; + y = ([[lineData.yAxisArray lastObject] floatValue] - yAxisMinValue) * stepY; CGPoint point2 = CGPointMake(WIDTH(self.graphView) - OFFSET_X, HEIGHT(self.graphView) - (OFFSET_Y + y)); UIBezierPath *fillPath = [UIBezierPath bezierPath]; @@ -614,7 +638,7 @@ - (void)findValueForTouch:(UITouch *)touch{ for (int i = 0; i < lineData.yAxisArray.count; i++){ NSInteger xIndex = [self.xAxisArray indexOfObject:[lineData.xAxisArray objectAtIndex:i]]; x = xIndex * stepX; - y = [[lineData.yAxisArray objectAtIndex:i] floatValue] * stepY; + y = ([[lineData.yAxisArray objectAtIndex:i] floatValue] - yAxisMinValue) * stepY; CGPoint point = CGPointMake(x + OFFSET_X, HEIGHT(self.graphView) - ( y + OFFSET_Y)); @@ -704,7 +728,7 @@ - (void)fillGraphBackgroundWithPath:(UIBezierPath *)path color:(UIColor *)color{ [shapeLayer setOpacity:0.1]; CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"fill"]; - [pathAnimation setDuration:ANIMATION_DURATION]; + [pathAnimation setDuration:_animationDuration]; [pathAnimation setFillMode:kCAFillModeForwards]; [pathAnimation setFromValue:(id)[[UIColor clearColor] CGColor]]; [pathAnimation setToValue:(id)[color CGColor]]; @@ -717,12 +741,12 @@ - (void)fillGraphBackgroundWithPath:(UIBezierPath *)path color:(UIColor *)color{ } #pragma mark Draw Grid Lines -- (void)drawLineForGridWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint text:(NSString *)text textFrame:(CGRect)frame drawGrid:(BOOL)draw{ +- (void)drawLineForGridWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint text:(NSString *)text textFrame:(CGRect)frame drawGrid:(BOOL)draw isAxisLine:(BOOL)isAxisLine{ if (draw) { CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init]; [shapeLayer setPath:[[self drawPathWithStartPoint:startPoint endPoint:endPoint] CGPath]]; - [shapeLayer setStrokeColor:self.gridLineColor.CGColor]; + [shapeLayer setStrokeColor:isAxisLine ? self.axisLineColor.CGColor : self.gridLineColor.CGColor]; [shapeLayer setLineWidth:self.gridLineWidth]; [self.graphView.layer addSublayer:shapeLayer]; } @@ -732,7 +756,7 @@ - (void)drawLineForGridWithStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endP [textLayer setFontSize:self.textFontSize]; [textLayer setFrame:frame]; [textLayer setString:text]; - [textLayer setAlignmentMode:kCAAlignmentCenter]; + [textLayer setAlignmentMode:self.axisAlignmentMode]; [textLayer setForegroundColor:self.textColor.CGColor]; [textLayer setShouldRasterize:YES]; [textLayer setRasterizationScale:[[UIScreen mainScreen] scale]]; diff --git a/dr-charts/Classes/PieChart/PieChart.m b/dr-charts/Classes/PieChart/PieChart.m index 10cbfe9..20fe746 100644 --- a/dr-charts/Classes/PieChart/PieChart.m +++ b/dr-charts/Classes/PieChart/PieChart.m @@ -7,7 +7,7 @@ // #import "PieChart.h" -#import "Constants.h" +#import "DrConstants.h" @interface PieChartDataRenderer : NSObject @@ -347,4 +347,4 @@ - (instancetype)init{ return self; } -@end \ No newline at end of file +@end diff --git a/drCharts.xcodeproj/project.pbxproj b/drCharts.xcodeproj/project.pbxproj index 59e4d8f..ac8a5e1 100644 --- a/drCharts.xcodeproj/project.pbxproj +++ b/drCharts.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ C50CCB531D0EA0D3002C87B7 /* BarChart.m in Sources */ = {isa = PBXBuildFile; fileRef = C50CCB3C1D0EA0D3002C87B7 /* BarChart.m */; }; C50CCB541D0EA0D3002C87B7 /* CircularChart.h in Headers */ = {isa = PBXBuildFile; fileRef = C50CCB3E1D0EA0D3002C87B7 /* CircularChart.h */; }; C50CCB551D0EA0D3002C87B7 /* CircularChart.m in Sources */ = {isa = PBXBuildFile; fileRef = C50CCB3F1D0EA0D3002C87B7 /* CircularChart.m */; }; - C50CCB561D0EA0D3002C87B7 /* Constants.h in Headers */ = {isa = PBXBuildFile; fileRef = C50CCB401D0EA0D3002C87B7 /* Constants.h */; }; + C50CCB561D0EA0D3002C87B7 /* DrConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = C50CCB401D0EA0D3002C87B7 /* DrConstants.h */; }; C50CCB571D0EA0D3002C87B7 /* DrGraphs.h in Headers */ = {isa = PBXBuildFile; fileRef = C50CCB411D0EA0D3002C87B7 /* DrGraphs.h */; }; C50CCB581D0EA0D3002C87B7 /* DRScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = C50CCB421D0EA0D3002C87B7 /* DRScrollView.h */; }; C50CCB591D0EA0D3002C87B7 /* DRScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = C50CCB431D0EA0D3002C87B7 /* DRScrollView.m */; }; @@ -51,7 +51,7 @@ C50CCB3C1D0EA0D3002C87B7 /* BarChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BarChart.m; sourceTree = "<group>"; }; C50CCB3E1D0EA0D3002C87B7 /* CircularChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircularChart.h; sourceTree = "<group>"; }; C50CCB3F1D0EA0D3002C87B7 /* CircularChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircularChart.m; sourceTree = "<group>"; }; - C50CCB401D0EA0D3002C87B7 /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; }; + C50CCB401D0EA0D3002C87B7 /* DrConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrConstants.h; sourceTree = "<group>"; }; C50CCB411D0EA0D3002C87B7 /* DrGraphs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrGraphs.h; sourceTree = "<group>"; }; C50CCB421D0EA0D3002C87B7 /* DRScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DRScrollView.h; sourceTree = "<group>"; }; C50CCB431D0EA0D3002C87B7 /* DRScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DRScrollView.m; sourceTree = "<group>"; }; @@ -130,7 +130,7 @@ children = ( C50CCB3A1D0EA0D3002C87B7 /* BarChart */, C50CCB3D1D0EA0D3002C87B7 /* CircularChart */, - C50CCB401D0EA0D3002C87B7 /* Constants.h */, + C50CCB401D0EA0D3002C87B7 /* DrConstants.h */, C50CCB411D0EA0D3002C87B7 /* DrGraphs.h */, C50CCB421D0EA0D3002C87B7 /* DRScrollView.h */, C50CCB431D0EA0D3002C87B7 /* DRScrollView.m */, @@ -214,7 +214,7 @@ C50CCB231D0EA0AB002C87B7 /* drCharts.h in Headers */, C50CCB5C1D0EA0D3002C87B7 /* LegendView.h in Headers */, C50CCB5A1D0EA0D3002C87B7 /* HorizontalStackBarChart.h in Headers */, - C50CCB561D0EA0D3002C87B7 /* Constants.h in Headers */, + C50CCB561D0EA0D3002C87B7 /* DrConstants.h in Headers */, C50CCB521D0EA0D3002C87B7 /* BarChart.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0;