0

I would like to draw a bar chart in an existing view on the user interface. The single bar highs are calculated after user input and stored in an array. The array should be passed to my custom GraphView class after a button is bushed to draw the bar chart finally. But it doesn't work. I don't know if I pass the array right (how can I check it?) and how to access it in my drawrect method to set the single bar highs? As soon I put NSNumber *balkenHoehe = [balkenArray objectAtIndex:i]; in the drawrect method and balkenHoehe as rect-hight I get errors. WHAT DO I HAVE TO DO? Thanks!

here is my code:

my AppDelegate.h

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *eingabeNennmass;
@property (weak) IBOutlet NSTextField *eingabeToleranzOben;
@property (weak) IBOutlet NSTextField *eingabeToleranzUnten;
@property (weak) IBOutlet NSTextField *eingabeAnzahlWerte;
@property (weak) IBOutlet NSTextField *ausgabeMittelwert;
@property (weak) IBOutlet NSTextField *ausgabeToleranz
@property (weak, nonatomic) IBOutlet GraphView *ausgabeGraph;

- (IBAction)pushSimulation:(NSButton *)sender;

@end

my AppDelegate.m shortened

#import "GraphView.h" 
#import "AppDelegate.h"

implementation AppDelegate
....//couple calculating code and building the array klassenArray//...

    [klassenArray addObject:[NSNumber numberWithDouble: n]];
....//more code//...

[_ausgabeGraph setBalkenArray:klassenArray]; (connected with the GraphView view on the user interface)

....//more code//...

my GraphView.h

#import <Cocoa/Cocoa.h>

@interface GraphView : NSView
{

NSMutableArray *balkenArray;

}

- (NSMutableArray *) balkenArray;
- (void) setBalkenArray:(NSMutableArray *)abalkenArray;

@end

my GraphView.m

#import "GraphView.h"

@implementation GraphView

//*******************************
- (void) setBalkenArray:(NSMutableArray *)abalkenArray
{
    balkenArray = abalkenArray;
    [self setNeedsDisplay:YES];
}

//*******************************
- (NSMutableArray *)balkenArray
{
    return balkenArray;
}

//*******************************
- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

    }

    return self;
}

//*******************************
- (void)drawRect:(NSRect)dirtyRect
{

    NSRect bounds = [self bounds];
    float fieldWith = bounds.size.width / 12.0;
    float fieldHeight = bounds.size.height / 12.0;

        //background
    NSRect hintergrundRect =
    hintergrundRect = NSMakeRect(bounds.origin.x, bounds.origin.y,
                                  bounds.size.width, bounds.size.height);
    [[NSColor grayColor] set];
    [NSBezierPath fillRect:hintergrundRect];

        //Diagram

    for (int i = 1; i<=10; i++) {
        NSNumber *balkenHoehe = [balkenArray objectAtIndex:i];
//        NSLog(@"rectnumber at index %d is %@", i, balkenHoehe);

        NSRect aRect =
        aRect = NSMakeRect (fieldWith*i, fieldHeight, fieldWith, balkenHoehe); //x, y, width, hight
        // draw rect
    [[NSColor whiteColor] set];
    [NSBezierPath fillRect:aRect];

        // draw border
    [[NSColor blackColor] set];
    NSBezierPath *aPath = [NSBezierPath bezierPathWithRect:aRect];
    [aPath setLineWidth:1];
    [aPath stroke];
    }
}


@end
JFS
  • 2,992
  • 3
  • 37
  • 48
  • what errors? what doesn't work? – bryanmac Dec 06 '12 at 22:16
  • I would not recommend having instance-variables (ivars) that have the same names as properties. – ColinE Dec 06 '12 at 22:18
  • @ bryanmac: Thanks. With the line `NSNumber *balkenHoehe = [balkenArray objectAtIndex:i];` in GraphView.m the build doesn't stop and I get thousands of wired notes in the log window. As soon as I put `balkenHoehe` as variable as the rect hight the error "Passing 'NSNumber *__strong' to parameter of incompatible type 'CGFloat' (aka 'double')" occurs when trying to build. – JFS Dec 06 '12 at 23:00
  • @ ColinE: Thanks for your answer. What do you mean with not having instance vars with same names as properties? How would you do it? – JFS Dec 06 '12 at 23:02
  • A standard convention is to have the ivars starting with an underscore, for instance `_myVar` where the property name is `myVar`. In this case you cannot refer accidentally to the ivar in place of the property since they are named differently. A way to achieve this is when you synthesize your property by doing `@syntesize myVar = _myVar;`. In the latest version of XCode this is done automatically if you omit the `@synthesize` declaration. – Gabriele Petronella Dec 07 '12 at 00:06
  • Thanks first. How would that solve my problem? How do I need to use an array within the drawrect method to set the bar highs `balkenHoehe`? – JFS Dec 07 '12 at 11:45

1 Answers1

0

Ok, thanks to myself here! Good guy. I used the @property and @systnesize thing in GrapView.h

@interface GraphView : NSView
{
NSMutableArray *balkenArray;
}
@property(nonatomic, retain)NSMutableArray *balkenArray;
@property(readwrite, assign)double _maxKlasse;
@end

and GraphView.m

@synthesize balkenArray, _maxKlasse;

in AppDelegate.m the array is send to the view:

_ausgabeGraph.balkenArray=klassenArray;
_ausgabeGraph._maxKlasse=maxKlasse;
[_ausgabeGraph setNeedsDisplay:YES];

and finally the array is used in the GraphView.m to draw the bar chart:

... code ...

for (int i = 1; i<=10; i++) {
  double _x = [(NSNumber*)[balkenArray objectAtIndex:i-1] doubleValue];

  //draw rect
  NSRect aRect =
    aRect = NSMakeRect (fieldWith * i, fieldHeight, fieldWith, (6*fieldHeight*_x/_maxKlasse)); //x, y, width, variable hight
    [[NSColor whiteColor] set];
    [NSBezierPath fillRect:aRect];

... more code ...

Thanks to Gabriele Petronella for the hint using property and synthesize. As long as I understood it is much easier to use. I still need to learn the conventions for the naming.

JFS
  • 2,992
  • 3
  • 37
  • 48