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.