Received: by ATHENA-PO-3.MIT.EDU (5.45/4.7) id AA20257; Fri, 12 Apr 91 03:22:28 EST
Received: from munnari.OZ.AU by ATHENA.MIT.EDU with SMTP
	id AA23329; Fri, 12 Apr 91 04:21:08 EDT
Received: from melba.bby.oz (via ditmela) by munnari.oz.au with SunIII (5.64+1.3.1+0.50)
	id AA19126; Fri, 12 Apr 1991 18:20:58 +1000 (from gnb%bby.oz.au@melba.bby.oz.au)
Received: from baby.bby.oz.au by melba.bby.oz.au (4.0/SMI-4.0/BBY)
	id AA06635; Fri, 12 Apr 91 14:25:34 EST
       (from gnb@bby.oz.au for bug-at%athena.mit.edu@munnari.oz)
Received: by baby.bby.oz.au (4.1/SMI-4.1)
	id AA04428; Fri, 12 Apr 91 14:25:26 EST
Message-Id: <9104120425.AA04428@baby.bby.oz.au>
To: bug-at@ATHENA.MIT.EDU
Subject: AtAxis bugs/enhancements
Date: Fri, 12 Apr 91 14:25:19 +1000
From: Gregory Bond <gnb@bby.oz.au>

Guys,

A set of diffs for the Axis widget that fix a few bugs and add a new
facility.

Bugs Fixed:

1) The ticMultiplier resource was never used.  It is now used to
   calculate labels.

2) A coredump in the SetValues routine that accessed ticLabels when
   none had been set.

3) A coredump cuased by ntics overflowing in the following scenario:
   Using framed axes, Yaxis runs from 0-300,000.  AtPlotterLayout
   calls AtAxisChangeBounds, which forces a RecalcNumTics, with
   ticInterval at the default 0.5.  This translates to 600,000 tics,
   ntics (a short int) overflows to a negative number, and we try and
   XtRealloc a negative number of doubles!  Fix is to not change ntics
   if it is negative or too large, on the assumption that an
   AtAxisChangeNumbering will immediatly follow to change ticInterval
   and call RecalcNumTics again.

4) Was using a fixed number for tic length in the space calculation
   code.  Changed to use the ticLength resource.

Enhancements:

1) Many fixes to make the flexible axis selection work.  (This allows
   selection of Y and X axes in the same way that showY2Axis currently
   works, but uses a different mechanism).   Full use of this requires
   the changes to Plotter.c which I will send a little later.

2) A new resource: "numbersOutside".  If true (the default), then
   numbers will appear outside the graph area.  Otherwise, they will
   appear inside the graph area.  Will also probably need the changes
   to Plotter.c to make it all work properly (in particular, the Y2
   axis should now be mirrored.

This changes the size of the Axis instance record by adding one Boolean.

Greg.
-- 
Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia
Internet: gnb@melba.bby.oz.au    non-MX: gnb%melba.bby.oz@uunet.uu.net
Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb

*** /tmp/,RCSt1a10341	Fri Apr 12 12:08:20 1991
--- Axis.c	Fri Apr 12 10:47:33 1991
***************
*** 103,108 ****
--- 103,110 ----
       sizeof(Boolean), offset(axis.ticsOutside), XtRImmediate, (caddr_t)True},
    {XtNticsInside, XtCTicsInside, XtRBoolean,
       sizeof(Boolean), offset(axis.ticsInside), XtRImmediate, (caddr_t)False},
+   {XtNnumbersOutside, XtCNumbersOutside, XtRBoolean,
+      sizeof(Boolean), offset(axis.numbersOutside), XtRImmediate, (caddr_t)True},
    {XtNticLength, XtCTicLength, XtRShort,
       sizeof(short), offset(axis.ticLength), XtRImmediate, (caddr_t)5},
    {XtNsubticLength, XtCTicLength, XtRShort,
***************
*** 446,452 ****
    }
      
    if (Changed(min) || Changed(max) || Changed(transform) ||
!       Changed(ticDensity) ||Changed(subticDensity) || Changed(autoNumber) ||
        (!new->axis.autoNumber && (Changed(ticInterval)||Changed(subtics)))) {
      if (!new->axis.autoNumber) RecalcNumTics(new);
      compticspacing = True;
--- 448,455 ----
    }
      
    if (Changed(min) || Changed(max) || Changed(transform) ||
!       Changed(numbersOutside) || Changed(ticDensity) ||
!       Changed(subticDensity) || Changed(autoNumber) || 
        (!new->axis.autoNumber && (Changed(ticInterval)||Changed(subtics)))) {
      if (!new->axis.autoNumber) RecalcNumTics(new);
      compticspacing = True;
***************
*** 462,468 ****
  
    if (Changed(drawGrid)) redraw = True;
  
!   if (Changed(ticLabels) || (strcmp(new->axis.ticLabels, 
  				    new->axis.ticlabelcpy)))  {
      for (i = 0; i < new->axis.nuserticlabels; i++)
        XtFree(new->axis.userticlabels[i]);
--- 465,472 ----
  
    if (Changed(drawGrid)) redraw = True;
  
!   if (Changed(ticLabels) || (new->axis.ticLabels && 
! 			     strcmp(new->axis.ticLabels,
  				    new->axis.ticlabelcpy)))  {
      for (i = 0; i < new->axis.nuserticlabels; i++)
        XtFree(new->axis.userticlabels[i]);
***************
*** 580,586 ****
        if (a->vertical) {
  	x = a->x1;
  	y = a->ticcoords[i];
! 	if (a->mirror) 
  	  x += bt2 + 2;
  	else
  	  x -= bt1 + 2 + wid;
--- 584,590 ----
        if (a->vertical) {
  	x = a->x1;
  	y = a->ticcoords[i];
! 	if (!a->mirror ^ !!a->numbersOutside) 
  	  x += bt2 + 2;
  	else
  	  x -= bt1 + 2 + wid;
***************
*** 589,595 ****
        else {
  	x = a->ticcoords[i];
  	y = a->y1;
! 	if (a->mirror)
  	  y -= bt1 + 2 + a->numberFont->descent;
  	else
  	  y += bt2 + 2 + a->numberFont->ascent;
--- 593,599 ----
        else {
  	x = a->ticcoords[i];
  	y = a->y1;
! 	if (!a->mirror ^ !!a->numbersOutside)
  	  y -= bt1 + 2 + a->numberFont->descent;
  	else
  	  y += bt2 + 2 + a->numberFont->ascent;
***************
*** 700,705 ****
--- 704,715 ----
    else
      axis->ntics = 1+(int)((log10(axis->max) - log10(axis->min))
  			  * 10.0/w->axis.ticInterval);
+ 
+   if (w->axis.ntics < 0 || w->axis.ntics > 10000) {
+     /* Obviously a major error - we hope an ensuing call to
+        AtAxisChangeNumbering will alter ticInterval! */
+     w->axis.ntics = oldntics;
+   }
    
    if (w->axis.ntics != oldntics) {
      axis->ticvalues = (double *)XtRealloc(axis->ticvalues,
***************
*** 929,935 ****
      if (axis->nuserticlabels)
        strcpy(buf, (i < axis->nuserticlabels ? axis->userticlabels[i] : ""));
      else
!       sprintf(buf, axis->ticFormat, axis->ticvalues[i]);
      len = strlen(buf);
      if (axis->ticlabels[i] != NULL) XtFree(axis->ticlabels[i]);
      axis->ticlabels[i] = strcpy(XtMalloc(len+1), buf);
--- 939,945 ----
      if (axis->nuserticlabels)
        strcpy(buf, (i < axis->nuserticlabels ? axis->userticlabels[i] : ""));
      else
!       sprintf(buf, axis->ticFormat, axis->ticvalues[i] * axis->ticMultiplier);
      len = strlen(buf);
      if (axis->ticlabels[i] != NULL) XtFree(axis->ticlabels[i]);
      axis->ticlabels[i] = strcpy(XtMalloc(len+1), buf);
***************
*** 942,961 ****
  /**********************************************************************/
  /*
   * returns the "width" (the height if horizontal) of the passed axis.
   */
  int AtAxisWidth(AtAxisObject w)
  {
    if (w->axis.vertical) {
      return ((w->axis.labelText) ? AtTextWidth(w->axis.labelText) : 0) +
!       ((w->axis.drawNumbers) ? w->axis.maxnumwidth : 0) +
! 	((w->axis.ticsOutside) ? TIC_LINE_LENGTH + 1 : 0) +
! 	  MIN_MARGIN;
    }
    else {
      return ((w->axis.labelText) ? AtTextHeight(w->axis.labelText) : 0) + 
!       ((w->axis.drawNumbers) ?
!        w->axis.numberFont->ascent+ w->axis.numberFont->descent :0) +
! 	 ((w->axis.ticsOutside) ? TIC_LINE_LENGTH + 1 : 0) +
  	   MIN_MARGIN;
    }
  }
--- 952,973 ----
  /**********************************************************************/
  /*
   * returns the "width" (the height if horizontal) of the passed axis.
+  * Only considers that part of the label marked "outside".
   */
  int AtAxisWidth(AtAxisObject w)
  {
    if (w->axis.vertical) {
      return ((w->axis.labelText) ? AtTextWidth(w->axis.labelText) : 0) +
!       ((w->axis.drawNumbers && w->axis.numbersOutside) ?
!        w->axis.maxnumwidth : 0) +
! 	 ((w->axis.ticsOutside) ? w->axis.ticLength + 1 : 0) +
! 	   MIN_MARGIN;
    }
    else {
      return ((w->axis.labelText) ? AtTextHeight(w->axis.labelText) : 0) + 
!       ((w->axis.drawNumbers && w->axis.numbersOutside) ?
!        w->axis.numberFont->ascent+ w->axis.numberFont->descent : 0) +
! 	 ((w->axis.ticsOutside) ? w->axis.ticLength + 1 : 0) +
  	   MIN_MARGIN;
    }
  }
***************
*** 1065,1067 ****
--- 1077,1084 ----
    else
      XtWarning(errortext);
  }
+ /*
+  * Local Variables:
+  * eval: (set-c-style 'GNU)
+  * End:
+  */
*** /tmp/,RCSt1a10341	Fri Apr 12 12:08:21 1991
--- Axis.h	Wed Apr 10 10:33:30 1991
***************
*** 45,50 ****
--- 45,51 ----
  #define XtNdrawNumbers "drawNumbers"    
  #define XtNdrawGrid "drawGrid"
  #define XtNticsOutside "ticsOutside"
+ #define XtNnumbersOutside "numbersOutside"
  #define XtNautoNumber "autoNumber"
  #define XtNticInterval "ticInterval"
  #define XtNsubtics "subtics"    
***************
*** 71,76 ****
--- 72,78 ----
  #define XtCDrawNumbers "DrawNumbers"    
  #define XtCDrawGrid "DrawGrid"
  #define XtCTicsOutside "TicsOutside"
+ #define XtCNumbersOutside "NumbersOutside"
  #define XtCAutoNumber "AutoNumber"
  #define XtCTicInterval "TicInterval"
  #define XtCSubtics "Subtics"    
*** /tmp/,RCSt1a10465	Fri Apr 12 14:09:48 1991
--- AxisP.h	Thu Apr 11 08:39:56 1991
***************
*** 71,76 ****
--- 71,77 ----
      String ticFormat;
      Boolean ticsOutside;
      Boolean ticsInside;
+     Boolean numbersOutside;
      short ticLength;
      short subticLength;
      String ticLabels;
***************
*** 122,128 ****
  extern AtAxisClassRec atAxisClassRec;
  
  #define MIN_MARGIN       5
- #define TIC_LINE_LENGTH  5
- #define SHORT_TIC_LINE_LENGTH 3
  
  #endif
--- 123,127 ----
*** /tmp/,RCSt1a10476	Fri Apr 12 14:10:08 1991
--- AxisPS.c	Thu Apr 11 09:29:59 1991
***************
*** 42,58 ****
   */
  int AtAxisWidthPS(AtAxisObject w)
  {
!     if (w->axis.vertical) {
! 	return ((w->axis.labelText) ? AtTextPSWidth(w->axis.labelText) : 0) +
! 	    MIN_MARGIN +  w->axis.maxnumwidth + TIC_LINE_LENGTH + 1;
!     }
!     else {
! 	return ((w->axis.labelText) ?
! 		(AtTextPSAscent(w->axis.labelText) +
! 		 AtTextPSDescent(w->axis.labelText)) : 0) + 
! 		     MIN_MARGIN + w->axis.numberFont->ascent +
! 			 w->axis.numberFont->descent + TIC_LINE_LENGTH + 1;
!     }
  }
  			   
  
--- 42,60 ----
   */
  int AtAxisWidthPS(AtAxisObject w)
  {
!   if (w->axis.vertical) {
!     return (w->axis.labelText ? AtTextPSWidth(w->axis.labelText) : 0) +
!       (w->axis.drawNumbers && w->axis.numbersOutside ?
!        w->axis.maxnumwidth : 0) +
! 	MIN_MARGIN + w->axis.ticLength + 1;
!   } else {
!     return (w->axis.labelText ? 
! 	    AtTextPSAscent(w->axis.labelText) +
! 	    AtTextPSDescent(w->axis.labelText) : 0) +
! 	      (w->axis.drawNumbers && w->axis.numbersOutside ?
! 	       w->axis.numberFont->ascent + w->axis.numberFont->descent : 0) +
! 		 MIN_MARGIN + w->axis.ticLength + 1;
!   }
  }
  			   
  
***************
*** 188,194 ****
  		x = x1;
  		/* y = a->ticcoords[i];*/
  		y = AtScaleUserToPixel(scale, a->ticvalues[i]) / 100;
! 		if (a->mirror) 
  		    x += bt2 + 2;
  		else
  		    x -= bt1 + 2 + wid;
--- 190,196 ----
  		x = x1;
  		/* y = a->ticcoords[i];*/
  		y = AtScaleUserToPixel(scale, a->ticvalues[i]) / 100;
! 		if (!a->mirror ^ !!a->numbersOutside) 
  		    x += bt2 + 2;
  		else
  		    x -= bt1 + 2 + wid;
***************
*** 198,204 ****
  		/*x = a->ticcoords[i];*/
  		x = AtScaleUserToPixel(scale, a->ticvalues[i]) / 100;
  		y = y1;
! 		if (a->mirror)
  		    y += bt1 + 2 + descent(a);
  		else
  		    y -= bt2 + 2 + ascent(a);
--- 200,206 ----
  		/*x = a->ticcoords[i];*/
  		x = AtScaleUserToPixel(scale, a->ticvalues[i]) / 100;
  		y = y1;
! 		if (!a->mirror ^ !!a->numbersOutside)
  		    y += bt1 + 2 + descent(a);
  		else
  		    y -= bt2 + 2 + ascent(a);
*** /tmp/AtAxis.man	Fri Apr 12 14:21:30 1991
--- AtAxis.man	Fri Apr 12 14:21:30 1991
***************
*** 65,70 ****
--- 65,71 ----
  XtNticsInside	Boolean	False
  XtNticLength	short	5
  XtNsubticLength	short	2
+ XtNnumbersOutside	Boolean	True
  XtNaxisNeedsRedraw	XtCallbackList	NULL
  XtNerrorCallback	XtCallbackList	NULL
  .TE
***************
*** 206,211 ****
--- 207,219 ----
  Specifies the length of pixels of a subtic. This many pixels are drawn
  on the "outside" or "inside" of the axis, or both, or neither depending
  on the state of the XtNticsOutside and XtNticsInside resources.
+ 
+ .IP XtNnumbersOutside
+ Specifies that the numbers for labelling this axis should appear
+ outside the graph proper. Setting this to False will place the numbers
+ inside the graph area, where they may be over-written by the graph
+ data.  This may be preferable to maximise the amount of area for the
+ graph.
  
  .IP XtNaxisNeedsRedraw
  Specifies procedures to be called when the axis should be redrawn
