Compare commits

...

58 Commits

Author SHA1 Message Date
Terry Worona a303422d8e updated read me, pod spec, etc 2014-05-13 19:44:52 -07:00
Terry Worona 1aff68557f Cleaned up demo code and add min value to bar charts 2014-05-13 19:42:14 -07:00
terryworona ac3744c0c9 Merge pull request #57 from pala/master
Fixed barView's frame.
2014-05-13 19:33:55 -07:00
Tao Zhang a6ea0c30f8 Update JBBarChartView.m 2014-05-13 21:56:02 -04:00
pala ea531e3cb1 Fixed barView's frame. 2014-05-13 19:42:06 -04:00
terryworona b1a3ebd4ed Merge pull request #55 from pala/patch-1
Update sample code in readme
2014-05-13 10:39:24 -07:00
Tao Zhang 554f93f3d3 Update sample code 2014-05-12 23:41:25 -04:00
Terry Worona 2ddd38fc9d updated change log 2014-05-07 09:55:10 -07:00
Terry Worona 6691f7a8c3 Updated comment, read me, pod spec, etc 2014-05-07 09:47:32 -07:00
terryworona c015531c85 Merge pull request #53 from skywinder/bar-color-delegate
Add delegate method barChartView:colorForBarViewAtIndex: to JBBarChartViewDataSource
2014-05-07 09:40:43 -07:00
terryworona 3d036edc96 Merge pull request #52 from skywinder/compiling-warrnings-and-typos
Compiling warrnings and typos
2014-05-07 09:36:48 -07:00
Petr Korolev 85c30351fe Add new delegate method to JBBarChartView
Implement logic to set specifed color before set the default kJBBarChartViewDefaultBarColor
Add call of this code to Example project
2014-05-07 15:33:50 +03:00
Petr Korolev d37383a352 fix typo 2014-05-07 14:59:34 +03:00
Petr Korolev 3c6cf24cf7 Cast to correct return type (NSUInteger) 2014-05-07 14:37:28 +03:00
Terry Worona 8dbb2679ee Updated log, spec and read me 2014-05-06 14:05:24 -07:00
Terry Worona 867466d1d1 More more compile error 2014-05-06 14:04:17 -07:00
Terry Worona 2046131143 Updated read me, pod spec, etc. 2014-05-06 13:40:21 -07:00
Terry Worona 208a727d88 Fixed compiler warnings 2014-05-06 13:38:24 -07:00
Terry Worona 43c6e9486f Updated version, pod spec, etc 2014-05-05 12:33:39 -07:00
Terry Worona 49206a01ed Fixed issue #48 2014-05-05 12:31:12 -07:00
Terry Worona e2b17820bf readme updates 2014-05-04 14:47:21 -07:00
Terry Worona b59904e5b9 updated for new version 2014-05-04 14:45:27 -07:00
Terry Worona 1d8f78d751 Fixed issue #48 2014-05-04 14:07:27 -07:00
Terry Worona 3cc39124b8 updated version 2014-05-04 09:48:10 -07:00
terryworona bedd7e2c71 Merge pull request #49 from simonnickel/master
fixed typo, renamed mininum -> minimum
2014-05-04 09:44:03 -07:00
Simon Nickel 786af91666 fixed typo, renamed mininum -> minimum 2014-05-03 22:18:42 +02:00
Terry Worona b7927cddb7 Fixes issue #46 2014-04-30 22:58:47 -07:00
Terry Worona 0f2d4d766c updated change log, pod spec, etc 2014-04-30 10:04:01 -07:00
terryworona 64de3e6e23 Merge pull request #45 from ktran03/smoothCurveFix
Smooth curve fix
2014-04-30 09:59:22 -07:00
ktran03 87fb8ee7b8 missing variable in condition 2014-04-29 22:03:40 -04:00
ktran03 7c0dfe3eb5 smooth curve fix for more straight line cases 2014-04-29 21:55:47 -04:00
Terry Worona 87b62ad2b1 updated change log, pod spec, read me 2014-04-28 12:06:03 -07:00
Terry Worona 9c0d788418 More style updates 2014-04-28 12:00:59 -07:00
Terry Worona de009f0236 PR #39 cleanup 2014-04-28 11:25:45 -07:00
ktran03 d46e4fe14d changed compare condition to using slope instead of vertical diff 2014-04-26 18:32:40 -04:00
ktran03 236336fdf3 added check for y-value difference if exceeds threshold 2014-04-25 15:14:16 -04:00
ktran03 9b60a1d662 Expose smooth option through delegate, fix diffs 2014-04-24 14:35:54 -04:00
ktran03 3700b4e2e2 smooth curve using bezierpath 2014-04-19 20:15:53 -04:00
Terry Worona 8c03033a1c Added screenshot to pod spec 2014-04-18 10:14:42 -07:00
Terry Worona bb084b1b89 Fixes issue #34 2014-04-17 18:32:58 -07:00
Terry Worona 1c7c8b2e52 Updated read me, pod spec etc for new version 2014-04-14 10:36:07 -07:00
Terry Worona 79a57d98e3 Clamp selection width to width of chart 2014-04-14 10:32:50 -07:00
Terry Worona 20d6b6081b Fixed comment 2014-04-14 10:30:24 -07:00
terryworona 20bbbdcc86 Merge pull request #37 from veducm/master
Added delegate method to configure the width of the vertical selection bar in a line chart.
2014-04-14 10:27:51 -07:00
Edu Caselles 51ac8a1d63 Added delegate method to configure the width of the vertical selection bar in a line chart. 2014-04-14 01:35:20 +02:00
Terry Worona 68d04a2cdb Fixes issue #36 2014-04-12 09:11:41 -07:00
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
13 changed files with 509 additions and 276 deletions
+64
View File
@@ -1,5 +1,69 @@
# Changelog
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.5">2.5.5</a>
#### 05/13/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/57">#57</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.4">2.5.4</a>
#### 05/07/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/53">#53</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.3">2.5.3</a>
#### 05/06/14
- More compiler warning fixes.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.2">2.5.2</a>
#### 05/06/14
- Fixed compiler warnings.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.1">2.5.1</a>
#### 05/05/14
- Additional fixes to issue <a href="https://github.com/Jawbone/JBChartView/pull/48">#48</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.5.0">2.5.0</a>
#### 05/04/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/48">#48</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.3">2.4.3</a>
#### 05/04/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/49">#49</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.2">2.4.2</a>
#### 04/30/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/46">#46</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.1">2.4.1</a>
#### 04/30/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/45">#45</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.4.0">2.4.0</a>
#### 04/28/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/23">#23</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.3.0">2.3.0</a>
#### 04/17/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/34">#34</a>.
## <a href="https://github.com/Jawbone/JBChartView/tree/v2.2.0">2.2.0</a>
#### 04/14/14
- Fixes issue <a href="https://github.com/Jawbone/JBChartView/pull/37">#37</a>.
## <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).
+14 -1
View File
@@ -102,9 +102,22 @@
*/
- (UIView *)barChartView:(JBBarChartView *)barChartView barViewAtIndex:(NSUInteger)index;
/**
* If you already implement barChartView:barViewAtIndex: delegate - this method has no effect.
* If a custom UIView isn't supplied, a flat bar will be made automatically (default color black).
*
* Default: if none specified - calls barChartView:barViewAtIndex:.
*
* @param barChartView The bar chart object requesting this information.
* @param index The 0-based index of a given bar (left to right, x-axis).
*
* @return The color to be used to color a bar in the chart.
*/
- (UIColor *)barChartView:(JBBarChartView *)barChartView colorForBarViewAtIndex:(NSUInteger)index;
/**
* The selection color to be overlayed on a bar during touch events.
* The color is automically faded to transparent (vertically). The property showsVerticalSelection
* The color is automatically faded to transparent (vertically). The property showsVerticalSelection
* must be YES for the color to apply.
*
* Default: white color (faded to transparent).
+44 -38
View File
@@ -18,6 +18,13 @@ NSInteger static const kJBBarChartViewUndefinedBarIndex = -1;
// Colors (JBChartView)
static UIColor *kJBBarChartViewDefaultBarColor = nil;
@interface JBChartView (Private)
- (BOOL)hasMaximumValue;
- (BOOL)hasMinimumValue;
@end
@interface JBBarChartView ()
@property (nonatomic, strong) NSDictionary *chartDataDictionary; // key = column, value = height
@@ -34,8 +41,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
// View quick accessors
- (CGFloat)availableHeight;
- (CGFloat)normalizedHeightForRawHeight:(NSNumber*)rawHeight;
- (CGFloat)minHeight;
- (CGFloat)maxHeight;
- (CGFloat)barWidth;
- (CGFloat)popOffset;
@@ -176,11 +181,24 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
else
{
barView = [[UIView alloc] init];
barView.backgroundColor = kJBBarChartViewDefaultBarColor;
UIColor *backgroundColor = nil;
if ([self.dataSource respondsToSelector:@selector(barChartView:colorForBarViewAtIndex:)])
{
backgroundColor = [self.dataSource barChartView:self colorForBarViewAtIndex:index];
NSAssert(backgroundColor != nil, @"JBBarChartView // datasource function - (UIColor *)barChartView:(JBBarChartView *)barChartView colorForBarViewAtIndex:(NSUInteger)index must return a non-nil UIColor");
}
else
{
backgroundColor = kJBBarChartViewDefaultBarColor;
}
barView.backgroundColor = backgroundColor;
}
CGFloat height = [self normalizedHeightForRawHeight:[self.chartDataDictionary objectForKey:key]];
CGFloat extensionHeight = height > 0.0 ? kJBBarChartViewPopOffset : 0.0;
barView.frame = CGRectMake(xOffset, self.bounds.size.height - height - self.footerView.frame.size.height + self.headerPadding, [self barWidth], height + extensionHeight - self.headerPadding);
barView.frame = CGRectMake(xOffset, self.bounds.size.height - height - self.footerView.frame.size.height, [self barWidth], height + extensionHeight);
[mutableBarViews addObject:barView];
// Add new bar
@@ -238,6 +256,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
@@ -249,8 +270,8 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
- (CGFloat)normalizedHeightForRawHeight:(NSNumber*)rawHeight
{
CGFloat minHeight = [self minHeight];
CGFloat maxHeight = [self maxHeight];
CGFloat minHeight = [self minimumValue];
CGFloat maxHeight = [self maximumValue];
CGFloat value = [rawHeight floatValue];
if ((maxHeight - minHeight) <= 0)
@@ -261,24 +282,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
return ((value - minHeight) / (maxHeight - minHeight)) * [self availableHeight];
}
- (CGFloat)minHeight
{
if (self.mininumValue != kJBChartViewUndefinedMinimumValue)
{
return MIN(self.mininumValue, self.cachedMinHeight);
}
return self.cachedMinHeight;
}
- (CGFloat)maxHeight
{
if (self.maximumValue != kJBChartViewUndefinedMaximumValue)
{
return MAX(self.maximumValue, self.cachedMaxHeight);
}
return self.cachedMaxHeight;
}
- (CGFloat)barWidth
{
NSUInteger barCount = [[self.chartDataDictionary allKeys] count];
@@ -298,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];
@@ -355,7 +358,7 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
{
callbackCopy();
}
}
}
}
else
{
@@ -366,14 +369,18 @@ 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:)];
NSArray *chartValues = [[NSMutableArray arrayWithArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
_cachedMinHeight = [[chartValues firstObject] floatValue];
}
return _cachedMinHeight;
@@ -383,29 +390,28 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
{
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:)];
NSArray *chartValues = [[NSMutableArray arrayWithArray:[self.chartDataDictionary allValues]] sortedArrayUsingSelector:@selector(compare:)];
_cachedMaxHeight = [[chartValues lastObject] floatValue];
}
return _cachedMaxHeight;
}
- (CGFloat)mininumValue
- (CGFloat)minimumValue
{
if ([super mininumValue] == kJBChartViewUndefinedMinimumValue)
if ([self hasMinimumValue])
{
return self.cachedMinHeight;
return fminf(self.cachedMinHeight, [super minimumValue]);
}
return [super mininumValue];
return self.cachedMinHeight;
}
- (CGFloat)maximumValue
{
if ([super maximumValue] == kJBChartViewUndefinedMaximumValue)
if ([self hasMaximumValue])
{
return self.cachedMaxHeight;
return fmaxf(self.cachedMaxHeight, [super maximumValue]);
}
return [super maximumValue];
return self.cachedMaxHeight;
}
#pragma mark - Touch Helpers
+19 -4
View File
@@ -9,8 +9,6 @@
#import <Foundation/Foundation.h>
extern CGFloat const kJBChartViewDefaultAnimationDuration;
extern CGFloat const kJBChartViewUndefinedMinimumValue; // helper for undefined min/max values
extern CGFloat const kJBChartViewUndefinedMaximumValue;
/**
* At a minimum, a chart can support two states, along with animations to-and-from.
@@ -43,7 +41,10 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
/**
* The minimum and maxmimum values of the chart.
* If no value(s) are supplied, the min and max values of the chart's data source are used.
* If no value(s) are supplied:
*
* minimumValue = chart's data source min value.
* maxmimumValue = chart's data source max value.
*
* If value(s) are supplied, they must be >= 0, otherwise an assertion will be thrown.
* The min/max values are clamped to the ceiling and floor of the actual min/max values of the chart's data source;
@@ -51,9 +52,13 @@ typedef NS_ENUM(NSInteger, JBChartViewState){
*
* For min/max modifications to take effect, reloadData must be called.
*/
@property (nonatomic, assign) CGFloat mininumValue;
@property (nonatomic, assign) CGFloat minimumValue;
@property (nonatomic, assign) CGFloat maximumValue;
// reset to default (chart's data source min & max value)
- (void)resetMinimumValue;
- (void)resetMaximumValue;
/**
* Charts can either be expanded or contracted.
* By default, a chart should be expanded on initialization.
@@ -66,6 +71,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.
*
+49 -11
View File
@@ -8,15 +8,21 @@
#import "JBChartView.h"
// Numerics
CGFloat const kJBChartViewDefaultAnimationDuration = 0.25f;
CGFloat const kJBChartViewUndefinedMinimumValue = -1.0f;
CGFloat const kJBChartViewUndefinedMaximumValue = -1.0f;
// Color (JBChartSelectionView)
static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
@interface JBChartView ()
@property (nonatomic, assign) BOOL hasMaximumValue;
@property (nonatomic, assign) BOOL hasMinimumValue;
// Construction
- (void)constructChartView;
// Validation
- (void)validateHeaderAndFooterHeights;
@end
@@ -25,14 +31,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 +56,13 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
return [self initWithFrame:CGRectZero];
}
#pragma mark - Construction
- (void)constructChartView
{
self.clipsToBounds = YES;
}
#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];
@@ -112,16 +138,28 @@ static UIColor *kJBChartVerticalSelectionViewDefaultBgColor = nil;
[self setState:state animated:NO];
}
- (void)setMininumValue:(CGFloat)mininumValue
- (void)setMinimumValue:(CGFloat)minimumValue
{
NSAssert(mininumValue >= 0, @"JBChartView // the minimumValue must be >= 0.");
_mininumValue = mininumValue;
NSAssert(minimumValue >= 0, @"JBChartView // the minimumValue must be >= 0.");
_minimumValue = minimumValue;
_hasMinimumValue = YES;
}
- (void)setMaximumValue:(CGFloat)maximumValue
{
NSAssert(maximumValue >= 0, @"JBChartView // the maximumValue must be >= 0.");
_maximumValue = maximumValue;
_hasMaximumValue = YES;
}
- (void)resetMinimumValue
{
_hasMinimumValue = NO; // clears min
}
- (void)resetMaximumValue
{
_hasMaximumValue = NO; // clears max
}
@end
Regular → Executable
+61 -4
View File
@@ -70,7 +70,8 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
* Occurs whenever there is a touch gesture on the chart (chart must be expanded).
* The horizontal index is the closest index to the touch point & is clamped to it's max/min value if it moves outside of the view's bounds.
* The lineIndex remains constant until the line is unselected and will be highlighted using the (optional) selectionColorForLineAtLineIndex: protocol.
* Futhermore, all other lines that aren't selected will be dimmed to 50% opacity throughout the duration of the touch/move.
* Futhermore, all other lines that aren't selected will be dimmed to 20%% opacity throughout the duration of the touch/move. Any dotted line that isn't the
* primary selection will have it's dots dimmed to hidden (to avoid transparency issues).
*
* @param lineChartView A line chart object informing the delegate about the new selection.
* @param lineIndex An index number identifying the closest line in the chart to the current touch
@@ -126,6 +127,21 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*/
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns the color of a particular dot in a 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: black color.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).point.
* @param lineIndex An index number identifying a line in the chart.
*
* @return The color to be used to color a dot within a dotted line in the chart.
*/
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
/**
* Returns the width of particular line at lineIndex within the chart.
*
@@ -138,6 +154,33 @@ 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 width of the (vertical) selection view to be overlayed on the chart during touch events.
* The property showsVerticalSelection must be YES for the width to apply. The width is clamped to the
* maxmimum width of the chart's bounds.
*
* Default: 20px.
*
* @param lineChartView The line chart object requesting this information.
*
* @return The width of the selection view used during chart selections.
*/
- (CGFloat)verticalSelectionWidthForLineChartView:(JBLineChartView *)lineChartView;
/**
* 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
@@ -147,7 +190,7 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*
* @param lineChartView The line chart object requesting this information.
*
* @return The color to be used on chart selections.
* @return The color of the selection view used during chart selections.
*/
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView;
@@ -164,6 +207,20 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
*/
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns the selection color to be overlayed on a line within the chart during touch events.
* The property showsLineSelection must be YES for the color to apply.
*
* Default: white color.
*
* @param lineChartView The line chart object requesting this information.
* @param horizontalIndex The 0-based horizontal index of a selection point (left to right, x-axis).point.
* @param lineIndex An index number identifying a line in the chart.
*
* @return The color to be used to highlight a dot within a dotted line during chart selections.
*/
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
/**
* Returns the line style of a particular line at lineIndex within the chart.
* See JBLineChartViewLineStyle for line style descriptions.
@@ -192,14 +249,14 @@ typedef NS_ENUM(NSInteger, JBLineChartViewLineStyle){
- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
/**
* Returns whether or not a line should be smoothed (rounded end caps and connections).
* Returns whether or not a line should be rendered with curved connections and rounded end caps.
*
* Default: NO
*
* @param lineChartView The line chart object requesting this information.
* @param lineIndex An index number identifying a line in the chart.
*
* @return Whether or not a line should smooth it's ends and connections.
* @return Whether or not a line should smooth it's connections and end caps.
*/
- (BOOL)lineChartView:(JBLineChartView *)lineChartView smoothLineAtLineIndex:(NSUInteger)lineIndex;
Regular → Executable
+191 -86
View File
@@ -22,11 +22,13 @@ typedef NS_ENUM(NSUInteger, JBLineChartHorizontalIndexClamp){
CGFloat static const kJBLineChartLinesViewStrokeWidth = 5.0;
CGFloat static const kJBLineChartLinesViewMiterLimit = -5.0;
CGFloat static const kJBLineChartLinesViewDefaultLinePhase = 1.0f;
CGFloat static const kJBLineChartLinesViewDefaultDimmedOpacity = 0.5f;
CGFloat static const kJBLineChartLinesViewDefaultDimmedOpacity = 0.20f;
NSInteger static const kJBLineChartLinesViewUnselectedLineIndex = -1;
CGFloat static const kJBLineChartLinesViewSmoothThresholdSlope = 0.01f;
NSInteger static const kJBLineChartLinesViewSmoothThresholdVertical = 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)
@@ -44,7 +46,16 @@ static NSArray *kJBLineChartLineViewDefaultDashPattern = nil;
// Colors (JBLineChartView)
static UIColor *kJBLineChartViewDefaultLineColor = nil;
static UIColor *kJBLineChartViewDefaultDotColor = nil;
static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
static UIColor *kJBLineChartViewDefaultDotSelectionColor = nil;
@interface JBChartView (Private)
- (BOOL)hasMaximumValue;
- (BOOL)hasMinimumValue;
@end
@interface JBLineLayer : CAShapeLayer
@@ -113,8 +124,11 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (NSArray *)chartDataForLineChartDotsView:(JBLineChartDotsView*)lineChartDotsView;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForLineAtLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(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;
@@ -142,8 +156,6 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
// View quick accessors
- (CGFloat)normalizedHeightForRawHeight:(CGFloat)rawHeight;
- (CGFloat)availableHeight;
- (CGFloat)minHeight;
- (CGFloat)maxHeight;
- (CGFloat)padding;
- (NSUInteger)dataCount;
@@ -170,7 +182,9 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
if (self == [JBLineChartView class])
{
kJBLineChartViewDefaultLineColor = [UIColor blackColor];
kJBLineChartViewDefaultDotColor = [UIColor blackColor];
kJBLineChartViewDefaultLineSelectionColor = [UIColor whiteColor];
kJBLineChartViewDefaultDotSelectionColor = [UIColor whiteColor];
}
}
@@ -237,7 +251,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
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];
NSAssert([self.dataSource respondsToSelector:@selector(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
for (NSUInteger lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
@@ -246,7 +260,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
NSUInteger dataCount = [self.dataSource lineChartView:self numberOfVerticalValuesAtLineIndex:lineIndex];
NSMutableArray *chartPointData = [NSMutableArray array];
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 rawHeight = [self.delegate lineChartView:self verticalValueForHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
NSAssert(rawHeight >= 0, @"JBLineChartView // delegate function - (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex must return a CGFloat >= 0");
@@ -281,7 +295,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
// Create new line and overlay subviews
self.linesView = [[JBLineChartLinesView alloc] initWithFrame:CGRectOffset(mainViewRect, 0, self.headerView.frame.size.height + self.headerPadding)];
self.linesView.delegate = self;
// Add new lines view
if (self.footerView)
{
@@ -330,7 +344,12 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
self.verticalSelectionView = nil;
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, kJBLineSelectionViewWidth, self.bounds.size.height - self.footerView.frame.size.height)];
CGFloat selectionViewWidth = kJBLineSelectionViewWidth;
if ([self.dataSource respondsToSelector:@selector(verticalSelectionWidthForLineChartView:)])
{
selectionViewWidth = MIN([self.dataSource verticalSelectionWidthForLineChartView:self], self.bounds.size.width);
}
self.verticalSelectionView = [[JBChartVerticalSelectionView alloc] initWithFrame:CGRectMake(0, 0, selectionViewWidth, self.bounds.size.height - self.footerView.frame.size.height)];
self.verticalSelectionView.alpha = 0.0;
self.verticalSelectionView.hidden = !self.showsVerticalSelection;
if ([self.dataSource respondsToSelector:@selector(verticalSelectionColorForLineChartView:)])
@@ -361,14 +380,17 @@ 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
- (CGFloat)normalizedHeightForRawHeight:(CGFloat)rawHeight
{
CGFloat minHeight = [self minHeight];
CGFloat maxHeight = [self maxHeight];
CGFloat minHeight = [self minimumValue];
CGFloat maxHeight = [self maximumValue];
if ((maxHeight - minHeight) <= 0)
{
@@ -383,41 +405,41 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return self.bounds.size.height - self.headerView.frame.size.height - self.footerView.frame.size.height - self.headerPadding;
}
- (CGFloat)minHeight
{
if (self.mininumValue != kJBChartViewUndefinedMinimumValue)
{
return MIN(self.mininumValue, self.cachedMinHeight);
}
return self.cachedMinHeight;
}
- (CGFloat)maxHeight
{
if (self.maximumValue != kJBChartViewUndefinedMaximumValue)
{
return MAX(self.maximumValue, self.cachedMaxHeight);
}
return self.cachedMaxHeight;
}
- (CGFloat)padding
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:widthForLineAtLineIndex:)])
CGFloat maxLineWidth = 0.0f;
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(numberOfLinesInLineChartView:)], @"JBLineChartView // dataSource must implement - (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView");
CGFloat maxWidth = 0.0f;
for (int lineIndex=0; lineIndex<[self.dataSource numberOfLinesInLineChartView:self]; lineIndex++)
BOOL showsDots = NO;
if ([self.dataSource respondsToSelector:@selector(lineChartView:showsDotsForLineAtLineIndex:)])
{
CGFloat lineWidth = [self.dataSource lineChartView:self widthForLineAtLineIndex:lineIndex];
if (lineWidth > maxWidth)
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:)])
{
maxWidth = lineWidth;
dotRadius = [self.dataSource lineChartView:self dotRadiusForLineAtLineIndex:lineIndex];
}
}
return ceil(maxWidth * 0.5);
CGFloat currentMaxLineWidth = MAX(dotRadius, lineWidth);
if (currentMaxLineWidth > maxLineWidth)
{
maxLineWidth = currentMaxLineWidth;
}
}
return ceil(kJBLineChartLinesViewStrokeWidth * 0.5);
return ceil(maxLineWidth * 0.5);
}
- (NSUInteger)dataCount
@@ -475,15 +497,6 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return [self padding];
}
- (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:smoothLineAtLineIndex:)])
{
return [self.dataSource lineChartView:self smoothLineAtLineIndex:lineIndex];
}
return NO;
}
- (JBLineChartViewLineStyle)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView lineStyleForLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:lineStyleForLineAtLineIndex:)])
@@ -493,6 +506,15 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return JBLineChartViewLineStyleSolid;
}
- (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:smoothLineAtLineIndex:)])
{
return [self.dataSource lineChartView:self smoothLineAtLineIndex:lineIndex];
}
return NO;
}
#pragma mark - JBLineChartDotsViewDelegate
- (NSArray *)chartDataForLineChartDotsView:(JBLineChartDotsView*)lineChartDotsView
@@ -509,6 +531,15 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return kJBLineChartViewDefaultLineColor;
}
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:colorForDotAtHorizontalIndex:atLineIndex:)])
{
return [self.dataSource lineChartView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
return kJBLineChartViewDefaultDotColor;
}
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:selectionColorForLineAtLineIndex:)])
@@ -518,6 +549,15 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return kJBLineChartViewDefaultLineSelectionColor;
}
- (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:selectionColorForDotAtHorizontalIndex:atLineIndex:)])
{
return [self.dataSource lineChartView:self selectionColorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
return kJBLineChartViewDefaultDotSelectionColor;
}
- (CGFloat)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView widthForLineAtLineIndex:(NSUInteger)lineIndex
{
if ([self.dataSource respondsToSelector:@selector(lineChartView:widthForLineAtLineIndex:)])
@@ -527,6 +567,18 @@ 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];
@@ -543,9 +595,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)
{
@@ -570,13 +622,13 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
} completion:^(BOOL finished) {
[UIView animateWithDuration:kJBLineChartViewStateAnimationDuration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
adjustViewFrames();
} completion:^(BOOL finished) {
} completion:^(BOOL adjustFinished) {
if (callback)
{
callback();
}
}];
}];
}];
[UIView animateWithDuration:kJBLineChartViewStateAnimationDuration delay:(self.state == JBChartViewStateExpanded) ? kJBLineChartViewStateAnimationDelay : 0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
adjustViewAlphas();
} completion:nil];
@@ -600,6 +652,11 @@ 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
@@ -654,22 +711,22 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
return _cachedMaxHeight;
}
- (CGFloat)mininumValue
- (CGFloat)minimumValue
{
if ([super mininumValue] == kJBChartViewUndefinedMinimumValue)
if ([self hasMinimumValue])
{
return self.cachedMinHeight;
return fminf(self.cachedMinHeight, [super minimumValue]);
}
return [super mininumValue];
return self.cachedMinHeight;
}
- (CGFloat)maximumValue
{
if ([super maximumValue] == kJBChartViewUndefinedMaximumValue)
if ([self hasMaximumValue])
{
return self.cachedMaxHeight;
return fmaxf(self.cachedMaxHeight, [super maximumValue]);
}
return [super maximumValue];
return self.cachedMaxHeight;
}
#pragma mark - Touch Helpers
@@ -721,8 +778,8 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
- (NSInteger)lineIndexForPoint:(CGPoint)point
{
// Find the horizontal indexes
NSInteger leftHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampLeft];
NSInteger rightHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampRight];
NSUInteger leftHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampLeft];
NSUInteger rightHorizontalIndex = [self horizontalIndexForPoint:point indexClamp:JBLineChartHorizontalIndexClampRight];
// Padding
CGFloat chartPadding = [self padding];
@@ -808,8 +865,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
@@ -849,8 +910,11 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [self clampPoint:[touch locationInView:self.linesView] toBounds:self.linesView.bounds padding:[self padding]];
[self.linesView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
[self.dotsView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
if (self.showsLineSelection)
{
[self.linesView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
[self.dotsView setSelectedLineIndex:[self lineIndexForPoint:touchPoint] animated:YES];
}
[self touchesBeganOrMovedWithTouches:touches];
}
@@ -976,8 +1040,15 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
UIBezierPath *path = [UIBezierPath bezierPath];
path.miterLimit = kJBLineChartLinesViewMiterLimit;
JBLineChartPoint *previousLineChartPoint = nil;
CGFloat previousSlope = 0.0f;
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:smoothLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (BOOL)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView smoothLineAtLineIndex:(NSUInteger)lineIndex");
BOOL smoothLine = [self.delegate lineChartLinesView:self smoothLineAtLineIndex:lineIndex];
NSUInteger index = 0;
for (JBLineChartPoint *lineChartPoint in [lineData sortedArrayUsingSelector:@selector(compare:)])
NSArray *sortedLineData = [lineData sortedArrayUsingSelector:@selector(compare:)];
for (JBLineChartPoint *lineChartPoint in sortedLineData)
{
if (index == 0)
{
@@ -985,9 +1056,37 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
}
else
{
[path addLineToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)))];
JBLineChartPoint *nextLineChartPoint = nil;
if (index != ([lineData count] - 1))
{
nextLineChartPoint = [sortedLineData objectAtIndex:(index + 1)];
}
CGFloat nextSlope = (nextLineChartPoint != nil) ? ((nextLineChartPoint.position.y - lineChartPoint.position.y)) / ((nextLineChartPoint.position.x - lineChartPoint.position.x)) : previousSlope;
CGFloat currentSlope = ((lineChartPoint.position.y - previousLineChartPoint.position.y)) / (lineChartPoint.position.x-previousLineChartPoint.position.x);
BOOL deltaFromNextSlope = ((currentSlope >= (nextSlope + kJBLineChartLinesViewSmoothThresholdSlope)) || (currentSlope <= (nextSlope - kJBLineChartLinesViewSmoothThresholdSlope)));
BOOL deltaFromPreviousSlope = ((currentSlope >= (previousSlope + kJBLineChartLinesViewSmoothThresholdSlope)) || (currentSlope <= (previousSlope - kJBLineChartLinesViewSmoothThresholdSlope)));
BOOL deltaFromPreviousY = (lineChartPoint.position.y >= previousLineChartPoint.position.y + kJBLineChartLinesViewSmoothThresholdVertical) || (lineChartPoint.position.y <= previousLineChartPoint.position.y - kJBLineChartLinesViewSmoothThresholdVertical);
if (smoothLine && deltaFromNextSlope && deltaFromPreviousSlope && deltaFromPreviousY)
{
CGFloat deltaX = lineChartPoint.position.x - previousLineChartPoint.position.x;
CGFloat controlPointX = previousLineChartPoint.position.x + (deltaX / 2);
CGPoint controlPoint1 = CGPointMake(controlPointX, previousLineChartPoint.position.y);
CGPoint controlPoint2 = CGPointMake(controlPointX, lineChartPoint.position.y);
[path addCurveToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y))) controlPoint1:controlPoint1 controlPoint2:controlPoint2];
}
else
{
[path addLineToPoint:CGPointMake(lineChartPoint.position.x, fmin(self.bounds.size.height - padding, fmax(padding, lineChartPoint.position.y)))];
}
previousSlope = currentSlope;
}
previousLineChartPoint = lineChartPoint;
index++;
}
@@ -1004,9 +1103,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:colorForLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView colorForLineAtLineIndex:(NSUInteger)lineIndex");
shapeLayer.strokeColor = [self.delegate lineChartLinesView:self colorForLineAtLineIndex:lineIndex].CGColor;
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:smoothLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView colorForLineAtLineIndex:(NSUInteger)lineIndex");
BOOL smoothLine = [self.delegate lineChartLinesView:self smoothLineAtLineIndex:lineIndex];
if (smoothLine)
if (smoothLine == YES)
{
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.lineJoin = kCALineJoinRound;
@@ -1043,12 +1140,14 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
_selectedLineIndex = selectedLineIndex;
__weak JBLineChartLinesView* weakSelf = self;
dispatch_block_t adjustLines = ^{
for (CALayer *layer in [self.layer sublayers])
for (CALayer *layer in [weakSelf.layer sublayers])
{
if ([layer isKindOfClass:[JBLineLayer class]])
{
if (((JBLineLayer *)layer).tag == _selectedLineIndex)
if (((NSInteger)((JBLineLayer *)layer).tag) == weakSelf.selectedLineIndex)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:selectedColorForLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex");
((JBLineLayer *)layer).strokeColor = [self.delegate lineChartLinesView:self selectedColorForLineAtLineIndex:((JBLineLayer *)layer).tag].CGColor;
@@ -1058,7 +1157,7 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartLinesView:colorForLineAtLineIndex:)], @"JBLineChartLinesView // delegate must implement - (UIColor *)lineChartLinesView:(JBLineChartLinesView *)lineChartLinesView colorForLineAtLineIndex:(NSUInteger)lineIndex");
((JBLineLayer *)layer).strokeColor = [self.delegate lineChartLinesView:self colorForLineAtLineIndex:((JBLineLayer *)layer).tag].CGColor;
((JBLineLayer *)layer).opacity = (_selectedLineIndex == kJBLineChartLinesViewUnselectedLineIndex) ? 1.0f : kJBLineChartLinesViewDefaultDimmedOpacity;
((JBLineLayer *)layer).opacity = (weakSelf.selectedLineIndex == kJBLineChartLinesViewUnselectedLineIndex) ? 1.0f : kJBLineChartLinesViewDefaultDimmedOpacity;
}
}
}
@@ -1151,20 +1250,22 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
if ([self.delegate lineChartDotsView:self showsDotsForLineAtLineIndex:lineIndex]) // line at index contains dots
{
NSMutableArray *mutableDotViews = [NSMutableArray array];
NSUInteger horizontalIndex = 0;
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 - 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];
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
[mutableDotViews addObject:dotView];
[self addSubview:dotView];
horizontalIndex++;
}
[mutableDotViewsDict setObject:[NSArray arrayWithArray:mutableDotViews] forKey:[NSNumber numberWithInteger:lineIndex]];
}
@@ -1179,26 +1280,30 @@ static UIColor *kJBLineChartViewDefaultLineSelectionColor = nil;
{
_selectedLineIndex = selectedLineIndex;
__weak JBLineChartDotsView* weakSelf = self;
dispatch_block_t adjustDots = ^{
[self.dotViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[weakSelf.dotViewsDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSUInteger horizontalIndex = 0;
for (JBLineChartDotView *dotView in (NSArray *)obj)
{
if ([key isKindOfClass:[NSNumber class]])
{
NSUInteger lineIndex = [((NSNumber *)key) intValue];
NSInteger lineIndex = [((NSNumber *)key) intValue];
if (_selectedLineIndex == lineIndex)
if (weakSelf.selectedLineIndex == lineIndex)
{
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:selectedColorForLineAtLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForLineAtLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self selectedColorForLineAtLineIndex:lineIndex];
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:selectedColorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView selectedColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self selectedColorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
}
else
{
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];
dotView.alpha = (_selectedLineIndex == kJBLineChartDotsViewUnselectedLineIndex) ? 1.0f : kJBLineChartLinesViewDefaultDimmedOpacity;
NSAssert([self.delegate respondsToSelector:@selector(lineChartDotsView:colorForDotAtHorizontalIndex:atLineIndex:)], @"JBLineChartDotsView // delegate must implement - (UIColor *)lineChartDotsView:(JBLineChartDotsView *)lineChartDotsView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex");
dotView.backgroundColor = [self.delegate lineChartDotsView:self colorForDotAtHorizontalIndex:horizontalIndex atLineIndex:lineIndex];
dotView.alpha = (weakSelf.selectedLineIndex == kJBLineChartDotsViewUnselectedLineIndex) ? 1.0f : 0.0f; // hide dots on off-selection
}
}
horizontalIndex++;
}
}];
};
@@ -1,17 +1,19 @@
Pod::Spec.new do |s|
s.name = "JBChartView"
s.version = "2.1.2"
s.version = "2.5.5"
s.summary = "Jawbone's iOS-based charting library for both line and bar graphs."
s.homepage = "https://github.com/Jawbone/JBChartView"
s.screenshot = "https://raw.github.com/Jawbone/JBChartView/master/Screenshots/main.png"
s.license = { :type => 'Apache', :file => 'LICENSE' }
s.author = { "Terry Worona" => "tworona@jawbone.com" }
s.source = {
:git => "https://github.com/Jawbone/JBChartView.git",
:tag => "v2.1.2"
:tag => "v2.5.5"
}
s.platform = :ios, '7.0'
s.source_files = 'Classes', 'Classes/**/*.{h,m}'
s.source_files = 'Classes/**/*.{h,m}'
s.requires_arc = true
end
@@ -21,7 +21,7 @@ CGFloat const kJBBarChartViewControllerChartHeaderHeight = 80.0f;
CGFloat const kJBBarChartViewControllerChartHeaderPadding = 10.0f;
CGFloat const kJBBarChartViewControllerChartFooterHeight = 25.0f;
CGFloat const kJBBarChartViewControllerChartFooterPadding = 5.0f;
CGFloat const kJBBarChartViewControllerBarPadding = 1;
NSUInteger kJBBarChartViewControllerBarPadding = 1;
NSInteger const kJBBarChartViewControllerNumBars = 12;
NSInteger const kJBBarChartViewControllerMaxBarHeight = 10;
NSInteger const kJBBarChartViewControllerMinBarHeight = 5;
@@ -107,6 +107,7 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
self.barChartView.delegate = self;
self.barChartView.dataSource = self;
self.barChartView.headerPadding = kJBBarChartViewControllerChartHeaderPadding;
self.barChartView.minimumValue = 0.0f;
self.barChartView.backgroundColor = kJBColorBarChartBackground;
JBChartHeaderView *headerView = [[JBChartHeaderView alloc] initWithFrame:CGRectMake(kJBBarChartViewControllerChartPadding, ceil(self.view.bounds.size.height * 0.5) - ceil(kJBBarChartViewControllerChartHeaderHeight * 0.5), self.view.bounds.size.width - (kJBBarChartViewControllerChartPadding * 2), kJBBarChartViewControllerChartHeaderHeight)];
@@ -155,11 +156,9 @@ NSString * const kJBBarChartViewControllerNavButtonViewKey = @"view";
return kJBBarChartViewControllerBarPadding;
}
- (UIView *)barChartView:(JBBarChartView *)barChartView barViewAtIndex:(NSUInteger)index
- (UIColor *)barChartView:(JBBarChartView *)barChartView colorForBarViewAtIndex:(NSUInteger)index
{
UIView *barView = [[UIView alloc] init];
barView.backgroundColor = (index % 2 == 0) ? kJBColorBarChartBarBlue : kJBColorBarChartBarGreen;
return barView;
return (index % 2 == 0) ? kJBColorBarChartBarBlue : kJBColorBarChartBarGreen;
}
- (UIColor *)barSelectionColorForBarChartView:(JBBarChartView *)barChartView
@@ -211,11 +211,21 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidLineColor: kJBColorLineChartDefaultDashedLineColor;
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidLineColor: kJBColorLineChartDefaultDashedLineColor;
}
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView widthForLineAtLineIndex:(NSUInteger)lineIndex
{
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];
@@ -226,6 +236,11 @@ NSString * const kJBLineChartViewControllerNavButtonViewKey = @"view";
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidSelectedLineColor: kJBColorLineChartDefaultDashedSelectedLineColor;
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? kJBColorLineChartDefaultSolidSelectedLineColor: kJBColorLineChartDefaultDashedSelectedLineColor;
}
- (JBLineChartViewLineStyle)lineChartView:(JBLineChartView *)lineChartView lineStyleForLineAtLineIndex:(NSUInteger)lineIndex
{
return (lineIndex == JBLineChartLineSolid) ? JBLineChartViewLineStyleSolid : JBLineChartViewLineStyleDashed;
@@ -10,7 +10,6 @@
@interface JBBarChartFooterView : UIView
@property (nonatomic, strong) UIColor *footerBackgroundColor; // footer background (default = black)
@property (nonatomic, assign) CGFloat padding; // label left & right padding (default = 4.0)
@property (nonatomic, readonly) UILabel *leftLabel;
@property (nonatomic, readonly) UILabel *rightLabel;
@@ -10,30 +10,12 @@
// Numerics
CGFloat const kJBBarChartFooterPolygonViewDefaultPadding = 4.0f;
CGFloat const kJBBarChartFooterPolygonViewArrowHeight = 8.0f;
CGFloat const kJBBarChartFooterPolygonViewArrowWidth = 16.0f;
// Colors
static UIColor *kJBBarChartFooterPolygonViewDefaultBackgroundColor = nil;
static UIColor *kJBBarChartFooterViewDefaultBackgroundColor = nil;
@protocol JBBarChartFooterPolygonViewDelegate;
@interface JBBarChartFooterView ()
@interface JBBarChartFooterPolygonView : UIView
@property (nonatomic, weak) id<JBBarChartFooterPolygonViewDelegate> delegate;
@end
@protocol JBBarChartFooterPolygonViewDelegate <NSObject>
- (UIColor *)backgroundColorForChartFooterPolygonView:(JBBarChartFooterPolygonView *)chartFooterPolygonView;
- (CGFloat)paddingForChartFooterPolygonView:(JBBarChartFooterPolygonView *)chartFooterPolygonView;
@end
@interface JBBarChartFooterView () <JBBarChartFooterPolygonViewDelegate>
@property (nonatomic, strong) JBBarChartFooterPolygonView *polygonView;
@property (nonatomic, strong) UILabel *leftLabel;
@property (nonatomic, strong) UILabel *rightLabel;
@@ -47,7 +29,7 @@ static UIColor *kJBBarChartFooterPolygonViewDefaultBackgroundColor = nil;
{
if (self == [JBBarChartFooterView class])
{
kJBBarChartFooterPolygonViewDefaultBackgroundColor = kJBColorBarChartControllerBackground;
kJBBarChartFooterViewDefaultBackgroundColor = kJBColorBarChartControllerBackground;
}
}
@@ -56,15 +38,10 @@ static UIColor *kJBBarChartFooterPolygonViewDefaultBackgroundColor = nil;
self = [super initWithFrame:frame];
if (self)
{
self.backgroundColor = kJBBarChartFooterPolygonViewDefaultBackgroundColor;
self.backgroundColor = kJBBarChartFooterViewDefaultBackgroundColor;
_footerBackgroundColor = kJBBarChartFooterPolygonViewDefaultBackgroundColor;
_padding = kJBBarChartFooterPolygonViewDefaultPadding;
_polygonView = [[JBBarChartFooterPolygonView alloc] initWithFrame:CGRectMake(self.bounds.origin.x, self.bounds.origin.y - kJBBarChartFooterPolygonViewArrowHeight, self.bounds.size.width, self.bounds.size.height + kJBBarChartFooterPolygonViewArrowHeight)];
_polygonView.delegate = self;
[self addSubview:_polygonView];
_leftLabel = [[UILabel alloc] init];
_leftLabel.adjustsFontSizeToFitWidth = YES;
_leftLabel.font = kJBFontFooterLabel;
@@ -100,95 +77,4 @@ static UIColor *kJBBarChartFooterPolygonViewDefaultBackgroundColor = nil;
self.rightLabel.frame = CGRectMake(CGRectGetMaxX(_leftLabel.frame), yOffset, width, self.bounds.size.height);
}
#pragma mark - JBBarChartFooterPolygonViewDelegate
- (UIColor *)backgroundColorForChartFooterPolygonView:(JBBarChartFooterPolygonView *)chartFooterPolygonView
{
return self.footerBackgroundColor;
}
- (CGFloat)paddingForChartFooterPolygonView:(JBBarChartFooterPolygonView *)chartFooterPolygonView
{
return self.padding;
}
@end
@implementation JBBarChartFooterPolygonView
#pragma mark - Alloc/Init
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.backgroundColor = [UIColor clearColor];
}
return self;
}
#pragma mark - Drawing
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
// Background gradient
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSAssert([self.delegate respondsToSelector:@selector(backgroundColorForChartFooterPolygonView:)], @"JBChartFooterPolygonView // delegate must implement - (UIColor *)backgroundColorForChartFooterPolygonView");
NSAssert([self.delegate respondsToSelector:@selector(paddingForChartFooterPolygonView:)], @"JBChartFooterPolygonView // delegate must implement - (CGFloat)paddingForChartFooterPolygonView");
UIColor *bgColor = [self.delegate backgroundColorForChartFooterPolygonView:self];
NSArray *colors = @[(__bridge id)bgColor.CGColor, (__bridge id)bgColor.CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
// Polygon shape
CGFloat xOffset = self.bounds.origin.x;
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.height;
CGFloat padding = [self.delegate paddingForChartFooterPolygonView:self];
NSArray *polygonPoints = @[[NSValue valueWithCGPoint:CGPointMake(xOffset, height)],
[NSValue valueWithCGPoint:CGPointMake(xOffset, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(xOffset + padding, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(xOffset + padding + ceil(kJBBarChartFooterPolygonViewArrowWidth * 0.5), 0)],
[NSValue valueWithCGPoint:CGPointMake(xOffset + padding + kJBBarChartFooterPolygonViewArrowWidth, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(width - padding - kJBBarChartFooterPolygonViewArrowWidth, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(width - padding - ceil(kJBBarChartFooterPolygonViewArrowWidth * 0.5), 0.0)],
[NSValue valueWithCGPoint:CGPointMake(width - padding, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(width, kJBBarChartFooterPolygonViewArrowHeight)],
[NSValue valueWithCGPoint:CGPointMake(width, height)],
[NSValue valueWithCGPoint:CGPointMake(xOffset, height)]];
// Draw polygon
NSValue *pointValue = polygonPoints[0];
CGContextSaveGState(context);
{
NSInteger index = 0;
for (pointValue in polygonPoints)
{
CGPoint point = [pointValue CGPointValue];
if (index == 0)
{
CGContextMoveToPoint(context, point.x, point.y);
}
else
{
CGContextAddLineToPoint(context, point.x, point.y);
}
index++;
}
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)), CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)), 0);
}
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
@end
+39 -5
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.2'
pod 'JBChartView', '~> 2.5.5'
### The Old School Way
@@ -63,14 +63,14 @@ To initialize a <i>JBBarChartView</i>, you only need a few lines of code (see be
At a minimum, you need to inform the data source how many bars are in the chart:
- (NSInteger)numberOfBarsInBarChartView:(JBBarChartView *)barChartView
- (NSUInteger)numberOfBarsInBarChartView:(JBBarChartView *)barChartView
{
return ...; // number of bars in chart
}
Secondly, you need to inform the delegate the height of each bar (automatically normalized across the entire chart):
- (CGFloat)barChartView:(JBBarChartView *)barChartView heightForBarViewAtAtIndex:(NSInteger)index
- (CGFloat)barChartView:(JBBarChartView *)barChartView heightForBarViewAtAtIndex:(NSUInteger)index
{
return ...; // height of bar at index
}
@@ -140,6 +140,10 @@ By default, a chart's bars will be black and flat. They can be customized by sup
{
return ...; // color of line in chart
}
If you don't require a custom UIView, simply supply a color for the bar instead:
- (UIColor *)barChartView:(JBBarChartView *)barChartView colorForBarViewAtIndex:(NSUInteger)index;
Furthermore, the color of the selection bar (on touch events) can be customized via the <i>optional</i> protocol:
@@ -181,13 +185,18 @@ The color, width and style of each line in the chart can be customized via the <
return ...; // style of line in chart
}
Furthermore, the color of the selection bar and line can be customized via the <i>optional</i> protocols:
Furthermore, the color and width of the selection view along with the color of the selected line can be customized via the <i>optional</i> protocols:
- (UIColor *)verticalSelectionColorForLineChartView:(JBLineChartView *)lineChartView
{
return ...; // color of selection view
}
- (CGFloat)verticalSelectionWidthForLineChartView:(JBLineChartView *)lineChartView
{
return ...; // width of selection view
}
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForLineAtLineIndex:(NSUInteger)lineIndex
{
return ...; // color of selected line
@@ -196,8 +205,18 @@ 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 (default 3x the line width), implement:
- (CGFloat)lineChartView:(JBLineChartView *)lineChartView dotRadiusForLineAtLineIndex:(NSUInteger)lineIndex;
As well, by default, each line will have squared off end caps and connection points. To enable line smoothing:
To customize the color of each dot during selection and non-selection events (default is white and black respectively), implement:
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView colorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
- (UIColor *)lineChartView:(JBLineChartView *)lineChartView selectionColorForDotAtHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
As well, by default, each line will have squared off end caps and connection points. To enable rounded connections and end caps:
- (BOOL)lineChartView:(JBLineChartView *)lineChartView smoothLineAtLineIndex:(NSUInteger)lineIndex;
@@ -214,6 +233,21 @@ Lastly, a line chart's selection events are delegated back via:
}
The <b>touchPoint</b> is especially important as it allows you to add custom elements to your chart during selection events. Refer to the demo project (<b>JBLineChartViewController</b>) to see how a tooltip can be used to display additional information during selection events.
## Minimum & Maximum Values
By default, a chart's minimum and maximum values are equal to the min and max supplied by the dataSource. You can override either value via:
- (void)setMinimumValue:(CGFloat)minimumValue;
- (void)setMaximumValue:(CGFloat)maximumValue;
If value(s) are supplied, they must be >= 0, otherwise an assertion will be thrown. To reset the values back to their original defaults:
- (void)resetMinimumValue;
- (void)resetMaximumValue;
The min/max values are clamped to the ceiling and floor of the actual min/max values of the chart's data source; for example, if a maximumValue of 20 is supplied & the chart's actual max is 100, then 100 will be used. For min/max modifications to take effect, reloadData must be called.
## License