Compare commits

..

17 Commits

Author SHA1 Message Date
Terry Worona b7734ef189 Updated for new version 2014-04-11 15:02:46 -07:00
Terry Worona f6d2fe8b62 Fixed issue #33 2014-04-11 15:00:33 -07:00
Terry Worona 5c9679f448 updated read me, etc for new version 2014-04-10 16:18:52 -07:00
Terry Worona 037225a386 Fixed issue #30 2014-04-10 16:15:28 -07:00
terryworona 0fe979bd22 Merge pull request #30 from gumbypp/master
JBChartView: needs initWithCoder initializer for inflation from a xib
2014-04-10 16:13:34 -07:00
Dale Low 31b64ed7e4 JBChartView: needs initWithCoder initializer for inflation from a xib 2014-04-10 16:00:27 -07:00
Terry Worona c30398c3ea Updated readme 2014-04-10 13:23:26 -07:00
Terry Worona bc08322a3a Updated version 2014-04-10 13:13:38 -07:00
Terry Worona 213973f4ed Fixing line chart padding calculations for custom dot radius 2014-04-10 11:20:16 -07:00
Terry Worona 28d40bcb31 Added dot radius callbacks for line charts 2014-04-10 10:58:47 -07:00
Terry Worona d4df0184a2 Updated change log, pod spec and read me 2014-04-03 14:49:36 -07:00
Terry Worona 4f313aab80 Added state force setters 2014-04-03 14:48:01 -07:00
Terry Worona b6262462c5 Updated pod spec change log and read me 2014-04-02 11:49:52 -07:00
Terry Worona 1080089753 Added dynamic padding to line chart view 2014-04-02 11:46:42 -07:00
Terry Worona 0afba01a9a Updated read me and pod spec 2014-04-02 10:26:59 -07:00
Terry Worona 63b47667ec Fixed min and max value properties 2014-04-02 09:08:12 -07:00
Terry Worona 4d6baf066f cleaned up cached constants 2014-04-02 08:50:43 -07:00
9 changed files with 342 additions and 129 deletions
+24
View File
@@ -1,5 +1,29 @@
# Changelog
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.6">2.1.6</a>
#### 04/11/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/33">#33</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.5">2.1.5</a>
#### 04/10/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/30">#30</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.4">2.1.4</a>
#### 04/10/14
- Added ability to specify a radius for dotted lines.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.3">2.1.3</a>
#### 04/03/14
- Added the ability to force a chart's state.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.2">2.1.2</a>
#### 04/02/14
- Added dynamic padding to JBLineChartView (based on max line width).
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.1">2.1.1</a>
#### 04/02/14
- Fixed minimumValue and maximumValue getter functions.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.1.0">2.1.0</a>
#### 03/30/14
- Added minimumValue and maximumValue properties.
+59 -34
View File
@@ -10,8 +10,7 @@
// Numerics
CGFloat static const kJBBarChartViewBarBasePaddingMutliplier = 50.0f;
CGFloat static const kJBBarChartViewUndefinedMaxHeight = -1.0f;
CGFloat static const kJBBarChartViewUndefinedMinHeight = -1.0f;
CGFloat static const kJBBarChartViewUndefinedCachedHeight = -1.0f;
CGFloat static const kJBBarChartViewStateAnimationDuration = 0.05f;
CGFloat static const kJBBarChartViewPopOffset = 10.0f; // used to offset bars for 'pop' animations
NSInteger static const kJBBarChartViewUndefinedBarIndex = -1;
@@ -35,8 +34,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
// View quick accessors
- (CGFloat)availableHeight;
- (CGFloat)normalizedHeightForRawHeight:(NSNumber*)rawHeight;
- (CGFloat)maxHeight;
- (CGFloat)minHeight;
- (CGFloat)maxHeight;
- (CGFloat)barWidth;
- (CGFloat)popOffset;
@@ -96,7 +95,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (void)construct
{
_showsVerticalSelection = YES;
_cachedMaxHeight = kJBBarChartViewUndefinedMaxHeight;
_cachedMinHeight = kJBBarChartViewUndefinedCachedHeight;
_cachedMaxHeight = kJBBarChartViewUndefinedCachedHeight;
}
#pragma mark - Memory Management
@@ -111,7 +111,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (void)reloadData
{
// reset cached max height
self.cachedMaxHeight = kJBBarChartViewUndefinedMaxHeight;
self.cachedMinHeight = kJBBarChartViewUndefinedCachedHeight;
self.cachedMaxHeight = kJBBarChartViewUndefinedCachedHeight;
/*
* The data collection holds all position information:
@@ -237,6 +238,9 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
// 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);
// Refresh state
[self setState:self.state animated:NO callback:nil force:YES];
}
#pragma mark - View Quick Accessors
@@ -262,19 +266,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (CGFloat)minHeight
{
BOOL hasCachedMinHeight = self.cachedMinHeight != kJBBarChartViewUndefinedMinHeight;
dispatch_block_t calculateCachedMinHeight = ^{
// min height is min value across all goals and values
NSArray *chartValues = [[[self.chartDataDictionary allValues] arrayByAddingObjectsFromArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
self.cachedMinHeight = [[chartValues firstObject] floatValue];
};
if (!hasCachedMinHeight)
{
calculateCachedMinHeight();
}
if (self.mininumValue != kJBChartViewUndefinedMinimumValue)
{
return MIN(self.mininumValue, self.cachedMinHeight);
@@ -284,19 +275,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (CGFloat)maxHeight
{
BOOL hasCachedMaxHeight = self.cachedMaxHeight != kJBBarChartViewUndefinedMaxHeight;
dispatch_block_t calculateCachedMaxHeight = ^{
// max height is max value across all goals and values
NSArray *chartValues = [[[self.chartDataDictionary allValues] arrayByAddingObjectsFromArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
self.cachedMaxHeight = [[chartValues lastObject] floatValue];
};
if (!hasCachedMaxHeight)
{
calculateCachedMaxHeight();
}
if (self.maximumValue != kJBChartViewUndefinedMaximumValue)
{
return MAX(self.maximumValue, self.cachedMaxHeight);
@@ -323,9 +301,9 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
#pragma mark - Setters
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback force:(BOOL)force
{
[super setState:state animated:animated callback:callback];
[super setState:state animated:animated callback:callback force:force];
dispatch_block_t callbackCopy = [callback copy];
@@ -380,7 +358,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
{
callbackCopy();
}
}
}
}
else
{
@@ -391,6 +369,53 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
}
}
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
{
[self setState:state animated:animated callback:callback force:NO];
}
#pragma mark - Getters
- (CGFloat)cachedMinHeight
{
if(_cachedMinHeight == kJBBarChartViewUndefinedCachedHeight)
{
// min height is min value across all goals and values
NSArray *chartValues = [[[self.chartDataDictionary allValues] arrayByAddingObjectsFromArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
_cachedMinHeight = [[chartValues firstObject] floatValue];
}
return _cachedMinHeight;
}
- (CGFloat)cachedMaxHeight
{
if (_cachedMaxHeight == kJBBarChartViewUndefinedCachedHeight)
{
// max height is max value across all goals and values
NSArray *chartValues = [[[self.chartDataDictionary allValues] arrayByAddingObjectsFromArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
_cachedMaxHeight = [[chartValues lastObject] floatValue];
}
return _cachedMaxHeight;
}
- (CGFloat)mininumValue
{
if ([super mininumValue] == kJBChartViewUndefinedMinimumValue)
{
return self.cachedMinHeight;
}
return [super mininumValue];
}
- (CGFloat)maximumValue
{
if ([super maximumValue] == kJBChartViewUndefinedMaximumValue)
{
return self.cachedMaxHeight;
}
return [super maximumValue];
}
#pragma mark - Touch Helpers
- (NSInteger)barViewIndexForPoint:(CGPoint)point
+10
View File
@@ -66,6 +66,16 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
*/
- (void)reloadData;
/**
* State setter.
*
* @param state Either collapse or expanded.
* @param animated Whether or not the state should be animated or not.
* @param callback Called once the animation is completed. If animated == NO, then callback is immediate.
* @param force If current state == new state, then setting force to YES will re-configure the chart (default NO).
*/
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback force:(BOOL)force;
/**
* State setter.
*
+32 -6
View File
@@ -17,6 +17,10 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
@interface JBChartView ()
// Construction
- (void)constructChartView;
// Validation
- (void)validateHeaderAndFooterHeights;
@end
@@ -25,14 +29,22 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
#pragma mark - Alloc/Init
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self constructChartView];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.clipsToBounds = YES;
_mininumValue = kJBChartViewUndefinedMinimumValue;
_maximumValue = kJBChartViewUndefinedMaximumValue;
[self constructChartView];
}
return self;
}
@@ -42,6 +54,15 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
return [self initWithFrame:CGRectZero];
}
#pragma mark - Construction
- (void)constructChartView
{
self.clipsToBounds = YES;
_mininumValue = kJBChartViewUndefinedMinimumValue;
_maximumValue = kJBChartViewUndefinedMaximumValue;
}
#pragma mark - Public
- (void)reloadData
@@ -49,7 +70,7 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
// Override
}
#pragma mark - Helpers
#pragma mark - Validation
- (void)validateHeaderAndFooterHeights
{
@@ -90,9 +111,9 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
[self reloadData];
}
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback force:(BOOL)force
{
if (_state == state)
if ((_state == state) && !force)
{
return;
}
@@ -102,6 +123,11 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
// Override
}
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
{
[self setState:state animated:animated callback:callback force:NO];
}
- (void)setState:(JBChartViewState)state animated:(BOOL)animated
{
[self setState:state animated:animated callback:nil];
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "JBChartView"
s.version = "2.1.0"
s.version = "2.1.6"
s.summary = "Jawbone's iOS-based charting library for both line and bar graphs."
s.homepage = "https://github.com/Jawbone/JBChartView"
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
s.author = { "Terry Worona" => "tworona@jawbone.com" }
s.source = {
:git => "https://github.com/Jawbone/JBChartView.git",
:tag => "v2.1.0"
:tag => "v2.1.6"
}
s.platform = :ios, '7.0'
+14
View File
@@ -138,6 +138,20 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*/
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView widthForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns the radius of all dots in a particular line at lineIndex within the chart.
* For this value to apply, showsDotsForLineAtLineIndex: must return YES for the line at lineIndex.
* Any value can be returned for lineIndex's that don't support dots, as it will never be called.
*
* Default: line width x 3.
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
*
* @return The radius of the dots within a dotted line in the chart.
*/
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns the (vertical) selection color to be overlayed on the chart during touch events.
* The color is automically faded to transparent (vertically). The property showsVerticalSelection
+191 -86
View File
@@ -19,7 +19,6 @@ typedef NS_ENUM(NSUInteger, JBLineChartHorizontalIndexClamp){
};
// Numerics (JBLineChartLineView)
CGFloat static const kJBLineChartLinesViewEdgePadding = 10.0;
CGFloat static const kJBLineChartLinesViewStrokeWidth = 5.0;
CGFloat static const kJBLineChartLinesViewMiterLimit = -5.0;
CGFloat static const kJBLineChartLinesViewDefaultLinePhase = 1.0f;
@@ -27,15 +26,14 @@ CGFloat static const kJBLineChartLinesViewDefaultDimmedOpacity = 0.5f;
NSInteger static const kJBLineChartLinesViewUnselectedLineIndex = -1;
// Numerics (JBLineChartDotsView)
NSInteger static const kJBLineChartDotsViewRadiusFactor = 3; // 3x size of line width
NSInteger static const kJBLineChartDotsViewDefaultRadiusFactor = 3; // 3x size of line width
NSInteger static const kJBLineChartDotsViewUnselectedLineIndex = -1;
// Numerics (JBLineSelectionView)
CGFloat static const kJBLineSelectionViewWidth = 20.0f;
// Numerics (JBLineChartView)
CGFloat static const kJBLineChartViewUndefinedMaxHeight = -1.0f;
CGFloat static const kJBLineChartViewUndefinedMinHeight = -1.0f;
CGFloat static const kJBBarChartViewUndefinedCachedHeight = -1.0f;
CGFloat static const kJBLineChartViewStateAnimationDuration = 0.25f;
CGFloat static const kJBLineChartViewStateAnimationDelay = 0.05f;
CGFloat static const kJBLineChartViewStateBounceOffset = 15.0f;
@@ -89,6 +87,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView colorForLineAtLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView widthForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)paddingForLineChartLinesView:(JBLineChartLinesView *)lineChartLinesView;
- (JBLineChartViewLineStyle)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView lineStyleForLineAtLineIndex:(NSUInteger)lineIndex;
- (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex;
@@ -116,6 +115,8 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForLineAtLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView widthForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
- (CGFloat)paddingForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView;
- (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
@end
@@ -142,8 +143,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
// View quick accessors
- (CGFloat)normalizedHeightForRawHeight:(CGFloat)rawHeight;
- (CGFloat)availableHeight;
- (CGFloat)maxHeight;
- (CGFloat)minHeight;
- (CGFloat)maxHeight;
- (CGFloat)padding;
- (NSUInteger)dataCount;
// Touch helpers
@@ -207,15 +209,20 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
_showsVerticalSelection = YES;
_showsLineSelection = YES;
_cachedMaxHeight = kJBLineChartViewUndefinedMaxHeight;
_cachedMinHeight = kJBBarChartViewUndefinedCachedHeight;
_cachedMaxHeight = kJBBarChartViewUndefinedCachedHeight;
}
#pragma mark - Data
- (void)reloadData
{
// reset cached max height
self.cachedMaxHeight = kJBLineChartViewUndefinedMaxHeight;
// Reset cached max height
self.cachedMinHeight = kJBBarChartViewUndefinedCachedHeight;
self.cachedMaxHeight = kJBBarChartViewUndefinedCachedHeight;
// Padding
CGFloat chartPadding = [self padding];
/*
* Subview rectangle calculations
@@ -228,8 +235,8 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
*/
dispatch_block_t createChartData = ^{
CGFloat pointSpace = (self.bounds.size.width - (kJBLineChartLinesViewEdgePadding * 2)) / ([self dataCount] - 1); // Space in between points
CGFloat xOffset = kJBLineChartLinesViewEdgePadding;
CGFloat pointSpace = (self.bounds.size.width - (chartPadding * 2)) / ([self dataCount] - 1); // Space in between points
CGFloat xOffset = chartPadding;
CGFloat yOffset = 0;
NSMutableArray *mutableChartData = [NSMutableArray array];
@@ -255,7 +262,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
xOffset += pointSpace;
}
[mutableChartData addObject:chartPointData];
xOffset = kJBLineChartLinesViewEdgePadding;
xOffset = chartPadding;
}
self.chartData = [NSArray arrayWithArray:mutableChartData];
};
@@ -355,6 +362,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
// 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);
// Refresh state
[self setState:self.state animated:NO callback:nil force:YES];
}
#pragma mark - View Quick Accessors
@@ -379,34 +389,6 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (CGFloat)minHeight
{
BOOL hasCachedMinHeight = self.cachedMinHeight != kJBLineChartViewUndefinedMinHeight;
dispatch_block_t calculateCachedMinHeight = ^{
CGFloat minHeight = FLT_MAX;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
for (NSUInteger horizontalIndex=0; horizontalIndex<dataCount; horizontalIndex++)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height < minHeight)
{
minHeight = height;
}
}
}
self.cachedMinHeight = minHeight;
};
if (!hasCachedMinHeight)
{
calculateCachedMinHeight();
}
if (self.mininumValue != kJBChartViewUndefinedMinimumValue)
{
return MIN(self.mininumValue, self.cachedMinHeight);
@@ -415,35 +397,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
}
- (CGFloat)maxHeight
{
BOOL hasCachedMaxHeight = self.cachedMaxHeight != kJBLineChartViewUndefinedMaxHeight;
dispatch_block_t calculateCachedMaxHeight = ^{
CGFloat maxHeight = 0;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
for (NSUInteger horizontalIndex=0; horizontalIndex<dataCount; horizontalIndex++)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height > maxHeight)
{
maxHeight = height;
}
}
}
self.cachedMaxHeight = maxHeight;
};
if (!hasCachedMaxHeight)
{
calculateCachedMaxHeight();
}
{
if (self.maximumValue != kJBChartViewUndefinedMaximumValue)
{
return MAX(self.maximumValue, self.cachedMaxHeight);
@@ -451,6 +405,43 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return self.cachedMaxHeight;
}
- (CGFloat)padding
{
CGFloat maxLineWidth = 0.0f;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (int lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
{
BOOL showsDots = NO;
if ([self.dataSource respondsToSelector:@selector(lineChartView:showsDotsForLineAtLineIndex:)])
{
showsDots = [self.dataSource lineChartView:self showsDotsForLineAtLineIndex:lineIndex];
}
CGFloat lineWidth = kJBLineChartLinesViewStrokeWidth; // default
if ([self.dataSource respondsToSelector:@selector(lineChartView:widthForLineAtLineIndex:)])
{
lineWidth = [self.dataSource lineChartView:self widthForLineAtLineIndex:lineWidth];
}
CGFloat dotRadius = lineWidth * kJBLineChartDotsViewDefaultRadiusFactor; // default
if (showsDots)
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:dotRadiusForLineAtLineIndex:)])
{
dotRadius = [self.dataSource lineChartView:self dotRadiusForLineAtLineIndex:lineIndex];
}
}
CGFloat currentMaxLineWidth = MAX(dotRadius, lineWidth);
if (currentMaxLineWidth > maxLineWidth)
{
maxLineWidth = currentMaxLineWidth;
}
}
return ceil(maxLineWidth * 0.5);
}
- (NSUInteger)dataCount
{
NSUInteger dataCount = 0;
@@ -501,6 +492,11 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return kJBLineChartLinesViewStrokeWidth;
}
- (CGFloat)paddingForLineChartLinesView:(JBLineChartLinesView *)lineChartLinesView
{
return [self padding];
}
- (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:smoothLineAtLineIndex:)])
@@ -553,6 +549,23 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return kJBLineChartLinesViewStrokeWidth;
}
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:dotRadiusForLineAtLineIndex:)])
{
return [self.dataSource lineChartView:self dotRadiusForLineAtLineIndex:lineIndex];
}
else
{
return [self lineChartDotsView:lineChartDotsView widthForLineAtLineIndex:lineIndex] * kJBLineChartDotsViewDefaultRadiusFactor;
}
}
- (CGFloat)paddingForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView
{
return [self padding];
}
- (BOOL)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:showsDotsForLineAtLineIndex:)])
@@ -564,9 +577,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
#pragma mark - Setters
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback force:(BOOL)force
{
[super setState:state animated:animated callback:callback];
[super setState:state animated:animated callback:callback force:force];
if ([self.chartData count] > 0)
{
@@ -597,7 +610,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
callback();
}
}];
}];
}];
[UIView animateWithDuration:kJBLineChartViewStateAnimationDuration delay:(self.state == JBChartViewStateExpanded) ? kJBLineChartViewStateAnimationDelay : 0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
adjustViewAlphas();
} completion:nil];
@@ -621,6 +634,83 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
}
}
- (void)setState:(JBChartViewState)state animated:(BOOL)animated callback:(void (^)())callback
{
[self setState:state animated:animated callback:callback force:NO];
}
#pragma mark - Getters
- (CGFloat)cachedMinHeight
{
if (_cachedMinHeight == kJBBarChartViewUndefinedCachedHeight)
{
CGFloat minHeight = FLT_MAX;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
for (NSUInteger horizontalIndex=0; horizontalIndex<dataCount; horizontalIndex++)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height < minHeight)
{
minHeight = height;
}
}
}
_cachedMinHeight = minHeight;
}
return _cachedMinHeight;
}
- (CGFloat)cachedMaxHeight
{
if (_cachedMaxHeight == kJBBarChartViewUndefinedCachedHeight)
{
CGFloat maxHeight = 0;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
{
NSAssert([self.dataSource respondsToSelector:@selector(lineChartView:numberOfVerticalValuesAtLineIndex:)], @"JBLineChartView // dataSource must implement - (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex");
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
for (NSUInteger horizontalIndex=0; horizontalIndex<dataCount; horizontalIndex++)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartView:verticalValueForHorizontalIndex:atLineIndex:)], @"JBLineChartView // delegate must implement - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
CGFloat height = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(height >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
if (height > maxHeight)
{
maxHeight = height;
}
}
}
_cachedMaxHeight = maxHeight;
}
return _cachedMaxHeight;
}
- (CGFloat)mininumValue
{
if ([super mininumValue] == kJBChartViewUndefinedMinimumValue)
{
return self.cachedMinHeight;
}
return [super mininumValue];
}
- (CGFloat)maximumValue
{
if ([super maximumValue] == kJBChartViewUndefinedMaximumValue)
{
return self.cachedMaxHeight;
}
return [super maximumValue];
}
#pragma mark - Touch Helpers
- (CGPoint)clampPoint:(CGPoint)point toBounds:(CGRect)bounds padding:(CGFloat)padding
@@ -673,6 +763,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
NSInteger leftHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampLeft];
NSInteger rightHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampRight];
// Padding
CGFloat chartPadding = [self padding];
NSUInteger shortestDistance = INT_MAX;
NSInteger selectedIndex = kJBLineChartUnselectedLineIndex;
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
@@ -687,11 +780,11 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
// Left point
JBLineChartPoint *leftLineChartPoint = [lineData objectAtIndex:leftHorizontalIndex];
CGPoint leftPoint = CGPointMake(leftLineChartPoint.position.x, fmin(fmax(kJBLineChartLinesViewEdgePadding, self.linesView.bounds.size.height - leftLineChartPoint.position.y), self.linesView.bounds.size.height - kJBLineChartLinesViewEdgePadding));
CGPoint leftPoint = CGPointMake(leftLineChartPoint.position.x, fmin(fmax(chartPadding, self.linesView.bounds.size.height - leftLineChartPoint.position.y), self.linesView.bounds.size.height - chartPadding));
// Right point
JBLineChartPoint *rightLineChartPoint = [lineData objectAtIndex:rightHorizontalIndex];
CGPoint rightPoint = CGPointMake(rightLineChartPoint.position.x, fmin(fmax(kJBLineChartLinesViewEdgePadding, self.linesView.bounds.size.height - rightLineChartPoint.position.y), self.linesView.bounds.size.height - kJBLineChartLinesViewEdgePadding));
CGPoint rightPoint = CGPointMake(rightLineChartPoint.position.x, fmin(fmax(chartPadding, self.linesView.bounds.size.height - rightLineChartPoint.position.y), self.linesView.bounds.size.height - chartPadding));
// Touch point
CGPoint normalizedTouchPoint = CGPointMake(point.x, self.linesView.bounds.size.height - point.y);
@@ -721,7 +814,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
}
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:kJBLineChartLinesViewEdgePadding];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:[self padding]];
if ([self.delegate respondsToSelector:@selector(lineChartView:didSelectLineAtIndex:horizontalIndex:touchPoint:)])
{
@@ -754,8 +847,12 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
[self.delegate didUnselectLineInLineChartView:self];
}
[self.linesView setSelectedLineIndex:kJBLineChartLinesViewUnselectedLineIndex animated:YES];
[self.dotsView setSelectedLineIndex:kJBLineChartDotsViewUnselectedLineIndex animated:YES];
if (self.showsLineSelection)
{
[self.linesView setSelectedLineIndex:kJBLineChartLinesViewUnselectedLineIndex animated:YES];
[self.dotsView setSelectedLineIndex:kJBLineChartDotsViewUnselectedLineIndex animated:YES];
}
}
#pragma mark - Setters
@@ -794,9 +891,12 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:kJBLineChartLinesViewEdgePadding];
[self.linesView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
[self.dotsView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:[self padding]];
if (self.showsLineSelection)
{
[self.linesView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
[self.dotsView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
}
[self touchesBeganOrMovedWithTouches:touches];
}
@@ -912,6 +1012,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
NSAssert([self.delegate respondsToSelector:@selector(chartDataForLineChartLinesView:)], @"JBLineChartLinesView // delegate must implement - (NSArray *)chartDataForLineChartLinesView:(JBLineChartLinesView *)lineChartLinesView");
NSArray *chartData = [self.delegate chartDataForLineChartLinesView:self];
NSAssert([self.delegate respondsToSelector:@selector(paddingForLineChartLinesView:)], @"JBLineChartLinesView // delegate must implement - (CGFloat)paddingForLineChartLinesView:(JBLineChartLinesView *)lineChartLinesView");
CGFloat padding = [self.delegate paddingForLineChartLinesView:self];
NSUInteger lineIndex = 0;
for (NSArray *lineData in chartData)
@@ -924,11 +1027,11 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
if (index == 0)
{
[path moveToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - kJBLineChartLinesViewEdgePadding, fmax(kJBLineChartLinesViewEdgePadding, lineChartPoint.position.y)))];
[path moveToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)))];
}
else
{
[path addLineToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - kJBLineChartLinesViewEdgePadding, fmax(kJBLineChartLinesViewEdgePadding, lineChartPoint.position.y)))];
[path addLineToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)))];
}
index++;
@@ -1081,6 +1184,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
NSAssert([self.delegate respondsToSelector:@selector(chartDataForLineChartDotsView:)], @"JBLineChartDotsView // delegate must implement - (NSArray *)chartDataForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView");
NSArray *chartData = [self.delegate chartDataForLineChartDotsView:self];
NSAssert([self.delegate respondsToSelector:@selector(paddingForLineChartDotsView:)], @"JBLineChartDotsView // delegate must implement - (CGFloat)paddingForLineChartDotsView:(JBLineChartDotsView *)lineChartDotsView");
CGFloat padding = [self.delegate paddingForLineChartDotsView:self];
NSUInteger lineIndex = 0;
NSMutableDictionary *mutableDotViewsDict = [NSMutableDictionary dictionary];
@@ -1092,13 +1198,12 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
NSMutableArray *mutableDotViews = [NSMutableArray array];
for (JBLineChartPoint *lineChartPoint in [lineData sortedArrayUsingSelector:@selector(compare:)])
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:widthForLineAtLineIndex:)], @"JBLineChartDotsView // delegate must implement - (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView widthForLineAtLineIndex:(NSUInteger)lineIndex");
CGFloat lineWidth = [self.delegate lineChartDotsView:self widthForLineAtLineIndex:lineIndex];
CGFloat dotRadius = lineWidth * kJBLineChartDotsViewRadiusFactor;
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:dotRadiusForLineAtLineIndex:)], @"JBLineChartDotsView // delegate must implement - (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex");
CGFloat dotRadius = [self.delegate lineChartDotsView:self dotRadiusForLineAtLineIndex:lineIndex];
JBLineChartDotView *dotView = [[JBLineChartDotView alloc] initWithRadius:dotRadius];
dotView.center = CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - kJBLineChartLinesViewEdgePadding, fmax(kJBLineChartLinesViewEdgePadding, lineChartPoint.position.y)));
dotView.center = CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)));
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForLineAtLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForLineAtLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForLineAtLineIndex:lineIndex];
@@ -216,6 +216,11 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
return (lineIndex == JBLineChartLineSolid) ? kJBLineChartViewControllerChartSolidLineWidth: kJBLineChartViewControllerChartDashedLineWidth;
}
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? 0.0: (kJBLineChartViewControllerChartDashedLineWidth * 4);
}
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView
{
return [UIColor whiteColor];
+5 -1
View File
@@ -38,7 +38,7 @@ Simply add the following line to your <code>Podfile</code>:
Your Podfile should look something like:
platform :ios, '7.0'
pod 'JBChartView', '~> 2.1.0'
pod 'JBChartView', '~> 2.1.6'
### The Old School Way
@@ -196,6 +196,10 @@ Furthermore, the color of the selection bar and line can be customized via the <
By default, each line will not show dots for each point. To enable this on a per-line basis:
- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
To customize the size of each dot, implement (default is 3x the line width):
- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
As well, by default, each line will have squared off end caps and connection points. To enable line smoothing: