Studio Symposium
Studio Symposium

Reputation: 287

Trouble implementing JBChartView

I'm starting to get brave and am attempting to populate a JBChartView (specifically a line chart) into my application for statistics tracking. I've never worked with a graphing library before but I did my best to look into them and this one seemed very robust. Problem is I'm having trouble getting the plots to work correctly from test data.

When I run the code as follows below, I get [__NSCFConstantString objectAtIndex:] unrecognized selector sent to instance. The offending line is at verticalValueforHorizontalIndex but I can't figure out another way to produce any data. Does anyone have any experience with this or can anyone help me figure out why I'm getting so much trouble here?

Implementation File

#import "waterStatsViewController.h"
#import "JBLineChartView.h"
#import "JBChartView.h"
#import "JBBarChartView.h"
#import "JBChartHeaderView.h"
#import "JBLineChartFooterView.h"

typedef NS_ENUM(NSInteger, JBLineChartLine){
JBLineChartLineSolid,
JBLineChartLineDashed,
JBLineChartLineCount
};

@interface waterStatsViewController ()

- (void)initData;

@end

@implementation waterStatsViewController

- (id)init
{
self = [super init];
if (self)
{
   [self initData];
}
return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
    [self initData];
}
return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
    [self initData];
}
return self;
}

- (void) initData
{
// DEFINE ARRAYS
testArray1 = [[NSArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", nil];
testArray2 = [[NSArray alloc] initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", nil];

// CREATE MUTABLE ARRAY FOR LINES IN CHART
NSMutableArray *mutableLineCharts = [NSMutableArray array];

// AS LONG AS LINEINDEX IS LESS THEN THE LINE COUNT, INCREASE THE LINE COUNT AND EXECUTE CODE
for (int lineIndex = 0; lineIndex<JBLineChartLineCount; lineIndex++)
{
    // CREATE MUTABLE ARRAY FOR DATA IN CHART
    NSMutableArray *mutableChartData = [NSMutableArray array];

    // AS LONG AS INT I IS LESS THEN THE COUNT OF OBJECTS IN TEST ARRAY 2; INCREASE COUNT AND EXECUTE CODE
    for (int i = 0; i < testArray2.count; i++)
    {
        // ADD OBJECTS FROM TEST ARRAY 2 TO CHART DATA
        [mutableChartData addObjectsFromArray:testArray2];
    }
    // TAKE OBJECTS FROM MUTABLE CHART DATA AND ADD THEM TO OHHHHHH FOR EACH ITEM YOU ADD ANOTHER LINE
    [mutableLineCharts addObjectsFromArray:mutableChartData];
}
}


- (void)viewDidLoad
{
self.title = @"Water Quality";

_chartView = [[JBLineChartView alloc] init];
_chartView.delegate = self;
_chartView.dataSource = self;
_chartView.state = 0;
_chartView.backgroundColor = [UIColor blackColor];
_chartView.showsLineSelection = YES;
_chartView.showsVerticalSelection = YES;

_headerView = [[JBChartHeaderView alloc]  initWithFrame:CGRectMake(0, 64, 320, 30)];
_chartView.frame = CGRectMake(0, 94, 320, 300);
 _footerView = [[JBLineChartFooterView alloc] initWithFrame:CGRectMake(0, 404, 320, 30)];

_headerView.titleLabel.text = @"Alkalinity";
_headerView.titleLabel.textColor = [UIColor whiteColor];

_footerView.leftLabel.text = [testArray1 firstObject];
_footerView.rightLabel.text = [testArray1 lastObject];
_footerView.leftLabel.textColor = [UIColor whiteColor];
_footerView.rightLabel.textColor = [UIColor whiteColor];
_footerView.backgroundColor = [UIColor blackColor];
_footerView.sectionCount = [testArray1 count];

// THIS IS THE VIEW WHEN THE USER INTERACTS WITH THE CHART
/*
_informationView = [[JBChartInformationView alloc] initWithFrame:CGRectMake(0, 0, 40, 300)];
[_informationView setBackgroundColor:[UIColor grayColor]];*/


[_chartView setMinimumValue:1.0f];
[_chartView setMaximumValue:20.0f];

[self.view addSubview:_footerView];
[self.view addSubview:_headerView];
[self.view addSubview:_chartView];
//    [self.view addSubview:_informationView];
[_chartView reloadData];

[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}

- (BOOL)lineChartView:(JBLineChartView *)lineChartView showsDotsForLineAtLineIndex:(NSUInteger)lineIndex;
{
return YES;
}

- (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView;
{
return 1;
}

- (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex;
{
return 1;
}


- (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
{
return [[[testArray2 objectAtIndex:lineIndex] objectAtIndex:horizontalIndex] floatValue];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

Upvotes: 0

Views: 1255

Answers (1)

Terry Worona
Terry Worona

Reputation: 299

A few issues:

  • Don't store numeric values as strings in your test arrays.
  • Remove the mutableLineCharts code; this is leftover from the demo and not needed for your purposes.
  • I assume you want two lines? One dashed and one solid? If so, return JBLineChartLineCount instead of 1 for numberOfLinesInLineChartView.
  • Return the numeric value for testArray1 or testArray2 in verticalValueForHorizontalIndex.

Initializing Data

- (void) initData
{
    testArray1 = @[@(1), @(2), @(3), @(4), @(5), @(6), @(7), @(8), @(9), @(10)];
    testArray2 = @[@(11), @(12), @(13), @(14), @(15), @(16), @(17), @(18), @(19), @(20)];
}

Line Count

- (NSUInteger)numberOfLinesInLineChartView:(JBLineChartView *)lineChartView;
{
    return JBLineChartLineCount;
}

Data Count

- (NSUInteger)lineChartView:(JBLineChartView *)lineChartView numberOfVerticalValuesAtLineIndex:(NSUInteger)lineIndex;
{
    if (lineIndex == JBLineChartLineSolid)
    {
        return [self.testArray1 count];
    }
    else
    {
        return [self.testArray2 count];
    }
    return 0;
}

Data Value

- (CGFloat)lineChartView:(JBLineChartView *)lineChartView verticalValueForHorizontalIndex:(NSUInteger)horizontalIndex atLineIndex:(NSUInteger)lineIndex;
{
    if (lineIndex == JBLineChartLineSolid)
    {
        NSNumber *value = (NSNumber *)[self.testArray1 objectAtIndex:horizontalIndex];
        return [value floatValue];
    }
    else
    {
        NSNumber *value = (NSNumber *)[self.testArray2 objectAtIndex:horizontalIndex];
        return [value floatValue];
    }
    return 0;
}

Hope this helps.

Upvotes: 3

Related Questions