Skip to content

Instantly share code, notes, and snippets.

@jeiting
Created April 11, 2013 06:39
Show Gist options
  • Select an option

  • Save jeiting/5361231 to your computer and use it in GitHub Desktop.

Select an option

Save jeiting/5361231 to your computer and use it in GitHub Desktop.
//
// FDRSparklineView.m
// roosevelt
//
// Created by Jacob Eiting on 4/7/13.
// Copyright (c) 2013 Jacob Eiting. All rights reserved.
//
#import "FDRSparklineView.h"
#import "FDRRecording.h"
#import "FDRLocationRecordingEvent.h"
#import <QuartzCore/QuartzCore.h>
@interface FDRSparklineView ()
@property (readwrite, strong) CAShapeLayer *miniMarksLayer;
@property (readwrite, strong) CAShapeLayer *megaMarksLayer;
@property (readwrite, strong) CAShapeLayer *outlineLayer;
@property (readwrite, strong) CAShapeLayer *fillLayer;
@end
#define kMiniMarkHeight 15.0f
@implementation FDRSparklineView
- (id)initWithFrame:(CGRect)frame recording:(FDRRecording *)recording
{
self = [super initWithFrame:frame];
if (self) {
_recording = recording;
self.backgroundColor = [UIColor whiteColor];
[self setupTimeMarkPaths];
[self setupSparkLine];
}
return self;
}
- (void)setupTimeMarkPaths
{
CGFloat maxX = self.frame.size.width;
CGFloat maxY = self.frame.size.height;
CGMutablePathRef miniMarks = CGPathCreateMutable();
CGMutablePathRef megaMarks = CGPathCreateMutable();
int smallMarks;
int bigMarks;
// create the time demarcations
if (self.recording.duration < 900.0) {
// mark in 5 minute intervals
smallMarks = self.recording.duration/60.0;
bigMarks = self.recording.duration/(60.0 * 5);
} else if (self.recording.duration < 4000.0) {
// smalls on the 5s, bigs on 15s
smallMarks = self.recording.duration/(60.0 * 5);
bigMarks = self.recording.duration/(60.0 * 15);
} else {
// smalls on the 15s bigs on the hours
smallMarks = self.recording.duration/(60.0 * 15);
bigMarks = self.recording.duration/(60.0 * 60);
}
// draw small marks
for (int i = 1; i <= smallMarks; i++) {
CGFloat x = (float)i/(float)smallMarks*maxX;
CGPathMoveToPoint(miniMarks, NULL, x, kMiniMarkHeight);
CGPathAddLineToPoint(miniMarks, NULL, x, 0);
}
// draw large marks
for (int i = 1; i <= bigMarks; i++) {
CGFloat x = (float)i/(float)bigMarks*maxX;
CGPathMoveToPoint(megaMarks, NULL, x, maxY);
CGPathAddLineToPoint(megaMarks, NULL, x, 0);
}
self.miniMarksLayer = [CAShapeLayer layer];
self.miniMarksLayer.path = miniMarks;
self.miniMarksLayer.strokeColor = [UIColor colorWithRed:0.92 green:0.92 blue:0.92 alpha:0.92].CGColor;
self.miniMarksLayer.lineWidth = 1.0f;
[self.layer addSublayer:self.miniMarksLayer];
self.megaMarksLayer = [CAShapeLayer layer];
self.megaMarksLayer.path = megaMarks;
self.megaMarksLayer.strokeColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.92].CGColor;
self.megaMarksLayer.lineWidth = 2.0f;
[self.layer addSublayer:self.megaMarksLayer];
}
- (void)setupSparkLine
{
CGFloat maxX = self.frame.size.width;
CGFloat maxY = self.frame.size.height;
// create the altitude sparkline
CGMutablePathRef outline = CGPathCreateMutable();
CGMutablePathRef shape = CGPathCreateMutable();
int count = [self.recording eventCountForType:FDRRecordingEventTypeLocation];
CGFloat originalY = 0.0f;
// create all the paths for the spark
for (int i = 0; i < count; i++) {
FDRLocationRecordingEvent *loc = (FDRLocationRecordingEvent *)[self.recording eventOfType:FDRRecordingEventTypeLocation atIndex:i];
CGFloat x = loc.missionElapsedTime/self.recording.duration*maxX;
CGFloat y = maxY - maxY*loc.altitude/[self.recording maxAltitude];
NSLog(@"%.2f,%.2f", x, y);
if (i == 0) {
CGPathMoveToPoint(outline, NULL, 0, y);
CGPathMoveToPoint(shape, NULL, 0, y);
originalY = y;
}
CGPathAddLineToPoint(outline, NULL, x, y);
CGPathAddLineToPoint(shape, NULL, x, y);
}
CGPathAddLineToPoint(shape, NULL, maxX, maxY);
CGPathAddLineToPoint(shape, NULL, 0, maxY);
CGPathCloseSubpath(shape);
self.outlineLayer = [CAShapeLayer layer];
self.outlineLayer.path = outline;
self.outlineLayer.strokeColor = [UIColor colorWithRed:0.0 green:0.40 blue:0.5 alpha:0.5].CGColor;
self.outlineLayer.lineWidth = 3.0f;
[self.layer addSublayer:self.outlineLayer];
self.fillLayer = [CAShapeLayer layer];
self.fillLayer.path = shape;
self.fillLayer.fillColor = [UIColor colorWithRed:0.54 green:0.733 blue:0.78 alpha:0.8].CGColor;
[self.layer addSublayer:self.fillLayer];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment