This is StripChart.m in view mode; [Download] [Up]
#import <stdio.h>
#import <stdlib.h>
#import <appkit/Font.h>
#import <dpsclient/psops.h>
#import <math.h>
#import <string.h>
#import "Monitorwraps.h"
#import "StripChart.h"
@implementation StripChart
- initFrame:(const NXRect *) frameRect maximum:(float) maxval scale:(float) scale title:(char *) string
{
[super initFrame: frameRect];
[[self allocateGState] notifyToInitGState: YES];
[self setOpaque: YES];
ceiling = maxval;
factor = scale;
title = string;
inited = 0;
xoffset = 0.0;
yoffset = 0.0;
width = 0.0;
height = 0.0;
count = (int) frameRect->size.width;
if (!(_values = (float *) NXZoneMalloc([self zone],4 * count * sizeof(float)))){
fprintf(stderr, "Monitor: insufficient memory for display\n");
exit(1);
}
bzero(_values, 4 * count * sizeof(float));
index = 0;
number = 0;
if (!(upath = (float *) NXZoneMalloc([self zone],4 * count * sizeof(float)))){
fprintf(stderr, "Monitor: insufficient memory for display\n");
exit(1);
}
nupath = 0;
if (!(uops = (char *) NXZoneMalloc([self zone],2 * count))){
fprintf(stderr, "Monitor: insufficient memory for display\n");
exit(1);
}
nuops = 0;
return(self);
}
/* Private Instance Methods */
- (BOOL)setMaximum:(float) maxval
{
if (ceiling >= 0.0){
maxval = (int) maxval + 1;
if (maxval > ceiling)
maxval = ceiling;
}else
if (number < 4)
maxval = (int) (1.25 * maxval) + 1;
else
maxval = (int) maxval;
if (maximum != maxval){
maximum = maxval;
return(YES);
}else
return(NO);
}
- (BOOL)scrollStats:(float) maxval
{
int shift;
int i;
float total;
index -= (shift = index >> 1);
bcopy(&values(shift, 0), _values, 4 * index * sizeof(float));
bzero(&values(index, 0), 4 * shift * sizeof(float));
switch (number){
case 4:
for (i = 0; i < index; i++){
total = values(i, 0) + values(i, 1) + values(i, 2) + values(i, 3);
if (total > maxval)
maxval = total;
}
break;
case 3:
for (i = 0; i < index; i++){
total = values(i, 0) + values(i, 1) + values(i, 2);
if (total > maxval)
maxval = total;
}
break;
case 2:
for (i = 0; i < index; i++){
total = values(i, 0) + values(i, 1);
if (total > maxval)
maxval = total;
}
break;
case 1:
for (i = 0; i < index; i++)
if (values(i, 0) > maxval)
maxval = values(i, 0);
}
[self setMaximum: maxval];
return(YES);
}
- userPath:(int) stat scale:(float) scale color:(NXColor ) color
{
char drawing;
float point = 0.0;
float saved = 0.0;
int start = 0;
int i;
for (drawing = NO, nupath = nuops = i = 0; i <= index; i++){
switch (stat){
case 2:
point = rint((values(i, 2) + values(i, 1) + values(i, 0)) * scale);
break;
case 1:
point = rint((values(i, 1) + values(i, 0)) * scale);
break;
case 0:
point = rint(values(i, 0) * scale);
}
if (drawing){
if (point == 0.0 || i == index){
upath[nupath++] = i;
upath[nupath++] = saved;
uops[nuops++] = dps_lineto;
upath[nupath++] = i;
upath[nupath++] = 0.0;
uops[nuops++] = dps_lineto;
upath[nupath++] = start;
upath[nupath++] = 0.0;
uops[nuops++] = dps_lineto;
uops[nuops++] = dps_closepath;
drawing = NO;
}else
if (point != saved){
upath[nupath++] = i;
upath[nupath++] = saved;
uops[nuops++] = dps_lineto;
upath[nupath++] = i;
upath[nupath++] = point;
uops[nuops++] = dps_lineto;
saved = point;
}
}else
if (i < index && point > 0.0){
upath[nupath++] = i;
upath[nupath++] = point;
uops[nuops++] = dps_moveto;
start = i;
saved = point;
drawing = YES;
}
}
if (nuops){
NXSetColor(color);
DPSDoUserPath(upath, nupath, dps_float, uops, nuops, ubbox, dps_ufill);
}
return(self);
}
/* Public Instance Methods */
- free
{
[self freeGState];
free(_values);
free(upath);
free(uops);
[super free];
return(self);
}
- initGState
{
PSsetgray(0.0);
[[Font newFont: "Screen-Helvetica" size: 8.0 matrix: NX_IDENTITYMATRIX] set];
return(self);
}
- drawSelf:(const NXRect *) rects :(int) rectCount
{
float scale;
char value[8];
float vwidth;
float vheight;
if (!inited){
inited = 1;
NXSetColor(NX_COLORLTGRAY);
fill_strip(0.0, 0.0, bounds.size.width, bounds.size.height);
string_size("0000", &xoffset, &yoffset);
xoffset += 2.0;
yoffset += 5.0;
draw_frame(0.5, 3.5, title, xoffset + 0.5, yoffset + 1.5, bounds.size.width - 0.5, bounds.size.height - 0.5);
width = bounds.size.width - xoffset - 4.0;
height = bounds.size.height - yoffset - 5.0;
count = (int) width;
[self translate: xoffset + 2.0: yoffset + 3.0];
ubbox[0] = 0.0;
ubbox[1] = 0.0;
ubbox[2] = width;
ubbox[3] = height;
}
if (maximum > 0.0){
NXSetColor(NX_COLORLTGRAY);
fill_strip(-xoffset - 2.0, 0.0, xoffset, bounds.size.height - yoffset - 3.0);
if (factor != 0.0){
sprintf(value, "%.2f", maximum / factor);
if (value[1] != '.')
sprintf(value, "%.1f", maximum / factor);
}else
sprintf(value, "%d", (int) rint(maximum));
string_size(value, &vwidth, &vheight);
draw_limits(-vwidth - 3.0, height - vheight - 1.0, value);
}
NXSetColor(NX_COLORWHITE);
fill_strip(0.0, 0.0, width, height);
if (index){
scale = (maximum > 0.0) ? height / maximum : 1.0;
switch (number){
case 4:
[self userPath: 2 scale: scale color: NX_COLORBLUE /* NX_COLORLTGRAY */];
case 3: case 2:
[self userPath: 1 scale: scale color: NX_COLORGREEN /* NX_COLORDKGRAY */];
case 1:
[self userPath: 0 scale: scale color: NX_COLORRED /* NX_COLORBLACK */];
}
}
return(self);
}
- plotStats:(float) black count:(int) samples
{
float scale;
float point;
int i;
if (number < 1)
number = 1;
if ((index + samples > count && [self scrollStats: black]) ||
(black > maximum && [self setMaximum: black]) )
[self update];
for (i = 0; i < samples; i++)
values(index + i, 0) = black;
scale = (maximum > 0.0) ? height / maximum : 1.0;
point = rint(black * scale);
if (point > 0.0)
if ([self isAutodisplay]){
[self lockFocus];
draw_1_stat(index, samples, point);
[self unlockFocus];
}else
[self setNeedsDisplay: YES];
index += samples;
return(self);
}
- plotStats:(float) black :(float) dgray count:(int) samples
{
float total;
float scale;
float points[2];
int i;
if (number < 2)
number = 2;
total = black + dgray;
if ((index + samples > count && [self scrollStats: total]) ||
(total > maximum && [self setMaximum: total]) )
[self update];
for (i = 0; i < samples; i++){
values(index + i, 0) = black;
values(index + i, 1) = dgray;
}
scale = (maximum > 0.0) ? height / maximum : 1.0;
points[0] = rint(black * scale);
points[1] = rint(total * scale) - points[0];
if (points[0] + points[1] > 0.0)
if ([self isAutodisplay]){
[self lockFocus];
draw_2_stats(index, samples, points[0], points[1]);
[self unlockFocus];
}
else
[self setNeedsDisplay: YES];
index += samples;
return(self);
}
- plotStats:(float) black :(float) dgray :(float) white count:(int) samples
{
float total;
float scale;
float points[2];
int i;
if (number < 3)
number = 3;
total = black + dgray + white;
if ((index + samples > count && [self scrollStats: total]) ||
(total > maximum && [self setMaximum: total]) )
[self update];
for (i = 0; i < samples; i++){
values(index + i, 0) = black;
values(index + i, 1) = dgray;
values(index + i, 2) = white;
}
scale = (maximum > 0.0) ? height / maximum : 1.0;
points[0] = rint(black * scale);
points[1] = rint((black + dgray) * scale) - points[0];
if (points[0] + points[1] > 0.0)
if ([self isAutodisplay]){
[self lockFocus];
draw_2_stats(index, samples, points[0], points[1]);
[self unlockFocus];
}else
[self setNeedsDisplay: YES];
index += samples;
return(self);
}
- plotStats:(float) black :(float) dgray :(float) lgray :(float) white count:(int) samples
{
float total;
float scale;
float points[3];
int i;
if (number < 4)
number = 4;
total = black + dgray + lgray + white;
if ((index + samples > count && [self scrollStats: total]) ||
(total > maximum && [self setMaximum: total]) )
[self update];
for (i = 0; i < samples; i++){
values(index + i, 0) = black;
values(index + i, 1) = dgray;
values(index + i, 2) = lgray;
values(index + i, 3) = white;
}
scale = (maximum > 0.0) ? height / maximum : 1.0;
points[0] = rint(black * scale);
points[1] = rint((black + dgray) * scale) - points[0];
points[2] = rint((black + dgray + lgray) * scale) - points[1] - points[0];
if (points[0] + points[1] + points[2] > 0.0)
if ([self isAutodisplay]){
[self lockFocus];
draw_3_stats(index, samples, points[0], points[1], points[2]);
[self unlockFocus];
}else
[self setNeedsDisplay: YES];
index += samples;
return(self);
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.