Bug 123698 - bar graph bars widths are not correctly calculated for unevenly spaced data
Summary: bar graph bars widths are not correctly calculated for unevenly spaced data
Status: RESOLVED FIXED
Alias: None
Product: kst
Classification: Applications
Component: general (show other bugs)
Version: 1.x
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: kst
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-16 01:25 UTC by Brendan Crill
Modified: 2006-03-17 21:14 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brendan Crill 2006-03-16 01:25:53 UTC
Version:           1.2.0_dr1 (using KDE 3.4.2 Level "b" , SUSE 10.0)
Compiler:          Target: i586-suse-linux
OS:                Linux (i686) release 2.6.13-15.8-default

I tried to make a bar graph of these four data points:

100 0.74
143 0.42
217 0.67
353 2.4

I plotted column 2 vs column 1 and the bars come out overlapping.  Barth tells me that the bar width calculation assumes uniform spacing, which doesn't work for this data.

Thanks!
Comment 1 Andrew Walker 2006-03-16 23:05:01 UTC
Clearly what is being done is incorrect, but what is the correct thing to do? There seem to be at least a couple of options:

1) Make each bar a fixed width, with the width being the smallest difference between data points
2) Make the bars variable width

Brendan, what were you expecting in your case?
Comment 2 Brendan Crill 2006-03-16 23:19:59 UTC
Hi Andrew,
I think option 1 would be fine for a default.  A nice feature would be to have control over the width.  Barth's idea (he happens to be sitting right next to me) is  if the X error bar option is set, have that vector set the bar width.  Thanks!
Comment 3 Andrew Walker 2006-03-17 20:35:50 UTC
Fixed for monotonically increasing x-axis
Comment 4 Andrew Walker 2006-03-17 21:14:44 UTC
SVN commit 519650 by arwalker:

CCBUG:123698 Make bar width the smallest difference between data points on the x-axis in the case where x-data is monotonically increasing. The x-error bar, if set,  already defines the bar width.

 M  +26 -8     kstvcurve.cpp  


--- trunk/extragear/graphics/kst/src/libkstmath/kstvcurve.cpp #519649:519650
@@ -843,7 +843,7 @@
   bool _xLog = context._xLog, _yLog = context._yLog;
   int penWidth = context.penWidth;
   double maxY = 0.0, minY = 0.0;
-  double rX, rY, rEX, rEY;
+  double rX = 0.0, rY, rEX, rEY;
   double X1 = 0.0, Y1 = 0.0;
   double X2 = 0.0, Y2 = 0.0;
   double last_x1, last_y1;
@@ -1145,10 +1145,12 @@
       // we might have some overlapping points still unplotted...
       if (overlap) {
         if (X2 >= Lx && X2 <= Hx) {
-          if (maxY > Hy && minY <= Hy)
+          if (maxY > Hy && minY <= Hy) {
             maxY = Hy;
-          if (minY < Ly && maxY >= Ly)
+          }
+          if (minY < Ly && maxY >= Ly) {
             minY = Ly;
+          }
           if (minY >= Ly && minY <= Hy && maxY >= Ly && maxY <= Hy) {
             p->drawLine(d2i(X2), d2i(minY), d2i(X2), d2i(maxY));
           }
@@ -1174,7 +1176,7 @@
       bool has_right = true;
       bool visible = true;
       double rX2 = 0.0;
-      double drX;
+      double drX = 0.0;
 
       if (barStyle() == 1) { // filled
         p->setPen(QPen(_foregroundColor, width, style));
@@ -1182,13 +1184,29 @@
         p->setPen(QPen(color(), width, style));
       }
 
-      drX = (maxX() - minX())/double(sampleCount());
+      if (!exv) {        
+        // determine the bar position width. NOTE: This is done
+        //  only if xv->isRising() as in this case the calculation
+        //  is simple...
+        drX = (maxX() - minX())/double(sampleCount());
+        if (xv->isRising()) {       
+          double oldX = 0.0;
+
+          for (i_pt = i0; i_pt <= iN; i_pt++) {
+            rX = xv->interpolate(i_pt, NS);
+            if (i_pt > i0) {                      
+              if (rX - oldX < drX) {
+                drX = rX - oldX;                      
+              }
+            }
+            oldX = rX; 
+          }
+        }
+      }
+      
       for (i_pt = i0; i_pt <= iN; i_pt++) {
         visible = has_bot = has_top = has_left = has_right = true;
 
-        // determine the bar position width.
-        // NOTE: this assumes even X spacing if XError is not defined
-        // There may a better way...
         if (exv) {
           drX = exv->interpolate(i_pt, NS);
         }