Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eacc211dbd | |||
| 641fb7f5fa | |||
| 28a660c57f |
@@ -1,5 +1,17 @@
|
||||
# Change Log
|
||||
|
||||
## [Unreleased](https://github.com/Jawbone/JBChartView/tree/HEAD)
|
||||
|
||||
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v3.0.6...HEAD)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Directions not set in UIViewController [\#199](https://github.com/Jawbone/JBChartView/issues/199)
|
||||
- Many Line Charts in Table View [\#198](https://github.com/Jawbone/JBChartView/issues/198)
|
||||
|
||||
## [v3.0.6](https://github.com/Jawbone/JBChartView/tree/v3.0.6) (2016-01-21)
|
||||
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v3.0.5...v3.0.6)
|
||||
|
||||
## [v3.0.5](https://github.com/Jawbone/JBChartView/tree/v3.0.5) (2016-01-20)
|
||||
[Full Changelog](https://github.com/Jawbone/JBChartView/compare/v3.0.4...v3.0.5)
|
||||
|
||||
|
||||
+143
-145
@@ -111,6 +111,10 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
|
||||
- (void)construct
|
||||
{
|
||||
_chartData = [NSArray array];
|
||||
_barViews = [NSArray array];
|
||||
_cachedBarViewHeights = [NSArray array];
|
||||
|
||||
_showsVerticalSelection = YES;
|
||||
_cachedMinHeight = kJBBarChartViewUndefinedCachedHeight;
|
||||
_cachedMaxHeight = kJBBarChartViewUndefinedCachedHeight;
|
||||
@@ -246,122 +250,122 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
|
||||
__weak JBBarChartView* weakSelf = self;
|
||||
|
||||
if (shouldAnimate)
|
||||
{
|
||||
self.cachedBarViewHeights = nil;
|
||||
__block NSUInteger barViewsCount = [self.barViews count];
|
||||
|
||||
dispatch_block_t updateExistingBarViewsBlock = ^{
|
||||
__block CGFloat xOffset = 0;
|
||||
[weakSelf.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
CGFloat height = [weakSelf normalizedHeightForRawHeight:(NSNumber *)obj];
|
||||
if (index < [weakSelf.barViews count])
|
||||
{
|
||||
// Update bar
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], height);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.bounds.size.height - height - weakSelf.footerView.frame.size.height, [weakSelf barWidth], height);
|
||||
}
|
||||
xOffset += ([weakSelf barWidth] + weakSelf.barPadding);
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t preAddBarViewsBlock = ^{
|
||||
__block CGFloat xOffset = 0;
|
||||
[self.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
if (index >= barViewsCount)
|
||||
{
|
||||
// Create bar
|
||||
UIView *barView = [weakSelf createBarViewForIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, self.bounds.size.height, [weakSelf barWidth], 0.0f);
|
||||
}
|
||||
|
||||
// Update stored view
|
||||
weakSelf.barViews = [NSArray arrayWithArray:[weakSelf.barViews arrayByAddingObject:barView]];
|
||||
|
||||
// Add bar to view
|
||||
[weakSelf insertBarView:barView];
|
||||
}
|
||||
xOffset += ([weakSelf barWidth] + weakSelf.barPadding);
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t postAddBarViewsBlock = ^{
|
||||
[self.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
if (index >= barViewsCount)
|
||||
{
|
||||
CGFloat height = [weakSelf normalizedHeightForRawHeight:(NSNumber *)obj];
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], height);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, self.bounds.size.height - height - weakSelf.footerView.frame.size.height, [weakSelf barWidth], height);
|
||||
}
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t preRemoveBarViewsBlock = ^{
|
||||
|
||||
// Move existing (removed) bars down
|
||||
for (NSUInteger index=[weakSelf.chartData count]; index<[weakSelf.barViews count]; index++)
|
||||
self.cachedBarViewHeights = nil;
|
||||
__block NSUInteger barViewsCount = [self.barViews count];
|
||||
|
||||
dispatch_block_t updateExistingBarViewsBlock = ^{
|
||||
__block CGFloat xOffset = 0;
|
||||
[weakSelf.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
CGFloat height = [weakSelf normalizedHeightForRawHeight:(NSNumber *)obj];
|
||||
if (index < [weakSelf.barViews count])
|
||||
{
|
||||
// Update bar
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, 0.0f);
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], height);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height, barView.frame.size.width, barView.frame.size.height);
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.bounds.size.height - height - weakSelf.footerView.frame.size.height, [weakSelf barWidth], height);
|
||||
}
|
||||
xOffset += ([weakSelf barWidth] + weakSelf.barPadding);
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t preAddBarViewsBlock = ^{
|
||||
__block CGFloat xOffset = 0;
|
||||
[self.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
if (index >= barViewsCount)
|
||||
{
|
||||
// Create bar
|
||||
UIView *barView = [weakSelf createBarViewForIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(xOffset, self.bounds.size.height, [weakSelf barWidth], 0.0f);
|
||||
}
|
||||
|
||||
// Update stored view
|
||||
weakSelf.barViews = [NSArray arrayWithArray:[weakSelf.barViews arrayByAddingObject:barView]];
|
||||
|
||||
// Add bar to view
|
||||
[weakSelf insertBarView:barView];
|
||||
}
|
||||
xOffset += ([weakSelf barWidth] + weakSelf.barPadding);
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t postAddBarViewsBlock = ^{
|
||||
[self.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
if (index >= barViewsCount)
|
||||
{
|
||||
CGFloat height = [weakSelf normalizedHeightForRawHeight:(NSNumber *)obj];
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, [weakSelf barWidth], height);
|
||||
}
|
||||
else
|
||||
{
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, self.bounds.size.height - height - weakSelf.footerView.frame.size.height, [weakSelf barWidth], height);
|
||||
}
|
||||
}
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
dispatch_block_t preRemoveBarViewsBlock = ^{
|
||||
|
||||
dispatch_block_t postRemoveBarViewsBlock = ^{
|
||||
|
||||
// Remove existing (removed) bars
|
||||
for (NSUInteger index=[weakSelf.chartData count]; index<[weakSelf.barViews count]; index++)
|
||||
// Move existing (removed) bars down
|
||||
for (NSUInteger index=[weakSelf.chartData count]; index<[weakSelf.barViews count]; index++)
|
||||
{
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
if (weakSelf.inverted)
|
||||
{
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
[barView removeFromSuperview];
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.headerView.frame.size.height + weakSelf.headerPadding, barView.frame.size.width, 0.0f);
|
||||
}
|
||||
|
||||
// Update bar view collection
|
||||
NSMutableArray *mutableBarViews = [NSMutableArray arrayWithArray:weakSelf.barViews];
|
||||
[mutableBarViews removeObjectsInRange:(NSRange){[weakSelf.chartData count], [weakSelf.barViews count] - [weakSelf.chartData count]}];
|
||||
weakSelf.barViews = [NSArray arrayWithArray:mutableBarViews];
|
||||
};
|
||||
|
||||
dispatch_block_t refreshedCachedBarViewHeightsBlock = ^{
|
||||
NSMutableArray *mutableCachedBarViewHeights = [NSMutableArray arrayWithArray:weakSelf.cachedBarViewHeights];
|
||||
for (UIView *barView in weakSelf.barViews)
|
||||
else
|
||||
{
|
||||
[mutableCachedBarViewHeights addObject:[NSNumber numberWithFloat:barView.frame.size.height]];
|
||||
barView.frame = CGRectMake(barView.frame.origin.x, weakSelf.bounds.size.height, barView.frame.size.width, barView.frame.size.height);
|
||||
}
|
||||
weakSelf.cachedBarViewHeights = [NSArray arrayWithArray:mutableCachedBarViewHeights];
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
dispatch_block_t postRemoveBarViewsBlock = ^{
|
||||
|
||||
/*
|
||||
* New data model equal;
|
||||
* Update existing bars to accomodate new model.
|
||||
*/
|
||||
if ([self.chartData count] == [self.barViews count])
|
||||
// Remove existing (removed) bars
|
||||
for (NSUInteger index=[weakSelf.chartData count]; index<[weakSelf.barViews count]; index++)
|
||||
{
|
||||
UIView *barView = [weakSelf.barViews objectAtIndex:index];
|
||||
[barView removeFromSuperview];
|
||||
}
|
||||
|
||||
// Update bar view collection
|
||||
NSMutableArray *mutableBarViews = [NSMutableArray arrayWithArray:weakSelf.barViews];
|
||||
[mutableBarViews removeObjectsInRange:(NSRange){[weakSelf.chartData count], [weakSelf.barViews count] - [weakSelf.chartData count]}];
|
||||
weakSelf.barViews = [NSArray arrayWithArray:mutableBarViews];
|
||||
};
|
||||
|
||||
dispatch_block_t refreshedCachedBarViewHeightsBlock = ^{
|
||||
NSMutableArray *mutableCachedBarViewHeights = [NSMutableArray arrayWithArray:weakSelf.cachedBarViewHeights];
|
||||
for (UIView *barView in weakSelf.barViews)
|
||||
{
|
||||
[mutableCachedBarViewHeights addObject:[NSNumber numberWithFloat:barView.frame.size.height]];
|
||||
}
|
||||
weakSelf.cachedBarViewHeights = [NSArray arrayWithArray:mutableCachedBarViewHeights];
|
||||
};
|
||||
|
||||
/*
|
||||
* New data model equal;
|
||||
* Update existing bars to accomodate new model.
|
||||
*/
|
||||
if ([self.chartData count] == [self.barViews count])
|
||||
{
|
||||
if (shouldAnimate)
|
||||
{
|
||||
[UIView animateWithDuration:kJBBarChartViewReloadDataAnimationDuration animations:^{
|
||||
updateExistingBarViewsBlock();
|
||||
@@ -370,12 +374,21 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
completionBlock();
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
* New data model greater;
|
||||
* Update existing bars to accomodate new model & add new bars.
|
||||
*/
|
||||
else if ([self.chartData count] > [self.barViews count])
|
||||
else
|
||||
{
|
||||
updateExistingBarViewsBlock();
|
||||
refreshedCachedBarViewHeightsBlock();
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* New data model greater;
|
||||
* Update existing bars to accomodate new model & add new bars.
|
||||
*/
|
||||
else if ([self.chartData count] > [self.barViews count])
|
||||
{
|
||||
if (shouldAnimate)
|
||||
{
|
||||
[UIView animateWithDuration:kJBBarChartViewReloadDataAnimationDuration animations:^{
|
||||
updateExistingBarViewsBlock();
|
||||
@@ -389,12 +402,23 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
/*
|
||||
* New data model less;
|
||||
* Update existing bars to accomodate new model & remove legacy bars.
|
||||
*/
|
||||
else if ([self.chartData count] < [self.barViews count])
|
||||
else
|
||||
{
|
||||
updateExistingBarViewsBlock();
|
||||
preAddBarViewsBlock();
|
||||
postAddBarViewsBlock();
|
||||
refreshedCachedBarViewHeightsBlock();
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* New data model less;
|
||||
* Update existing bars to accomodate new model & remove legacy bars.
|
||||
*/
|
||||
else if ([self.chartData count] < [self.barViews count])
|
||||
{
|
||||
if (shouldAnimate)
|
||||
{
|
||||
[UIView animateWithDuration:kJBBarChartViewReloadDataAnimationDuration animations:^{
|
||||
preRemoveBarViewsBlock();
|
||||
@@ -408,35 +432,14 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove old bars
|
||||
for (UIView *barView in self.barViews)
|
||||
else
|
||||
{
|
||||
[barView removeFromSuperview];
|
||||
preRemoveBarViewsBlock();
|
||||
postRemoveBarViewsBlock();
|
||||
updateExistingBarViewsBlock();
|
||||
refreshedCachedBarViewHeightsBlock();
|
||||
completionBlock();
|
||||
}
|
||||
|
||||
self.cachedBarViewHeights = nil;
|
||||
|
||||
__block CGFloat xOffset = 0;
|
||||
__block NSMutableArray *mutableBarViews = [NSMutableArray array];
|
||||
__block NSMutableArray *mutableCachedBarViewHeights = [NSMutableArray array];
|
||||
[self.chartData enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop) {
|
||||
UIView *barView = [weakSelf createBarViewForIndex:index];
|
||||
|
||||
CGFloat height = [weakSelf normalizedHeightForRawHeight:(NSNumber *)obj];
|
||||
barView.frame = CGRectMake(xOffset, self.bounds.size.height - height - weakSelf.footerView.frame.size.height, [weakSelf barWidth], height);
|
||||
[mutableBarViews addObject:barView];
|
||||
[mutableCachedBarViewHeights addObject:[NSNumber numberWithFloat:height]];
|
||||
|
||||
[weakSelf insertBarView:barView];
|
||||
|
||||
xOffset += ([weakSelf barWidth] + weakSelf.barPadding);
|
||||
index++;
|
||||
}];
|
||||
self.barViews = [NSArray arrayWithArray:mutableBarViews];
|
||||
self.cachedBarViewHeights = [NSArray arrayWithArray:mutableCachedBarViewHeights];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -461,11 +464,6 @@ static UIColor *kJBBarChartViewDefaultBarColor = nil;
|
||||
createSelectionViewBlock();
|
||||
createBarViewsBlock();
|
||||
layoutHeaderAndFooterBlock();
|
||||
|
||||
if (!shouldAnimate)
|
||||
{
|
||||
completionBlock(); // animated versions call this internally
|
||||
}
|
||||
}
|
||||
|
||||
- (void)reloadData
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "JBChartView"
|
||||
s.version = "3.0.5"
|
||||
s.version = "3.0.7"
|
||||
s.summary = "Jawbone's iOS-based charting library for both line and bar graphs."
|
||||
s.homepage = "https://github.com/Jawbone/JBChartView"
|
||||
|
||||
@@ -10,7 +10,7 @@ Pod::Spec.new do |s|
|
||||
s.author = { "Terry Worona" => "tworona@jawbone.com" }
|
||||
s.source = {
|
||||
:git => "https://github.com/Jawbone/JBChartView.git",
|
||||
:tag => "v3.0.5"
|
||||
:tag => "v3.0.7"
|
||||
}
|
||||
|
||||
s.platform = :ios, '6.0'
|
||||
|
||||
Reference in New Issue
Block a user