Skip to content
This repository has been archived by the owner on Dec 2, 2020. It is now read-only.

New TestBed App and multiple bug fixes/cleanups #295

Merged
merged 17 commits into from
Jul 21, 2017
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ osx_image: xcode8.2
xcode_project: Sample Project/SimpleLineChart.xcodeproj
xcode_scheme: SimpleLineChartTests
xcode_sdk: iphonesimulator
script:
- xcodebuild clean build test -project "Sample Project/SimpleLineChart.xcodeproj" -scheme SimpleLineChartTests -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 7" ONLY_ACTIVE_ARCH=NO
4 changes: 2 additions & 2 deletions Classes/BEMAverageLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


/// A line displayed horizontally across the graph at the average y-value
@interface BEMAverageLine : NSObject
@interface BEMAverageLine : NSObject <NSCoding>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Love that BEMAverageLine is now also NSCoding compliant.



/// When set to YES, an average line will be displayed on the line graph
Expand All @@ -35,7 +35,7 @@


/// Dash pattern for the average line
@property (strong, nonatomic, nullable) NSArray *dashPattern;
@property (strong, nonatomic, nullable) NSArray <NSNumber *> *dashPattern;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Love these changes! Perfect!



//Label for average line in y axis. Default is blank.
Expand Down
44 changes: 41 additions & 3 deletions Classes/BEMAverageLine.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,60 @@ - (instancetype)init {
self = [super init];
if (self) {
_enableAverageLine = NO;
_color = [UIColor whiteColor];
_alpha = 1.0;
_width = 3.0;
_yValue = NAN;
}

return self;
}
-(void) setLabel:(UILabel *)label {

- (instancetype) initWithCoder:(NSCoder *)coder {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: extra space.


#define RestoreProperty(property, type) {\
if ([coder containsValueForKey:@#property]) { \
self.property = [coder decode ## type ##ForKey:@#property ]; \
}\
}
self = [self init];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion"

RestoreProperty (enableAverageLine, Bool);
RestoreProperty (color, Object);
RestoreProperty (yValue, Double);
RestoreProperty (alpha, Double);
RestoreProperty (width, Double);
RestoreProperty (dashPattern, Object);
RestoreProperty (title, Object);
#pragma clang diagnostic pop

//AverageLine
return self;
}

- (void) encodeWithCoder: (NSCoder *)coder {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: extra space.


#define EncodeProperty(property, type) [coder encode ## type: self.property forKey:@#property]
EncodeProperty (enableAverageLine, Bool);
EncodeProperty (color, Object);
EncodeProperty (yValue, Float);
EncodeProperty (alpha, Float);
EncodeProperty (width, Float);
EncodeProperty (dashPattern, Object);
EncodeProperty (title, Object);
}



- (void)setLabel:(UILabel *)label {
if (_label != label) {
[_label removeFromSuperview];
_label = label;
}
}

-(void) dealloc {
- (void)dealloc {
self.label= nil;
}
@end
42 changes: 21 additions & 21 deletions Classes/BEMGraphCalculator.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ - (instancetype)init {
// MARK: -
// MARK: Essential Calculations

- (nonnull NSArray *)calculationDataPointsOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
- (nonnull NSArray <NSNumber *> *)calculationDataPointsOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSPredicate *filter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSNumber *value = (NSNumber *)evaluatedObject;
BOOL retVal = ![value isEqualToNumber:@(BEMNullGraphValue)];
return retVal;
}];
NSArray *filteredArray = [[graph graphValuesForDataPoints] filteredArrayUsingPredicate:filter];
NSArray <NSNumber *> *filteredArray = [[graph graphValuesForDataPoints] filteredArrayUsingPredicate:filter];
return filteredArray;
}

// MARK: -
// MARK: Basic Statistics

- (nonnull NSNumber *)calculatePointValueAverageOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"average:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -65,7 +65,7 @@ - (nonnull NSNumber *)calculatePointValueAverageOnGraph:(nonnull BEMSimpleLineGr
}

- (nonnull NSNumber *)calculatePointValueSumOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"sum:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -75,7 +75,7 @@ - (nonnull NSNumber *)calculatePointValueSumOnGraph:(nonnull BEMSimpleLineGraphV
}

- (nonnull NSNumber *)calculatePointValueMedianOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"median:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -85,19 +85,19 @@ - (nonnull NSNumber *)calculatePointValueMedianOnGraph:(nonnull BEMSimpleLineGra
}

- (nonnull NSNumber *)calculatePointValueModeOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"mode:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
NSMutableArray *value = [expression expressionValueWithObject:nil context:nil];
NSNumber *numberValue = [value firstObject];
NSMutableArray <NSNumber *> *values = [expression expressionValueWithObject:nil context:nil];
NSNumber *numberValue = [values firstObject];

if (numberValue) return numberValue;
else return [NSNumber numberWithInt:0];
}

- (nonnull NSNumber *)calculateStandardDeviationOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"stddev:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -110,7 +110,7 @@ - (nonnull NSNumber *)calculateStandardDeviationOnGraph:(nonnull BEMSimpleLineGr
// MARK: Minimum / Maximum

- (nonnull NSNumber *)calculateMinimumPointValueOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"min:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -119,7 +119,7 @@ - (nonnull NSNumber *)calculateMinimumPointValueOnGraph:(nonnull BEMSimpleLineGr
}

- (nonnull NSNumber *)calculateMaximumPointValueOnGraph:(nonnull BEMSimpleLineGraphView *)graph {
NSArray *filteredArray = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *filteredArray = [self calculationDataPointsOnGraph:graph];
if (filteredArray.count == 0) return [NSNumber numberWithInt:0];

NSExpression *expression = [NSExpression expressionForFunction:@"max:" arguments:@[[NSExpression expressionForConstantValue:filteredArray]]];
Expand All @@ -132,18 +132,18 @@ - (nonnull NSNumber *)calculateMaximumPointValueOnGraph:(nonnull BEMSimpleLineGr
// MARK: Integration

- (nonnull NSNumber *)calculateAreaUsingIntegrationMethod:(BEMIntegrationMethod)integrationMethod onGraph:(nonnull BEMSimpleLineGraphView *)graph xAxisScale:(nonnull NSNumber *)scale {
NSArray *fixedDataPoints = [self calculationDataPointsOnGraph:graph];
NSArray <NSNumber *> *fixedDataPoints = [self calculationDataPointsOnGraph:graph];
if (integrationMethod == BEMIntegrationMethodLeftReimannSum) return [self integrateUsingLeftReimannSum:fixedDataPoints xAxisScale:scale];
else if (integrationMethod == BEMIntegrationMethodRightReimannSum) return [self integrateUsingRightReimannSum:fixedDataPoints xAxisScale:scale];
else if (integrationMethod == BEMIntegrationMethodTrapezoidalSum) return [self integrateUsingTrapezoidalSum:fixedDataPoints xAxisScale:scale];
else if (integrationMethod == BEMIntegrationMethodParabolicSimpsonSum) return [self integrateUsingParabolicSimpsonSum:fixedDataPoints xAxisScale:scale];
else return [NSNumber numberWithInt:0];
}

- (NSNumber *)integrateUsingLeftReimannSum:(nonnull NSArray *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
- (NSNumber *)integrateUsingLeftReimannSum:(nonnull NSArray <NSNumber *> *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
NSNumber *totalArea = [NSNumber numberWithInt:0];

NSMutableArray *leftSumPoints = graphPoints.mutableCopy;
NSMutableArray <NSNumber *> *leftSumPoints = graphPoints.mutableCopy;
[leftSumPoints removeLastObject];

for (NSNumber *yValue in leftSumPoints) {
Expand All @@ -154,10 +154,10 @@ - (NSNumber *)integrateUsingLeftReimannSum:(nonnull NSArray *)graphPoints xAxisS
return totalArea;
}

- (NSNumber *)integrateUsingRightReimannSum:(nonnull NSArray *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
- (NSNumber *)integrateUsingRightReimannSum:(nonnull NSArray <NSNumber *> *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
NSNumber *totalArea = [NSNumber numberWithInt:0];

NSMutableArray *rightSumPoints = graphPoints.mutableCopy;
NSMutableArray <NSNumber *> *rightSumPoints = graphPoints.mutableCopy;
[rightSumPoints removeObjectAtIndex:0];

for (NSNumber *yValue in rightSumPoints) {
Expand All @@ -168,16 +168,16 @@ - (NSNumber *)integrateUsingRightReimannSum:(nonnull NSArray *)graphPoints xAxis
return totalArea;
}

- (NSNumber *)integrateUsingTrapezoidalSum:(nonnull NSArray *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
- (NSNumber *)integrateUsingTrapezoidalSum:(nonnull NSArray <NSNumber *> *)graphPoints xAxisScale:(nonnull NSNumber *)scale {
NSNumber *left = [self integrateUsingLeftReimannSum:graphPoints xAxisScale:scale];
NSNumber *right = [self integrateUsingRightReimannSum:graphPoints xAxisScale:scale];
NSNumber *trapezoidal = [NSNumber numberWithFloat:(left.floatValue+right.floatValue)/2];
return trapezoidal;
}

- (NSNumber *)integrateUsingParabolicSimpsonSum:(nonnull NSArray *)points xAxisScale:(nonnull NSNumber *)scale {
- (NSNumber *)integrateUsingParabolicSimpsonSum:(nonnull NSArray <NSNumber *> *)points xAxisScale:(nonnull NSNumber *)scale {
// Get all the points from the graph into a mutable array
NSMutableArray *graphPoints = points.mutableCopy;
NSMutableArray <NSNumber *> *graphPoints = points.mutableCopy;

// If there are two or fewer points on the graph, no parabolic curve can be created. Thus, the next most accurate method will be employed: a trapezoidal summation
if (graphPoints.count <= 2) return [self integrateUsingTrapezoidalSum:points xAxisScale:scale];
Expand Down Expand Up @@ -233,8 +233,8 @@ - (NSNumber *)integrateUsingParabolicSimpsonSum:(nonnull NSArray *)points xAxisS
- (NSNumber *)calculateCorrelationCoefficientUsingCorrelationMethod:(BEMCorrelationMethod)correlationMethod onGraph:(BEMSimpleLineGraphView *)graph xAxisScale:(nonnull NSNumber *)scale {
// Grab the x and y points
// Because a BEMSimpleLineGraph object simply increments X-Values, we must calculate the values here
NSArray *yPoints = [self calculationDataPointsOnGraph:graph];
NSMutableArray *xPoints = [NSMutableArray arrayWithCapacity:yPoints.count];
NSArray <NSNumber *> *yPoints = [self calculationDataPointsOnGraph:graph];
NSMutableArray <NSNumber *> *xPoints = [NSMutableArray arrayWithCapacity:yPoints.count];
if (scale == nil || scale.floatValue == 0.0) {
for (NSUInteger i = 1; i <= yPoints.count; i++) {
[xPoints addObject:[NSNumber numberWithInteger:i]];
Expand Down
18 changes: 9 additions & 9 deletions Classes/BEMLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ typedef NS_ENUM(NSUInteger, BEMLineGradientDirection) {
//----- POINTS -----//

/// All of the Y-axis values for the points
@property (strong, nonatomic, nonnull) NSArray *arrayOfPoints;
@property (strong, nonatomic, nonnull) NSArray <NSNumber *> *arrayOfPoints;

/// All of the X-Axis coordinates used to draw vertical lines through
@property (strong, nonatomic, nonnull) NSArray *arrayOfVerticalReferenceLinePoints;
@property (strong, nonatomic, nonnull) NSArray <NSNumber *> *arrayOfVerticalReferenceLinePoints;

/// The value used to offset the fringe vertical reference lines when the x-axis labels are on the edge
@property (assign, nonatomic) CGFloat verticalReferenceHorizontalFringeNegation;

/// All of the Y-Axis coordinates used to draw horizontal lines through
@property (strong, nonatomic, nullable) NSArray *arrayOfHorizontalReferenceLinePoints;
@property (strong, nonatomic, nullable) NSArray <NSNumber *> *arrayOfHorizontalReferenceLinePoints;

/// All of the point values
@property (strong, nonatomic, nullable) NSArray *arrayOfValues;
@property (strong, nonatomic, nullable) NSArray <NSNumber *> *arrayOfValues;

/** Draw thin, translucent, reference lines using the provided X-Axis and Y-Axis coordinates.
@see Use \p arrayOfVerticalReferenceLinePoints to specify vertical reference lines' positions. Use \p arrayOfHorizontalReferenceLinePoints to specify horizontal reference lines' positions. */
Expand All @@ -77,10 +77,10 @@ typedef NS_ENUM(NSUInteger, BEMLineGradientDirection) {
@property (assign, nonatomic) BOOL enableTopReferenceFrameLine;

/** Dash pattern for the references line on the X axis */
@property (nonatomic, strong, nullable) NSArray *lineDashPatternForReferenceXAxisLines;
@property (nonatomic, strong, nullable) NSArray <NSNumber *> *lineDashPatternForReferenceXAxisLines;

/** Dash pattern for the references line on the Y axis */
@property (nonatomic, strong, nullable) NSArray *lineDashPatternForReferenceYAxisLines;
@property (nonatomic, strong, nullable) NSArray <NSNumber *> *lineDashPatternForReferenceYAxisLines;

/** If a null value is present, interpolation would draw a best fit line through the null point bound by its surrounding points. Default: YES */
@property (assign, nonatomic) BOOL interpolateNullValues;
Expand All @@ -99,16 +99,16 @@ typedef NS_ENUM(NSUInteger, BEMLineGradientDirection) {
@property (strong, nonatomic, nullable) UIColor *topColor;

/// A color gradient applied to the area above the line, inside of its superview. If set, it will be drawn on top of the fill from the \p topColor property.
@property (assign, nonatomic, nullable) CGGradientRef topGradient;
@property (strong, nonatomic, nullable) __attribute__((NSObject)) CGGradientRef topGradient;

/// The color of the area below the line, inside of its superview
@property (strong, nonatomic, nullable) UIColor *bottomColor;

/// A color gradient applied to the area below the line, inside of its superview. If set, it will be drawn on top of the fill from the \p bottomColor property.
@property (assign, nonatomic, nullable) CGGradientRef bottomGradient;
@property (strong, nonatomic, nullable) __attribute__((NSObject)) CGGradientRef bottomGradient;

/// A color gradient to be applied to the line. If this property is set, it will mask (override) the \p color property.
@property (assign, nonatomic, nullable) CGGradientRef lineGradient;
@property (strong, nonatomic, nullable) __attribute__((NSObject)) CGGradientRef lineGradient;

/// The drawing direction of the line gradient color
@property (nonatomic) BEMLineGradientDirection lineGradientDirection;
Expand Down
Loading