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 1 commit
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: 1 addition & 1 deletion Classes/BEMAverageLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
12 changes: 6 additions & 6 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 Down
24 changes: 11 additions & 13 deletions Classes/BEMLine.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

@interface BEMLine()

@property (nonatomic, strong) NSMutableArray *points;
@property (nonatomic, strong) NSMutableArray <NSValue *> *points;

@end

Expand Down Expand Up @@ -286,39 +286,38 @@ - (void)drawRect:(CGRect)rect {
}
}

- (NSArray *)topPointsArray {
- (NSArray <NSValue *> *)topPointsArray {
CGPoint topPointZero = CGPointMake(0,0);
CGPoint topPointFull = CGPointMake(self.frame.size.width, 0);
NSMutableArray *topPoints = [NSMutableArray arrayWithArray:self.points];
NSMutableArray <NSValue *> *topPoints = [NSMutableArray arrayWithArray:self.points];
[topPoints insertObject:[NSValue valueWithCGPoint:topPointZero] atIndex:0];
[topPoints addObject:[NSValue valueWithCGPoint:topPointFull]];
return topPoints;
}

- (NSArray *)bottomPointsArray {
- (NSArray <NSValue *> *)bottomPointsArray {
CGPoint bottomPointZero = CGPointMake(0, self.frame.size.height);
CGPoint bottomPointFull = CGPointMake(self.frame.size.width, self.frame.size.height);
NSMutableArray *bottomPoints = [NSMutableArray arrayWithArray:self.points];
NSMutableArray <NSValue *> *bottomPoints = [NSMutableArray arrayWithArray:self.points];
[bottomPoints insertObject:[NSValue valueWithCGPoint:bottomPointZero] atIndex:0];
[bottomPoints addObject:[NSValue valueWithCGPoint:bottomPointFull]];
return bottomPoints;
}

+ (UIBezierPath *)linesToPoints:(NSArray *)points {
+ (UIBezierPath *)linesToPoints:(NSArray <NSValue *> *)points {
UIBezierPath *path = [UIBezierPath bezierPath];
NSValue *value = points[0];
CGPoint p1 = [value CGPointValue];
[path moveToPoint:p1];

for (NSUInteger i = 1; i < points.count; i++) {
value = points[i];
CGPoint p2 = [value CGPointValue];
for (NSValue * point in points) {
CGPoint p2 = [point CGPointValue];
[path addLineToPoint:p2];
}
return path;
}

+ (UIBezierPath *)quadCurvedPathWithPoints:(NSArray *)points {
+ (UIBezierPath *)quadCurvedPathWithPoints:(NSArray <NSValue *> *)points {
UIBezierPath *path = [UIBezierPath bezierPath];

NSValue *value = points[0];
Expand All @@ -332,9 +331,8 @@ + (UIBezierPath *)quadCurvedPathWithPoints:(NSArray *)points {
return path;
}

for (NSUInteger i = 1; i < points.count; i++) {
value = points[i];
CGPoint p2 = [value CGPointValue];
for (NSValue * point in points) {
CGPoint p2 = [point CGPointValue];

CGPoint midPoint = midPointForPoints(p1, p2);
[path addQuadCurveToPoint:midPoint controlPoint:controlPointForPoints(midPoint, p1)];
Expand Down
6 changes: 3 additions & 3 deletions Classes/BEMSimpleLineGraphView.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,11 @@ IB_DESIGNABLE @interface BEMSimpleLineGraphView : UIView <UIGestureRecognizerDel


/// A line dash patter to be applied to X axis reference lines. This allows you to draw a dotted or hashed line
@property (nonatomic, strong) NSArray *lineDashPatternForReferenceXAxisLines;
@property (nonatomic, strong) NSArray <NSNumber *> *lineDashPatternForReferenceXAxisLines;


/// A line dash patter to be applied to Y axis reference lines. This allows you to draw a dotted or hashed line
@property (nonatomic, strong) NSArray *lineDashPatternForReferenceYAxisLines;
@property (nonatomic, strong) NSArray <NSNumber *> *lineDashPatternForReferenceYAxisLines;


/// Color to be used for the no data label on the chart
Expand Down Expand Up @@ -568,7 +568,7 @@ IB_DESIGNABLE @interface BEMSimpleLineGraphView : UIView <UIGestureRecognizerDel
When this is set, `numberOfGapsBetweenLabelsOnLineGraph` is ignored
@param graph The graph object which is requesting the number of gaps between the labels.
@return Array of graph indices to place X-Axis labels */
- (NSArray *)incrementPositionsForXAxisOnLineGraph:(BEMSimpleLineGraphView *)graph;
- (NSArray <NSNumber *> *)incrementPositionsForXAxisOnLineGraph:(BEMSimpleLineGraphView *)graph;



Expand Down
6 changes: 3 additions & 3 deletions Classes/BEMSimpleLineGraphView.m
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ - (void)drawXAxis {

__block UILabel *prevLabel;

NSMutableArray *overlapLabels = [NSMutableArray arrayWithCapacity:self.xAxisLabels.count];
NSMutableArray <UILabel *> *overlapLabels = [NSMutableArray arrayWithCapacity:self.xAxisLabels.count];
[self.xAxisLabels enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger idx, BOOL *stop) {
if (idx == 0) {
prevLabel = label; //always show first label
Expand Down Expand Up @@ -987,7 +987,7 @@ - (void)drawYAxis {
value = increment/2;
}
}
NSMutableArray *dotValues = [[NSMutableArray alloc] initWithCapacity:numberOfLabels];
NSMutableArray <NSNumber *> *dotValues = [[NSMutableArray alloc] initWithCapacity:numberOfLabels];
for (NSUInteger i = 0; i < numberOfLabels; i++) {
[dotValues addObject:@(value)];
value += increment;
Expand All @@ -1013,7 +1013,7 @@ - (void)drawYAxis {

// Detect overlapped labels
__block UILabel * prevLabel = nil;;
NSMutableArray *overlapLabels = [NSMutableArray arrayWithCapacity:0];
NSMutableArray <UILabel *> *overlapLabels = [NSMutableArray arrayWithCapacity:0];

[self.yAxisLabels enumerateObjectsUsingBlock:^(UILabel *label, NSUInteger idx, BOOL *stop) {

Expand Down
6 changes: 3 additions & 3 deletions Sample Project/SimpleLineChart/ViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

@property (weak, nonatomic) IBOutlet BEMSimpleLineGraphView *myGraph;

@property (strong, nonatomic) NSMutableArray *arrayOfValues;
@property (strong, nonatomic) NSMutableArray *arrayOfDates;
@property (strong, nonatomic) NSMutableArray <NSNumber *> *arrayOfValues;
@property (strong, nonatomic) NSMutableArray <NSDate *> *arrayOfDates;

@property (strong, nonatomic) IBOutlet UILabel *labelValues;
@property (strong, nonatomic) IBOutlet UILabel *labelDates;
Expand All @@ -29,4 +29,4 @@

- (IBAction)displayStatistics:(id)sender;

@end
@end
Loading