This is CurveView.m in view mode; [Download] [Up]
/* * A plotting view. * Rob Ferrante */ #import "CurveView.h" #import "GradeSlider.h" #include "CV.h" #import <appkit/Matrix.h> #import <appkit/Cell.h> #import <objc/List.h> #import <dpsclient/wraps.h> #import <strings.h> @implementation CurveView float scoreFromPos(int x) { return 100.0 - x/5.0; } - initFrame: (NXRect *)r { int i; self = [super initFrame:r]; count = 0; percentMode = NO; topOfView = 399; for (i=0;i<20;i++) scoreBin[i]=0; posA = 100; posB=200; posC=300; posD=400; return self; } - setPercentMode:sender { percentMode = ([[sender selectedCell] tag] == 1); [self updateFields]; return self; } - loadStudents:sender { int num, i, maxBin=0; [scoreMatrix getNumRows:&num numCols:&i]; // used i for cols, don't need count = 0; for (i=0;i<20;i++) scoreBin[i]=0; for (i=0;i<num;i++) { scores[i] = [[scoreMatrix cellAt:i :0] floatValue]; if (strlen([[nameMatrix cellAt:i :0] stringValue]) >0){ count++; if (scores[i]>=100.0) scores[i]=99.9; scoreBin[(int)(scores[i]/5.0)]++; } } for (i=0;i<20;i++) if (maxBin < scoreBin[i]) maxBin = scoreBin[i]; [self setDrawSize:500 :(topOfView=maxBin*1.25)]; [self display]; [self updateFields]; return self; } - loadGrades:sender { int i; float cutA,cutB,cutC,cutD; cutA = scoreFromPos(posA); cutB = scoreFromPos(posB); cutC = scoreFromPos(posC); cutD = scoreFromPos(posD); for (i=0;i<count;i++) { if (scores[i] >= cutA) [[gradeMatrix cellAt:i :0] setStringValue:"A"]; else if (scores[i] >= cutB) [[gradeMatrix cellAt:i :0] setStringValue:"B"]; else if (scores[i] >= cutC) [[gradeMatrix cellAt:i :0] setStringValue:"C"]; else if (scores[i] >= cutD) [[gradeMatrix cellAt:i :0] setStringValue:"D"]; else [[gradeMatrix cellAt:i :0] setStringValue:"F"]; } return self; } - drawSelf:(NXRect *)list:(int)count { int i=19, k=0; NXRect bar; NXEraseRect(&bounds); PSsetgray(NX_DKGRAY); while(i>=0) { NXSetRect(&bar,k,0,25,scoreBin[i--]); NXRectFill(&bar); k +=25; } PSlines(posA, posB, posC, posD, topOfView); return self; } - moveA:sender { posA = [sender posA]; [self display]; [fieldA setFloatValue:[self percentBetween:scoreFromPos(posA) :100.01]]; [fieldB setFloatValue:[self percentBetween:scoreFromPos(posB) :scoreFromPos(posA)]]; return self; } - moveB:sender { posB = [sender posB]; [self display]; [fieldB setFloatValue:[self percentBetween:scoreFromPos(posB) :scoreFromPos(posA)]]; [fieldC setFloatValue:[self percentBetween:scoreFromPos(posC) :scoreFromPos(posB)]]; return self; } - moveC:sender { posC = [sender posC]; [self display]; [fieldC setFloatValue:[self percentBetween:scoreFromPos(posC) :scoreFromPos(posB)]]; [fieldD setFloatValue:[self percentBetween:scoreFromPos(posD) :scoreFromPos(posC)]]; return self; } - moveD:sender { posD = [sender posD]; [self display]; [fieldD setFloatValue:[self percentBetween:scoreFromPos(posD) :scoreFromPos(posC)]]; [fieldF setFloatValue:[self percentBetween:0.0 :scoreFromPos(posD)]]; return self; } - updateFields { [fieldA setFloatValue:[self percentBetween:scoreFromPos(posA) :100.01]]; [fieldB setFloatValue:[self percentBetween:scoreFromPos(posB) :scoreFromPos(posA)]]; [fieldC setFloatValue:[self percentBetween:scoreFromPos(posC) :scoreFromPos(posB)]]; [fieldD setFloatValue:[self percentBetween:scoreFromPos(posD) :scoreFromPos(posC)]]; [fieldF setFloatValue:[self percentBetween:0.0 :scoreFromPos(posD)]]; return self; } -(float)percentBetween:(float)low :(float)high { int i,k=0; for (i=0; i<count;i++) { if (scores[i]>=low && scores[i]<high) k++; } if (percentMode == YES) return (k/(float)count)*100.0; else return k; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.