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.