Annotation of Examples/DatabaseKit/BarChart/ChartOfMatrix.m, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * BarChart, A simple multi source loadable class.
                      3:  *
                      4:  *     Written by: Joe Freeman 7/92
                      5:  *     
                      6:  *     HSB color sweep stolen from some of Randy Nelson's code
                      7:  *             should use NXEqualColor() for duplicates
                      8:  *
                      9:  */
                     10: 
                     11: 
                     12: #import "ChartOfMatrix.h"
                     13: #import <dpsclient/psops.h>
                     14: #import <c.h>
                     15: #import <stdio.h>
                     16: 
                     17: #define NUM_BOGUS      8       /* number of bars to draw when no data */
                     18: #define COM_VERSION    3.3     /* version 3 ported to 3.0 */
                     19: 
                     20: @implementation ChartOfMatrix
                     21: 
                     22: 
                     23: /*============================================================
                     24:  *factory
                     25:  *============================================================*/
                     26: 
                     27: 
                     28: + initialize
                     29: {
                     30:        [super initialize];
                     31:        [ChartOfMatrix setVersion:2];
                     32:        return self;
                     33: }
                     34: 
                     35: - (const char *)getInspectorClassName 
                     36: { 
                     37:        return "ChartOfMatrixInspector"; }
                     38: 
                     39: - initFrame:(NXRect *)r
                     40: {
                     41:        self = [super initFrame:r];
                     42:        minSheetSet = 0.0;
                     43:        maxSheetSet = 1.0;
                     44:        COM_Flags.autoScale = YES;
                     45:        COM_Flags.drawType = DRAW_V_BAR;
                     46:        backgroundColor = NX_COLORWHITE;
                     47:        highlightColor = NX_COLORBLACK;
                     48:        highlightIndex = MAXINT;                /* don't show on default */
                     49:        COM_Flags.drawFrame = YES;
                     50:        hMargin = vMargin = 15.0;
                     51:        hMargin = vMargin = 5.0;
                     52:        numPrototypes = 5;
                     53:        COM_Flags.randomBarColors = YES;
                     54:        return self;
                     55: }
                     56: 
                     57: - awake
                     58: {
                     59:     [super awake];
                     60:     highlightIndex = MAXINT;
                     61:     [self registerForDraggedTypes:&NXColorPboardType count:1];
                     62:     return self;
                     63: }
                     64: 
                     65: /*============================================================
                     66:  * color dragging support
                     67:  *============================================================*/
                     68: 
                     69: - (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
                     70: {
                     71:     if ([sender draggingSourceOperationMask] & NX_DragOperationGeneric) {
                     72:        return NX_DragOperationGeneric;
                     73:     } else {
                     74:        return NX_DragOperationNone;
                     75:            }
                     76:     }
                     77: 
                     78: - (BOOL)performDragOperation:(id <NXDraggingInfo>)sender
                     79: {
                     80:     NXColor c = NXReadColorFromPasteboard([sender draggingPasteboard]);
                     81:     [self setBackgroundColor: c];
                     82:     return YES;
                     83: }
                     84: /*============================================================
                     85:  * instance set / query methods
                     86:  *============================================================*/
                     87: 
                     88: - setDataSrc:anObject
                     89: {
                     90:     dataSrc = anObject;
                     91:     return self;
                     92: }
                     93: 
                     94: - setGraphType:(int)drawCode
                     95:        { COM_Flags.drawType = drawCode;  [self update]; return self; }
                     96: - (int)graphType
                     97:        { return COM_Flags.drawType; }
                     98: 
                     99: - takeRandomColorStateFrom:sender
                    100:        { [self setRandomBarColorEnabled:[sender state]]; return self; }
                    101: - setRandomBarColorEnabled:(BOOL)flag
                    102:        { COM_Flags.randomBarColors = flag; [self update]; return self; }
                    103: - (BOOL)isRandomBarColorEnabled
                    104:        { return COM_Flags.randomBarColors; }
                    105:        
                    106: - takeBackgroundColorFrom:sender
                    107:        { [self setBackgroundColor:  [sender color]]; return self; }
                    108: - setBackgroundColor:(NXColor)aColor
                    109:        {  backgroundColor = aColor; [self update]; return self; }
                    110: - (NXColor)backgroundColor
                    111:        { return backgroundColor; }
                    112:        
                    113: - takeHighlightColorFrom:sender
                    114:        { [self setHighlightColor:  [sender color]]; return self; }
                    115: - setHighlightColor:(NXColor)aColor
                    116:        {  highlightColor = aColor; [self update]; return self; }
                    117: - (NXColor)highlightColor
                    118:        { return highlightColor; }
                    119: 
                    120: 
                    121: /* set and query the size for the margins (in points) */
                    122: - takeHMarginFrom:sender
                    123:        { hMargin = [sender floatValue]; [self update]; return self; }
                    124: - takeVMarginFrom:sender
                    125:        { vMargin = [sender floatValue]; [self update]; return self; }
                    126: - (float)hMargin
                    127:        { return hMargin; }
                    128: - (float)vMargin
                    129:        { return vMargin; }
                    130: 
                    131: - takeAutoScaleStateFrom:sender
                    132:        { COM_Flags.autoScale = [sender floatValue]; return self; }
                    133: - setAutoScale:(BOOL)flag
                    134:        { COM_Flags.autoScale = flag; [self update]; return self; }
                    135: - (BOOL)autoScale
                    136:        { return COM_Flags.autoScale; }
                    137: 
                    138: /* fancy controls */
                    139: - takeFrameStateFrom:sender
                    140:        { COM_Flags.drawFrame = [sender state]; [self update]; return self; }
                    141: - (BOOL)frameState
                    142:        { return COM_Flags.drawFrame; }
                    143: 
                    144: - takeNumProtosFrom:sender
                    145:        { numPrototypes= [sender intValue]; [self update]; return self; }
                    146: - (int)numProtos
                    147:        { return numPrototypes; }
                    148: 
                    149: - takeBorderTypeFrom:sender
                    150:        { borderType = [sender tag]; [self update]; return self; }
                    151: - (int)borderType
                    152:        { return borderType; }
                    153: 
                    154: /* when autoscale is off, set the min and max for the sheet */
                    155: - takeMinValueFrom:sender
                    156:        { minSheetSet = [sender floatValue]; return self; }
                    157: - takeMaxValueFrom:sender
                    158:        { maxSheetSet = [sender floatValue]; return self; }
                    159: - (double)minValue
                    160:        { return minSheetSet; }
                    161: - (double)maxValue
                    162:        { return maxSheetSet; }
                    163: 
                    164:   
                    165: /*============================================================
                    166:  * target/action
                    167:  *============================================================*/
                    168: 
                    169: - (BOOL)acceptsFirstResponder { return YES; }
                    170: 
                    171: - copy:sender
                    172: {
                    173:        id pb = [Pasteboard new];       /* global pasteboard object */
                    174:        NXStream        *st;            /* stream to collect data in */
                    175:        char            *data;          /* actual data buffer */
                    176:        int             length;         /* length of data */
                    177:        int             maxLength;      /* (not used here) */
                    178:        
                    179:        /* declare that we will supply  a single type of data, eps */
                    180:        [pb declareTypes:&NXPostScriptPboard num:1 owner:self];
                    181:        
                    182:        /* get a stream which writes to memory */
                    183:        st = NXOpenMemory (NULL, 0, NX_WRITEONLY);
                    184:        
                    185:        /* find bounding box and then write it to the stream */
                    186:        [self copyPSCodeInside:&bounds to:st];
                    187:        
                    188:        /* get actuall data buffer form stream */
                    189:        NXGetMemoryBuffer (st, &data, &length, &maxLength);
                    190:        
                    191:        /* write data to pasteboard */
                    192:        [pb writeType:NXPostScriptPboard data:data length:length ];
                    193:        
                    194:        /* dealocate stream including it's buffer */
                    195:        NXCloseMemory (st, NX_FREEBUFFER );
                    196:        
                    197: 
                    198:     return self;
                    199: }
                    200: 
                    201: /*============================================================
                    202:  * do real work
                    203:  *============================================================*/
                    204: 
                    205: - (int)numLocations
                    206: {
                    207:     int numRows,numCols;
                    208: 
                    209:     if ([dataSrc respondsTo:@selector(getValue:forProperty:at:)]){
                    210:        return [dataSrc count];
                    211:     } else if ([dataSrc respondsTo:@selector(selectedCell)]){
                    212:        [dataSrc getNumRows:&numRows numCols:&numCols];
                    213:        return MAX(numRows,numCols);
                    214:     } else if (!dataSrc) {
                    215:        /* put up some dummy graph on palette */
                    216:        return NUM_BOGUS;
                    217:     }
                    218:     return 0;
                    219: }
                    220: 
                    221: - (float)valueOfLocation:(int)n
                    222: {
                    223:     static     float   data[NUM_BOGUS] = {.1, .3, .2, .7, .4, .8, .5, .98};
                    224:     int numRows,numCols;
                    225:     float theValue;
                    226:     id   mrValue = [[DBValue alloc] init];
                    227: 
                    228:     if ([dataSrc respondsTo:@selector(getValue:forProperty:at:)]){
                    229:        [dataSrc getValue:mrValue forProperty:mrExpression at:n];
                    230:        theValue = [mrValue floatValue];
                    231:        [mrValue free];
                    232:        return theValue;
                    233:     } else if ([dataSrc respondsTo:@selector(selectedCell)]){
                    234:        [dataSrc getNumRows:&numRows numCols:&numCols];
                    235:        if (numCols == 1) {
                    236:                return [[dataSrc cellAt:n :0] floatValue];
                    237:        } else {        /* numRows == 1 */
                    238:                return [[dataSrc cellAt:0 :n] floatValue];
                    239:        }
                    240:     } else if (!dataSrc) {
                    241:        return data[n];
                    242:     }
                    243:     
                    244:     return 0.0;
                    245: }
                    246: 
                    247: /*============================================================
                    248:  * target action loading
                    249:  *============================================================*/
                    250: 
                    251: - plotFromMatrix:sender
                    252: {
                    253:     if (!dataSrc && [sender respondsTo:@selector(selectedCell)]){
                    254:        [self setDataSrc:sender];
                    255:     } 
                    256:     [self update];
                    257:     return self;
                    258: }
                    259: 
                    260: /*============================================================
                    261:  * dbKit support
                    262:  *============================================================*/
                    263: 
                    264: - associationContentsDidChange:association
                    265: {
                    266:     mrFetchGroup =     [association fetchGroup];
                    267:     dataSrc =          [mrFetchGroup recordList];
                    268:     highlightIndex =   [mrFetchGroup currentRecord];
                    269:     mrExpression =     [association expression];
                    270:     [self update];
                    271:     return self;
                    272: }
                    273: 
                    274: /*
                    275: ** adh 7/27/92
                    276: ** Do this so we redraw when values are updated in the UI
                    277: */
                    278: - association:association setValue:(DBValue *)value
                    279: {
                    280:     return [self update];
                    281: }
                    282: 
                    283: - associationSelectionDidChange:association
                    284: {
                    285:     /* assume fetchgroup doesn't change so don't update mrFetchGroup */
                    286:     highlightIndex =  [[association fetchGroup] currentRecord];
                    287:     return [self update];
                    288: }
                    289: 
                    290: - associationCurrentRecordDidDelete:association
                    291: {
                    292:     /* assumes record list is the same */
                    293:     return [self update];
                    294:     return self;
                    295: }
                    296: 
                    297: /*============================================================
                    298:  * do a selection with the mouse
                    299:  *============================================================*/
                    300:  
                    301: - mouseDown:(NXEvent *)theEvent
                    302: {
                    303:     NXEvent    lastEvent;
                    304:     NXRect     rectOfBar;
                    305:     NXRect     drawRect;
                    306:     int        longSize = [self numLocations];
                    307:     int                index;
                    308: 
                    309:     
                    310:     if ((COM_Flags.drawType != DRAW_H_BAR && 
                    311:                        COM_Flags.drawType != DRAW_V_BAR ) ||
                    312:                ![dataSrc respondsTo:@selector(getValue:forProperty:at:)]) {
                    313:        NXBeep();
                    314:        return nil;
                    315:     }
                    316:     
                    317:     lastEvent = *theEvent;
                    318:     [self convertPoint: &lastEvent.location fromView:nil];
                    319:     /* modify the mouse position to be in psuedo drawing area coords */
                    320:     lastEvent.location.x -= hMargin;
                    321:     lastEvent.location.y -= vMargin;
                    322: 
                    323:     /* allow for the margins when calc'ing the bar moused down on */
                    324:     drawRect = bounds;
                    325:     drawRect.origin.x +=       hMargin;
                    326:     drawRect.origin.y +=       vMargin;
                    327:     drawRect.size.width -=     (2*hMargin);
                    328:     drawRect.size.height -=    (2*vMargin);
                    329:     
                    330:     for ( index = 0 ; index < longSize; index++){
                    331:        if (COM_Flags.drawType == DRAW_V_BAR) {
                    332:                [self calcRect:&rectOfBar ofBar:index
                    333:                        insideRect:&drawRect
                    334:                        usingMin:NX_Y(&bounds) ];
                    335:                rectOfBar.origin.y = bounds.origin.y;
                    336:                rectOfBar.size.height = bounds.size.height;
                    337:        } else  if (COM_Flags.drawType == DRAW_H_BAR) {
                    338:                [self calcRect:&rectOfBar ofBar:index
                    339:                        insideRect:&drawRect
                    340:                        usingMin:NX_X(&bounds) ];
                    341:                rectOfBar.origin.x = bounds.origin.x;
                    342:                rectOfBar.size.width = bounds.size.width;
                    343:        } else {
                    344:                return nil;
                    345:        }
                    346:        if ([self mouse:&lastEvent.location inRect:&rectOfBar]){
                    347:                [mrFetchGroup setCurrentRecord:index];
                    348:                break;
                    349:        }
                    350:     }
                    351:     return self;
                    352: } 
                    353: 
                    354: /*============================================================
                    355:  * target/action
                    356:  *============================================================*/
                    357: 
                    358: - read:(NXTypedStream *)stream
                    359: {
                    360:         int tmpScale, tmpDrawFrame, tmpDrawType;
                    361:        [super read:stream];
                    362:        dataSrc =  NXReadObject(stream);
                    363:        minField = NXReadObject(stream);
                    364:        maxField =  NXReadObject(stream);
                    365:        meanField = NXReadObject(stream);
                    366:        /* the first demo palette went out as version 1 */
                    367:        if (NXTypedStreamClassVersion(stream, "ChartOfMatrix")<2) {
                    368:                NXReadTypes(stream,"ffffiii",
                    369:                                        &minSheetSet,&maxSheetSet,
                    370:                                        &vMargin,&hMargin,
                    371:                                        &tmpScale,
                    372:                                        &tmpDrawType,
                    373:                                        &tmpDrawFrame);
                    374:                COM_Flags.autoScale = tmpScale;
                    375:                COM_Flags.drawType = tmpDrawType;
                    376:                COM_Flags.drawFrame = tmpDrawFrame;
                    377:                COM_Flags.randomBarColors = YES;
                    378:        } else {
                    379:                NXReadTypes(stream,"ffffi",
                    380:                                        &minSheetSet,&maxSheetSet,
                    381:                                        &vMargin,&hMargin,
                    382:                                        &COM_Flags);
                    383:        }
                    384:        
                    385:        backgroundColor = NXReadColor(stream);
                    386:        highlightColor = NXReadColor(stream);
                    387:        NXReadTypes(stream,"ii",
                    388:                                        &numPrototypes,
                    389:                                        &borderType);
                    390:        return self;
                    391: }
                    392: 
                    393: - write:(NXTypedStream *)stream
                    394: {
                    395:        [super write:stream];
                    396:        NXWriteObjectReference(stream, dataSrc);
                    397:        NXWriteObjectReference(stream, minField);
                    398:        NXWriteObjectReference(stream, maxField);
                    399:        NXWriteObjectReference(stream, meanField);
                    400:        NXWriteTypes(stream,"ffffi",
                    401:                                        &minSheetSet,&maxSheetSet,
                    402:                                        &vMargin,&hMargin,
                    403:                                        &COM_Flags);
                    404:        NXWriteColor(stream,            backgroundColor);
                    405:        NXWriteColor(stream,            highlightColor);
                    406:        NXWriteTypes(stream,"ii",
                    407:                                        &numPrototypes,
                    408:                                        &borderType);
                    409:        return self;
                    410: }
                    411: 
                    412: /*============================================================
                    413:  *display
                    414:  *============================================================*/
                    415: 
                    416: - calcMin:(float *)rMin andMax:(float *)rMax andMean:(float *)rMean;
                    417: {
                    418:        int     index;
                    419:        int     longSize;
                    420:        float   thisVal;
                    421:        float   sumAll = 0;
                    422: 
                    423:        *rMin = *rMax = [self valueOfLocation:0];
                    424:        longSize = [self numLocations];
                    425: 
                    426:        /* first figure out what the maxs and mins are */
                    427:        for ( index = 0 ; index < longSize; index++){
                    428:                thisVal = [self valueOfLocation:index];
                    429:                if (*rMin > thisVal)            *rMin = thisVal;
                    430:                if (*rMax < thisVal)            *rMax = thisVal;
                    431:                sumAll += thisVal;
                    432:        }
                    433:        *rMean = sumAll / longSize;
                    434:        
                    435:        [minField setFloatValue:*rMin];
                    436:        [maxField setFloatValue:*rMax];
                    437:        [meanField setFloatValue:*rMean];
                    438:        return self;
                    439: }
                    440: 
                    441: - renderVLines:(NXRect *)r  min:(float )minSheetVal max:(float )maxSheetVal
                    442: {
                    443:        int     longSize;       /* numRows or numCols, whichever is the long side */
                    444:        int     index;
                    445:        float   thisVal;
                    446:        float   cellWidth;      /* the width of a unit (N) to plot */
                    447: 
                    448:        /* scale the plot */
                    449:        PSscale(1.0, r->size.height / ( maxSheetVal - minSheetVal) );
                    450:        PStranslate(0.0, -minSheetVal);
                    451:                
                    452:        longSize = [self numLocations];
                    453:        cellWidth = r->size.width / (longSize);
                    454: 
                    455:        /* now plot each square */
                    456:        PSsetgray(NX_BLACK);
                    457:        thisVal = [self valueOfLocation:0];
                    458:        PSmoveto(cellWidth/2.0, thisVal);
                    459:        for ( index = 0 ; index < longSize; index++){
                    460:                thisVal = [self valueOfLocation:index];
                    461:                PSlineto(cellWidth*index+ cellWidth/2.0, thisVal);
                    462:        }
                    463:        PSstroke();
                    464:        return self;
                    465: }
                    466: 
                    467: /* we can position the bars anywhere inside the view by changing the
                    468:  * insideRect parameter 
                    469:  */
                    470: - calcRect:(NXRect *)r 
                    471:        ofBar:(int)n 
                    472:        insideRect:(NXRect *)boundingRect
                    473:        usingMin:(float)minSheetVal 
                    474: {
                    475:     float      thisVal;
                    476:     float      cellWidth;      /* width of a unit (N) to plot */
                    477: 
                    478:     thisVal = [self valueOfLocation:n];
                    479:     if (COM_Flags.drawType == DRAW_V_BAR){
                    480:        cellWidth = boundingRect->size.width / (3 * [self numLocations] + 1);
                    481:        r->origin.x = n * 3 * cellWidth + cellWidth;
                    482:        if (thisVal < 0.0){
                    483:                                r->origin.y = thisVal;
                    484:                                r->size.height = -thisVal;
                    485:        }else{
                    486:                                r->origin.y = MAX(minSheetVal, 0.0);
                    487:                                r->size.height= thisVal-r->origin.y;
                    488:        }
                    489:        r->size.width = 2 * cellWidth;
                    490:     } else /* assume h bar */ {
                    491:        cellWidth = boundingRect->size.height / (3 * [self numLocations] + 1);
                    492:        r->origin.y = n * 3 * cellWidth + cellWidth;
                    493:        if (thisVal < 0.0){
                    494:                                r->origin.x = thisVal;
                    495:                                r->size.width = -thisVal;
                    496:        }else{
                    497:                                r->origin.x = MAX(minSheetVal, 0.0);
                    498:                                r->size.width= thisVal - r->origin.x;
                    499:        }
                    500:        r->size.height = 2 * cellWidth;
                    501:     }
                    502: 
                    503:     return self;
                    504: }
                    505: 
                    506: /* this should probably be empty but because Kris asked for a bar/lines switch 
                    507:  * in the inspectorwe have the abillity to draw bars (vertical).  Of course  
                    508:  * this makes the vertical bar drawing object almost codeless
                    509:  */
                    510: - renderBars:(NXRect *)r min:(float )minSheetVal max:(float )maxSheetVal
                    511: {
                    512:        int     longSize;       /* numRows/numCols, whichever is long side */
                    513:        int     index;
                    514:        NXRect  barRect;        /* bounding rectangle for bar in the chart */
                    515:        NXColor HSBColor;       /* in case randomBarColors */
                    516: 
                    517:        longSize = [self numLocations];
                    518:        if (COM_Flags.drawType == DRAW_V_BAR){
                    519:                /* scale the plot */
                    520:                PSscale(1.0, r->size.height / ( maxSheetVal - minSheetVal) );
                    521:                PStranslate(0.0, -minSheetVal);
                    522:        } else /* assume h bar */ {
                    523:                /* scale the plot */
                    524:                PSscale(r->size.width / ( maxSheetVal - minSheetVal), 1.0 );
                    525:                PStranslate( -minSheetVal, 0.0);
                    526:        }
                    527:                
                    528:        /* now plot each square */
                    529:        for ( index = 0 ; index < longSize; index++){
                    530:                if (index == highlightIndex)
                    531:                        NXSetColor(highlightColor);
                    532:                else if (!COM_Flags.randomBarColors) {
                    533:                        PSsetgray ((1.0 / (longSize+2.0)) * (index +1));
                    534:                } else {
                    535:                        HSBColor = NXConvertHSBToColor(
                    536:                                ((float)index / (float)longSize), 
                    537:                                1.0, 1.0);
                    538:                        NXSetColor(HSBColor);
                    539:                }
                    540:                [self calcRect:&barRect ofBar:index
                    541:                        insideRect:(NXRect *)r
                    542:                        usingMin:minSheetVal];
                    543:                NXRectFill(&barRect);
                    544:        }
                    545:        return self;
                    546: }
                    547: 
                    548: 
                    549: /* spacing:    Each plot is a width of 2N and each gap is a width of 1N
                    550:  *             total width is m*(2N+N) + N  = 3mN+N = where m = number of bars
                    551:  *             Thus N = width / (3m+1)
                    552:  *
                    553:  * scaling:    The scaling can make some stuff look pretty funny.  
                    554:  */
                    555: - drawSelf:(NXRect *)r :(int)c
                    556: {      
                    557:     float      minCellVal, maxCellVal; /* min & max of values to be plotted */
                    558:     float      meanCellVal;            /* mean of the plotted values */
                    559:     float      minSheetVal,maxSheetVal;/* RangeOfNumbers will plot in graph */
                    560:     NXRect     rectOfPlot;             /* bounds of rect that will hold plot */
                    561:     NXSetColor(backgroundColor);
                    562:     NXRectFill(&bounds);
                    563:     PSsetgray(NX_BLACK);
                    564:     switch     (borderType) {
                    565:        case    NX_LINE:
                    566:                        NXFrameRect(&bounds);
                    567:                        break;
                    568:        case    NX_BEZEL:
                    569:                        NXDrawWhiteBezel(&bounds,&bounds);
                    570:                        break;
                    571:        case    NX_GROOVE:
                    572:                        NXDrawGroove(&bounds, &bounds);
                    573:                        break;
                    574:        default:        break;
                    575:     }
                    576:     rectOfPlot= bounds;
                    577:     rectOfPlot.origin.x += hMargin;
                    578:     rectOfPlot.origin.y += vMargin;
                    579:     rectOfPlot.size.width -=2*hMargin;
                    580:     rectOfPlot.size.height -=2*vMargin;
                    581:     if (               NX_WIDTH(&bounds) < (2*hMargin) || 
                    582:                        NX_HEIGHT(&bounds) < (2*vMargin) ) 
                    583:                return self;
                    584:                
                    585:        
                    586:     [window disableFlushWindow];
                    587:     PSgsave();
                    588:     PSsetlinewidth(0.0);
                    589:     PStranslate (hMargin, vMargin);
                    590:     
                    591:     if (YES){
                    592:        /* great we only have a single axis to work on */
                    593:        [self calcMin:&minCellVal andMax:&maxCellVal andMean:&meanCellVal];
                    594: 
                    595:        if (COM_Flags.autoScale){
                    596:                /* give us a plot if they are all the same (but not 0.0)  */
                    597:                if (minCellVal == maxCellVal){
                    598:                                if (minCellVal > 0.0)   minCellVal = 0.0;
                    599:                                else if (maxCellVal < 0.0) maxCellVal = 0.0;
                    600:                }
                    601:                
                    602:                /* figure out what min and the max should be on the sheet */
                    603:                if (minCellVal == 0.0)  minSheetVal= 0.0;
                    604:                else minSheetVal= minCellVal - ((maxCellVal - minCellVal)*0.2);
                    605:                /* we shouldn't have pushed this across the origin */
                    606:                if (minSheetVal < 0.0 && minCellVal > 0.0) minSheetVal = 0.0;
                    607:                
                    608:                if (maxCellVal == 0.0)  maxSheetVal = 0.0;
                    609:                else maxSheetVal= maxCellVal +((maxCellVal - minCellVal)* 0.2);
                    610:                /* make sure we didn't go across the origin */
                    611:                if (maxSheetVal > 0.0 && maxCellVal < 0.0) maxSheetVal = 0.0;
                    612:        } else {
                    613:                minSheetVal = minSheetSet;
                    614:                maxSheetVal = maxSheetSet;
                    615:        }
                    616:                
                    617:        switch(COM_Flags.drawType){
                    618:        case    DRAW_H_BAR:
                    619:        case    DRAW_V_BAR:
                    620:                [self renderBars:&rectOfPlot min:minSheetVal max:maxSheetVal];
                    621:                break;
                    622:        case    DRAW_H_LINE:
                    623:                break;
                    624:        case    DRAW_V_LINE:
                    625:                [self renderVLines:&rectOfPlot min:minSheetVal max:maxSheetVal ];
                    626:                break;
                    627:        default:
                    628:                break;
                    629:        }
                    630: 
                    631:        PSgrestore();
                    632:        if (COM_Flags.drawFrame){
                    633:                PSsetgray(NX_BLACK);
                    634:                NXFrameRect(&rectOfPlot);
                    635:        }
                    636:     }
                    637:     [window reenableFlushWindow];
                    638:     return self;
                    639: }
                    640: 
                    641: @end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.