Received: by ATHENA-PO-3.MIT.EDU (5.45/4.7) id AA10450; Fri, 5 Apr 91 00:23:30 EST
Received: from munnari.OZ.AU by ATHENA.MIT.EDU with SMTP
	id AB08475; Fri, 5 Apr 91 00:23:09 EST
Received: from melba.bby.oz (via ditmela) by munnari.oz.au with SunIII (5.64+1.3.1+0.50)
	id AA05816; Fri, 5 Apr 1991 15:22:55 +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 AA00706; Fri, 5 Apr 91 12:46:09 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 AA14634; Fri, 5 Apr 91 12:46:01 EST
Message-Id: <9104050246.AA14634@baby.bby.oz.au>
To: bug-at@ATHENA.MIT.EDU
Subject: AtPlotter bug-of-the-day club: barcharts and non-integer xvalues
Date: Fri, 05 Apr 91 12:45:58 +1000
From: Gregory Bond <gnb@bby.oz.au>

Barchart widgets fail in a horrible way if the x axis is not integer
data, or at least large in span, due to assumptions made in the
calculation of the X values. (or, the error was to add 1 to the span
of the X axis, not subtract one from the number of chunks to cut it
into!)

The following patch seems to fix it.  I have not looked at the
FBarchart so I can't tell if that needs similar fixes.

Re the displayed constraint resource: I shall look at that today
(Friday) or Monday.  I expect at this point that I will rip out all
the distinction between bargraphs and linegraphs, and rely on
application writers to use creation order or rankChildren to get the
right overlay behaviour.  Much simpler all round.  If there is some
major reason why this is a bad idea (and I am not too convinced that
backwards compatability is a sufficient reason) then speak now....

Greg, slowly slowly plotty graphy.

*** ../tmp/Barchart.c	Tue Mar 19 03:44:48 1991
--- Barchart.c	Fri Apr  5 12:32:37 1991
***************
*** 279,289 ****
       */
  
    if (NEW.numPoints > 0) 
!     NEW.xIncrement = ((NEW.xMax - NEW.xMin) + 1) / NEW.numPoints;
  
!   for (i=0, tempx=NEW.xMin; i < NEW.numPoints;
         i++, tempx += NEW.xIncrement)
!     NEW.xpts[i] = tempx - NEW.halfdensity;
  
    NEW.ypts = (double *) XtMalloc(sizeof(double) * NEW.numPoints);
    
--- 279,290 ----
       */
  
    if (NEW.numPoints > 0) 
!     NEW.xIncrement = ((NEW.xMax - NEW.xMin)) / (NEW.numPoints - 1);
  
!   for (i=0, tempx=NEW.xMin - NEW.halfdensity * NEW.xIncrement; 
!        i < NEW.numPoints;
         i++, tempx += NEW.xIncrement)
!     NEW.xpts[i] = tempx;
  
    NEW.ypts = (double *) XtMalloc(sizeof(double) * NEW.numPoints);
    
***************
*** 311,316 ****
--- 312,329 ----
    XtSetArg(a, XtNautoScale, &autoS);
    XtGetValues(XtParent((Widget) new), &a, 1);
  
+   if (Changed(density)) {
+     if (NEW.density < 0.0) {
+       AtWarning(new, "AtBarchart: density can not be less than zero.");
+       NEW.density = 0.0;
+     }
+     if (NEW.density > 1.0) {
+       AtWarning(new, "AtBarchart: density can not be greater than one.");
+       NEW.density = 1.0;
+     }
+     NEW.halfdensity = NEW.density / 2;
+   }
+ 
    if (Changed(numPoints)) {
      XtFree(NEW.xpts);
      XtFree(NEW.ypts);
***************
*** 322,372 ****
      NEW.ypts = (double *)XtMalloc(sizeof(double) * NEW.numPoints);
  
      if (NEW.numPoints > 0) 
!       NEW.xIncrement = ((NEW.xMax - NEW.xMin) + 1) / NEW.numPoints;
      else
        AtWarning(new, "AtBarchart: numPoints must be greater than zero");
-     for (i=0, tempx=NEW.xMin; i < NEW.numPoints;
-          i++, tempx += NEW.xIncrement)
-       NEW.xpts[i] = tempx - NEW.halfdensity;
  
      bcopy((char *)NEW.yPoints, (char *)NEW.ypts,
            sizeof(double) * NEW.numPoints);
- 
-     NEW.valid = False;
-     SetBoundingBox(new);
-     new->plot.redisplay = True; /* refresh all plots. */
    }
-   
-   if (Changed(density)) {
-     if (NEW.density < 0.0) {
-       AtWarning(new, "AtBarchart: density can not be less than zero.");
-       NEW.density = 0.0;
-     }
-     if (NEW.density > 1.0) {
-       AtWarning(new, "AtBarchart: density can not be greater than one.");
-       NEW.density = 1.0;
-     }
-     NEW.halfdensity = NEW.density / 2;
  
!     for (i=0, tempx=NEW.xMin; i < NEW.numPoints;
           i++, tempx += NEW.xIncrement)
!       NEW.xpts[i] = tempx - NEW.halfdensity;
!     
      NEW.valid = False;
      SetBoundingBox(new);
-     new->plot.redisplay = True; /* refresh all plots */
-   }
- 
-   if (Changed(xMin) || Changed(xMax)) {
-     if (NEW.numPoints > 0) 
-       NEW.xIncrement = ((NEW.xMax - NEW.xMin) + 1) / NEW.numPoints;
-     else
-       AtWarning(new, "AtBarchart: numPoints must be greater than zero\n");
-     for (i=0, tempx=NEW.xMin; i < NEW.numPoints;
- 	 i++, tempx += NEW.xIncrement)
-       NEW.xpts[i] = tempx-NEW.halfdensity;
-     NEW.valid = False;
-     SetBoundingBox(new);
      new->plot.redisplay = True; /* refresh all plots. NOTE, we may
  				   want to change this later to 
  				   refresh only this plot if no autoS.
--- 335,358 ----
      NEW.ypts = (double *)XtMalloc(sizeof(double) * NEW.numPoints);
  
      if (NEW.numPoints > 0) 
!       NEW.xIncrement = ((NEW.xMax - NEW.xMin) + 1) / (NEW.numPoints - 1);
      else
        AtWarning(new, "AtBarchart: numPoints must be greater than zero");
  
      bcopy((char *)NEW.yPoints, (char *)NEW.ypts,
            sizeof(double) * NEW.numPoints);
    }
  
!   if (Changed(numPoints) || Changed(density) ||	Changed(xMin) ||
!       Changed(xMax)) {
!     if (NEW.numPoints > 0) 
!       NEW.xIncrement = (NEW.xMax - NEW.xMin) / (NEW.numPoints - 1);
!     for (i=0, tempx=NEW.xMin - NEW.halfdensity * NEW.xIncrement; 
!          i < NEW.numPoints;
           i++, tempx += NEW.xIncrement)
!       NEW.xpts[i] = tempx;
      NEW.valid = False;
      SetBoundingBox(new);
      new->plot.redisplay = True; /* refresh all plots. NOTE, we may
  				   want to change this later to 
  				   refresh only this plot if no autoS.
***************
*** 443,449 ****
      }
      else {
          xmin = W.xpts[0];
! 	xmax = W.xpts[W.numPoints - 1] + W.density;
  
          ymin = ymax = W.ypts[0];
          for(i=1; i < W.numPoints; i++) {
--- 429,435 ----
      }
      else {
          xmin = W.xpts[0];
! 	xmax = W.xpts[W.numPoints - 1] + W.density * W.xIncrement;
  
          ymin = ymax = W.ypts[0];
          for(i=1; i < W.numPoints; i++) {
***************
*** 540,546 ****
      XSetRegion(dpy, BCW.fillGc, region);
    }
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density + 1;
  
    for (i=0; i<BCW.numPoints; i++) {
      XFillRectangle(dpy, win, BCW.fillGc, BCW.pixpts[i].x, BCW.pixpts[i].y,
--- 526,532 ----
      XSetRegion(dpy, BCW.fillGc, region);
    }
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density;
  
    for (i=0; i<BCW.numPoints; i++) {
      XFillRectangle(dpy, win, BCW.fillGc, BCW.pixpts[i].x, BCW.pixpts[i].y,
***************
*** 576,582 ****
      xpts[i] = AtScaleUserToPixel(xs, p->barchart.xpts[i])/100.0;
      ypts[i] = AtScaleUserToPixel(ys, p->barchart.ypts[i])/100.0;
    }
!   barwidth = (xpts[1] - xpts[0]) * BCW.density + 1;
  
    if (BCW.shading)
      pattern = 1.0 - ((p->barchart.pattern + 1.0) / 
--- 562,568 ----
      xpts[i] = AtScaleUserToPixel(xs, p->barchart.xpts[i])/100.0;
      ypts[i] = AtScaleUserToPixel(ys, p->barchart.ypts[i])/100.0;
    }
!   barwidth = (xpts[1] - xpts[0]) * BCW.density;
  
    if (BCW.shading)
      pattern = 1.0 - ((p->barchart.pattern + 1.0) / 
***************
*** 668,674 ****
    clipy = BCW.fillGc->values.clip_y_origin;
    clip_mask = BCW.fillGc->values.clip_mask;
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density + 1;
    
    XSetClipRectangles(dpy, BCW.fillGc, 0, 0, cliprect, 1, Unsorted);
    for (i = 0; i < BCW.numPoints; i++)
--- 654,660 ----
    clipy = BCW.fillGc->values.clip_y_origin;
    clip_mask = BCW.fillGc->values.clip_mask;
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density;
    
    XSetClipRectangles(dpy, BCW.fillGc, 0, 0, cliprect, 1, Unsorted);
    for (i = 0; i < BCW.numPoints; i++)
***************
*** 696,702 ****
    clipy = BCW.fillGc->values.clip_y_origin;
    clip_mask = BCW.fillGc->values.clip_mask;
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density + 1;
    XSetRegion (dpy, BCW.fillGc, region);
  
    for (i=0; i<BCW.numPoints; i++) 
--- 682,688 ----
    clipy = BCW.fillGc->values.clip_y_origin;
    clip_mask = BCW.fillGc->values.clip_mask;
  
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density;
    XSetRegion (dpy, BCW.fillGc, region);
  
    for (i=0; i<BCW.numPoints; i++) 
***************
*** 720,726 ****
    if (BCW.valid == False) Recompute(plot, xscale, yscale);
  
    rlist = (XRectangle *) XtMalloc(BCW.numPoints * sizeof(XRectangle));
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density + 1;
  
    for (i = 0; i < BCW.numPoints; i++)  {
      if (BCW.pixpts[i].y < BCW.oldpixpts[i].y) { /* bar growing */
--- 706,712 ----
    if (BCW.valid == False) Recompute(plot, xscale, yscale);
  
    rlist = (XRectangle *) XtMalloc(BCW.numPoints * sizeof(XRectangle));
!   barwidth = (BCW.pixpts[1].x - BCW.pixpts[0].x) * BCW.density;
  
    for (i = 0; i < BCW.numPoints; i++)  {
      if (BCW.pixpts[i].y < BCW.oldpixpts[i].y) { /* bar growing */
