Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added customization for line width #15

Merged
merged 3 commits into from
Mar 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Classes/JBLineChartView.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@

/**
* The color of the line within the chart.
*
*
* Default: black color
*
* @param lineChartView The origin chart
Expand All @@ -88,6 +88,17 @@
*/
- (UIColor *)lineColorForLineChartView:(JBLineChartView *)lineChartView;

/**
* The width of the line within the chart.
*
* Default: 5 points
*
* @param lineChartView The origin chart
*
* @return The width to be used to draw the line on the chart.
*/
- (CGFloat)lineWidthForLineChartView:(JBLineChartView *)lineChartView;

/**
* The selection color to be overlayed on the chart during touch events.
* The color is automically faded to transparent (vertically).
Expand Down
106 changes: 58 additions & 48 deletions Classes/JBLineChartView.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ @interface JBLineChartLineView : UIView
@property (nonatomic, assign) id<JBLineChartLineViewDelegate> delegate;
@property (nonatomic, assign) JBLineChartLineViewState state;
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, assign) BOOL aniamted;
@property (nonatomic, assign) BOOL animated;

// Data
- (void)reloadData;
Expand All @@ -63,6 +63,7 @@ @protocol JBLineChartLineViewDelegate <NSObject>

- (NSArray *)chartDataForLineChartLineView:(JBLineChartLineView*)lineChartLineView;
- (UIColor *)lineColorForLineChartLineView:(JBLineChartLineView*)lineChartLineView;
- (CGFloat)lineWidthForLineChartLineView:(JBLineChartLineView*)lineChartLineView;

@end

Expand Down Expand Up @@ -120,22 +121,22 @@ - (void)reloadData
{
// reset cached max height
self.cachedMaxHeight = kJBLineChartViewUndefinedMaxHeight;

/*
* Subview rectangle calculations
*/
CGRect mainViewRect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, [self availableHeight]);

/*
* The data collection holds all position and marker information:
* constructed via datasource and delegate functions
*/
dispatch_block_t createChartData = ^{

CGFloat pointSpace = (self.bounds.size.width - (kJBLineChartLineViewEdgePadding * 2)) / ([self dataCount] - 1); // Space in between points
CGFloat xOffset = kJBLineChartLineViewEdgePadding;
CGFloat yOffset = 0;

// Build up the data collection
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:heightForIndex:)], @"JBLineChartView // delegate must implement - (NSInteger)lineChartView:(JBLineChartView *)lineChartView heightForIndex:(NSInteger)index");
NSMutableArray *mutableChartData = [NSMutableArray array];
Expand All @@ -145,34 +146,34 @@ - (void)reloadData
CGFloat rawHeight = [self.delegate lineChartView:self heightForIndex:index];
CGFloat normalizedHeight = [self normalizedHeightForRawHeight:rawHeight];
yOffset = mainViewRect.size.height - normalizedHeight;

chartPoint.position = CGPointMake(xOffset, yOffset);

[mutableChartData addObject:chartPoint];
xOffset += pointSpace;
}

self.chartData = [NSArray arrayWithArray:mutableChartData];
};

/*
* Creates a new line graph view using the previously calculated data model
*/
dispatch_block_t createLineGraphView = ^{

// Remove old line and overlay views
if (self.lineView)
{
[self.lineView removeFromSuperview];
self.lineView = nil;
}

// Create new line and overlay subviews
self.lineView = [[JBLineChartLineView alloc] initWithFrame:CGRectOffset(mainViewRect, 0, self.headerView.frame.size.height + self.headerPadding)];
self.lineView.delegate = self;
[self addSubview:self.lineView];
};

/*
* Creates a vertical selection view for touch events
*/
Expand All @@ -182,7 +183,7 @@ - (void)reloadData
[self.selectionView removeFromSuperview];
self.selectionView = nil;
}

self.selectionView = [[JBChartSelectionView alloc] initWithFrame:CGRectMake(0, 0, kJBLineSelectionViewWidth, self.bounds.size.height - self.footerView.frame.size.height)];
self.selectionView.alpha = 0.0;
if ([self.dataSource respondsToSelector:@selector(selectionColorForLineChartView:)])
Expand All @@ -191,14 +192,14 @@ - (void)reloadData
}
[self insertSubview:self.selectionView belowSubview:self.footerView];
};

createChartData();
createLineGraphView();
createSelectionView();

// Reload views
[self.lineView reloadData];

// Position header and footer
self.headerView.frame = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, self.headerView.frame.size.height);
self.footerView.frame = CGRectMake(self.bounds.origin.x, self.bounds.size.height - self.footerView.frame.size.height, self.bounds.size.width, self.footerView.frame.size.height);
Expand All @@ -210,12 +211,12 @@ - (CGFloat)normalizedHeightForRawHeight:(CGFloat)rawHeight
{
CGFloat minHeight = [self minHeight];
CGFloat maxHeight = [self maxHeight];

if ((maxHeight - minHeight) <= 0)
{
return 0;
}

return ((rawHeight - minHeight) / (maxHeight - minHeight)) * [self availableHeight];
}

Expand Down Expand Up @@ -269,12 +270,21 @@ - (UIColor *)lineColorForLineChartLineView:(JBLineChartLineView*)lineChartLineVi
return kJBLineChartViewDefaultLineColor;
}

- (CGFloat)lineWidthForLineChartLineView:(JBLineChartLineView*)lineChartLineView
{
if ([self.dataSource respondsToSelector:@selector(lineWidthForLineChartView:)])
{
return [self.dataSource lineWidthForLineChartView:self];
}
return kJBLineChartLineViewStrokeWidth;
}

#pragma mark - Setters

- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
{
[super setState:state animated:animated callback:callback];

if (state == JBChartViewStateCollapsed)
{
[self.lineView setState:JBLineChartLineViewStateCollapsed animated:animated callback:callback];
Expand Down Expand Up @@ -310,9 +320,9 @@ - (void)touchesEndedOrCancelledWithTouches:(NSSet *)touches
{
return;
}

[self setSelectionViewVisible:NO animated:YES];

UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
NSInteger index = [self indexForPoint:touchPoint];
Expand All @@ -327,7 +337,7 @@ - (void)touchesEndedOrCancelledWithTouches:(NSSet *)touches
- (void)setSelectionViewVisible:(BOOL)selectionViewVisible animated:(BOOL)animated
{
_selectionViewVisible = selectionViewVisible;

if (animated)
{
[UIView animateWithDuration:kJBChartViewDefaultAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
Expand All @@ -353,15 +363,15 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
return;
}

UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];

if ([self.delegate respondsToSelector:@selector(lineChartView:didSelectChartAtIndex:)])
{
[self.delegate lineChartView:self didSelectChartAtIndex:[self indexForPoint:touchPoint]];
}

CGFloat xOffset = fmin(self.bounds.size.width - self.selectionView.frame.size.width, fmax(0, touchPoint.x - (ceil(self.selectionView.frame.size.width * 0.5))));
self.selectionView.frame = CGRectMake(xOffset, self.selectionView.frame.origin.y, self.selectionView.frame.size.width, self.selectionView.frame.size.height);
[self setSelectionViewVisible:YES animated:YES];
Expand All @@ -373,15 +383,15 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
return;
}

UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];

if ([self.delegate respondsToSelector:@selector(lineChartView:didSelectChartAtIndex:)])
{
[self.delegate lineChartView:self didSelectChartAtIndex:[self indexForPoint:touchPoint]];
}

CGFloat xOffset = fmin(self.bounds.size.width - self.selectionView.frame.size.width, fmax(0, touchPoint.x - (ceil(self.selectionView.frame.size.width * 0.5))));
self.selectionView.frame = CGRectMake(xOffset, self.selectionView.frame.origin.y, self.selectionView.frame.size.width, self.selectionView.frame.size.height);
[self setSelectionViewVisible:YES animated:YES];
Expand Down Expand Up @@ -426,15 +436,15 @@ - (void)dealloc
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];

CGContextRef context = UIGraphicsGetCurrentContext();

UIBezierPath *flatPath = [UIBezierPath bezierPath];
flatPath.miterLimit = kJBLineChartLineViewMiterLimit;

UIBezierPath *dynamicPath = [UIBezierPath bezierPath];
dynamicPath.miterLimit = kJBLineChartLineViewMiterLimit;

NSAssert([self.delegate respondsToSelector:@selector(chartDataForLineChartLineView:)], @"JBLineChartLineView // delegate must implement - (NSArray *)chartDataForLineChartLineView:(JBLineChartLineView *)lineChartLineView");
NSInteger index = 0;
for (JBLineChartPoint *lineChartPoint in [[self.delegate chartDataForLineChartLineView:self] sortedArrayUsingSelector:@selector(compare:)])
Expand All @@ -449,27 +459,27 @@ - (void)drawRect:(CGRect)rect
[dynamicPath addLineToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - kJBLineChartLineViewEdgePadding, fmax(kJBLineChartLineViewEdgePadding, lineChartPoint.position.y)))];
[flatPath addLineToPoint:CGPointMake(lineChartPoint.position.x, ceil(self.bounds.size.height * 0.5))];
}

index++;
}

NSAssert([self.delegate respondsToSelector:@selector(lineColorForLineChartLineView:)], @"JBLineChartLineView // delegate must implement - (UIColor *)lineColorForLineChartLineView:(JBLineChartLineView*)lineChartLineView");

if (self.shapeLayer == nil)
{
self.shapeLayer = [CAShapeLayer layer];
}
if (self.aniamted)

if (self.animated)
{
self.shapeLayer.zPosition = 0.0f;
self.shapeLayer.strokeColor = [self.delegate lineColorForLineChartLineView:self].CGColor;
self.shapeLayer.lineWidth = kJBLineChartLineViewStrokeWidth;
self.shapeLayer.lineWidth = [self.delegate lineWidthForLineChartLineView:self];
self.shapeLayer.lineCap = kCALineCapRound;
self.shapeLayer.lineJoin = kCALineJoinRound;
self.shapeLayer.frame = self.bounds;
self.shapeLayer.fillColor = [UIColor clearColor].CGColor;

if (self.state == JBLineChartLineViewStateCollapsed)
{
self.shapeLayer.path = dynamicPath.CGPath;
Expand All @@ -478,7 +488,7 @@ - (void)drawRect:(CGRect)rect
{
self.shapeLayer.path = flatPath.CGPath;
}

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"path"];
[anim setRemovedOnCompletion:NO];
anim.toValue = self.state == JBLineChartLineViewStateCollapsed ? (id)flatPath.CGPath : (id)dynamicPath.CGPath;
Expand All @@ -494,7 +504,7 @@ - (void)drawRect:(CGRect)rect
{
CGContextSaveGState(context);
{
CGContextSetLineWidth(context, kJBLineChartLineViewStrokeWidth);
CGContextSetLineWidth(context, [self.delegate lineWidthForLineChartLineView:self]);
CGContextSetStrokeColorWithColor(context, [self.delegate lineColorForLineChartLineView:self].CGColor);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineJoin(context, kCGLineJoinRound);
Expand All @@ -504,8 +514,8 @@ - (void)drawRect:(CGRect)rect
}
CGContextRestoreGState(context);
}
self.aniamted = NO;

self.animated = NO;
}

#pragma mark - Data
Expand All @@ -524,13 +534,13 @@ - (void)setState:(JBLineChartLineViewState)state animated:(BOOL)animated callbac
{
return;
}

dispatch_block_t callbackCopy = [callback copy];

_state = state;
self.aniamted = animated;
self.animated = animated;
[self setNeedsDisplay];

if (animated)
{
[self performSelector:@selector(fireCallback:) withObject:callback afterDelay:kJBLineChartLineViewStateAnimationDuration];
Expand All @@ -554,7 +564,7 @@ - (void)setState:(JBLineChartLineViewState)state animated:(BOOL)animated
- (void)fireCallback:(void (^)())callback
{
dispatch_block_t callbackCopy = [callback copy];

if (callbackCopy != nil)
{
callbackCopy();
Expand Down
File renamed without changes.