Bug 72204 - Data Mode doesn't work if vectors don't start at file frame 0
Summary: Data Mode doesn't work if vectors don't start at file frame 0
Status: RESOLVED FIXED
Alias: None
Product: kst
Classification: Applications
Component: general (show other bugs)
Version: 1.x
Platform: Mandrake RPMs Linux
: NOR normal
Target Milestone: ---
Assignee: George Staikos
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-09 01:23 UTC by Netterfield
Modified: 2004-01-27 05:02 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Netterfield 2004-01-09 01:23:24 UTC
Version:           0.95-devel (using KDE 3.1.3)
Installed from:    Mandrake Linux Cooker i586 - Cooker
Compiler:          gcc version 3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk)
OS:          Linux (i686) release 2.4.22-10mdk

Read part of a file, not starting at frame 0
(eg, -f 10)

Go do data mode.

Data mode numbers don't update when you move the mouse.
Comment 1 Matthew Truch 2004-01-14 22:15:24 UTC
This is also true if you are viewing live data, and the beginning of the data is not shown (this is virtually the same case as non-live data), but I'm confirming.
Comment 2 George Staikos 2004-01-16 03:29:16 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

Make data mode work with vectors that started after 0
CCMAIL: 72204-done@bugs.kde.org


  M +10 -0     kstview.cpp   1.73


--- kdeextragear-2/kst/kst/kstview.cpp  #1.72:1.73
@@ -418,4 +418,11 @@ void KstView::updateMouse() {
         double xpt = 0.0, ypt = 0.0;
         int pt = int((*i)->sampleCount() * xpos / ((*i)->maxX() - (*i)->minX()));
+
+        pt -= (*i)->minX();
+
+        if (pt < 0) {
+          continue;
+        }
+ 
         (*i)->getPoint(pt, xpt, ypt);
         if (fabs(ypos - ypt) < delta) {
@@ -433,4 +441,6 @@ void KstView::updateMouse() {
         return;
       }
+      emit newDataMsg(QString::null);
+      return;
     }
 


Comment 3 Matthew Truch 2004-01-17 23:02:18 UTC
I've updated my cvs, but I still don't get updated datamode data when the first frame isn't frame 0.  The red markers appear only at the extreme right of the graph (and the numbers printed in the lower right corner reflect the position of the red markers).  

This problem does not exist when the starting frame is frame 0.  
Comment 4 George Staikos 2004-01-17 23:04:30 UTC
Subject: Re:  Data Mode doesn't work if vectors don't start at file frame 0

On Saturday 17 January 2004 17:02, Matthew Truch wrote:
> I've updated my cvs, but I still don't get updated datamode data when the
> first frame isn't frame 0.  The red markers appear only at the extreme
> right of the graph (and the numbers printed in the lower right corner
> reflect the position of the red markers).
>
> This problem does not exist when the starting frame is frame 0.

   Does the red marker appear properly if the frame starts at 0?  Hm I find 
this odd, the bug was quite clear and it works here.  What example are you 
using in particular?

Comment 5 Matthew Truch 2004-01-17 23:07:31 UTC
When the frame starts at 0, the red marker appears on one of the curves, at what looks like a datapoint, and the lower right does correctly indicate the coordinates of the datapoint indicated by the marker.  However, the red marker usually isn't at the datapoint closest to the cursor, but is one of the cloest few (and seems to be always erring to a earlier data point).  
Comment 6 George Staikos 2004-01-17 23:11:36 UTC
Subject: Re:  Data Mode doesn't work if vectors don't start at file frame 0

On Saturday 17 January 2004 17:07, Matthew Truch wrote:
> When the frame starts at 0, the red marker appears on one of the curves, at
> what looks like a datapoint, and the lower right does correctly indicate
> the coordinates of the datapoint indicated by the marker.  However, the red
> marker usually isn't at the datapoint closest to the cursor, but is one of
> the cloest few (and seems to be always erring to a earlier data point).

   Do you have a sample .kst file plus datafile that I can test against?

Comment 7 Matthew Truch 2004-01-17 23:17:10 UTC
It seems that the problem goes away if I the X value of a curve is INDEX.  All of my plots have involved one derived field versus another derived field, and in that case datamode doesn't work (and seems to display only the last point).  
Comment 8 Matthew Truch 2004-01-17 23:43:51 UTC
Things also don't work right when skip frames is active, although the problems above (it works when X is INDEX, and doesn't work when X isn't) occur regardless of skip frames settings, and even when the first frame is zero.  

When first frame is greater than zero, the derived vs. derived still fails in the same way; the derived vs. INDEX starts to fail more and more as the first frame is increased from 1 to some value that seems to be (# of frames) * (skip frames # if skip frames>0; 1 otherwise).  When I say fails more and more, I mean not all the datamode marker doesn't align with the cursor propoerly, and only allows you to access the first so many datapoints on the curve.  

When the starting frame is really large, none of datamode works, and only shows values for one point.  
Comment 9 George Staikos 2004-01-20 10:32:23 UTC
Let's investigate
Comment 10 George Staikos 2004-01-20 10:41:19 UTC
Ok I'm able to see the "not the one exactly nearest the pointer" problem, but I need a testcase for a curve that exhibits the other problems.
Comment 11 George Staikos 2004-01-20 11:13:07 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

As the previous implementation wasn't considered "close enough", we now check
the point rounded up and down (slight bias upward), and use the shortest
distance instead of the closest Y point.  This is closer to the concept of
the "closest data point".  It still falls apart with very steep graphs.
CCMAIL: 72204@bugs.kde.org


  M +25 -4     kstview.cpp   1.75


--- kdeextragear-2/kst/kst/kstview.cpp  #1.74:1.75
@@ -421,11 +421,32 @@ void KstView::updateMouse() {
         pt -= int((*i)->minX());
 
-        if (pt < 0) {
+        double ydiff, xdiff, nd;
+
+        if (pt >= 0 && pt < (*i)->sampleCount()) {
+          (*i)->getPoint(pt, xpt, ypt);
+          ydiff = ypos - ypt;
+          xdiff = xpos - xpt;
+          nd = ydiff*ydiff + xdiff*xdiff;
+          if (nd < delta) {
+            delta = nd;
+            newxpos = xpt;
+            newypos = ypt;
+            curve = *i;
+          }
+        }
+
+        // The previous point rounded down, let's round up.
+        // This doesn't help us with very vertical regions though.
+        pt++;
+        if (pt >= (*i)->sampleCount() || pt < 0) {
           continue;
         }
  
         (*i)->getPoint(pt, xpt, ypt);
-        if (fabs(ypos - ypt) < delta) {
-          delta = fabs(ypos - ypt);
+        ydiff = ypos - ypt;
+        xdiff = xpos - xpt;
+        nd = ydiff*ydiff + xdiff*xdiff;
+        if (nd < delta) {
+          delta = nd;
           newxpos = xpt;
           newypos = ypt;


Comment 12 George Staikos 2004-01-26 21:00:45 UTC
I now have a testcase for the rest of this problem and am working on it.
Comment 13 George Staikos 2004-01-27 05:02:45 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

Make datamode work on shifted vectors with an absolutely disgusting hack that
really should be removed ASAP.  SamplesPerFrame should be completely
encapsulated within the vector and curve I think, but it isn't presently which
means I need to pass it out via kstbasecurve and use it in kstview.  This
feels really wrong to me.

CCMAIL: 72204-done@bugs.kde.org


  M +2 -0      kstbasecurve.h   1.12
  M +16 -11    kstvcurve.cpp   1.23
  M +2 -0      kstvcurve.h   1.17
  M +9 -4      kstview.cpp   1.76


--- kdeextragear-2/kst/kst/kstbasecurve.h  #1.11:1.12
@@ -82,4 +82,6 @@ public:
   virtual bool xIsRising() const {return false;}
 
+  virtual int samplesPerFrame() const { return 1; }
+
   KstPoint Point;
 

--- kdeextragear-2/kst/kst/kstvcurve.cpp  #1.22:1.23
@@ -223,19 +223,19 @@ bool KstVCurve::hasYError() const {
 /** Save curve information */
 void KstVCurve::save(QTextStream &ts) {
-  ts << " <curve>\n";
-  ts << "  <tag>" << _tag << "</tag>\n";
-  ts << "  <xvectag>" << VX->tagName() << "</xvectag>\n";
-  ts << "  <yvectag>" << VY->tagName() << "</yvectag>\n";
+  ts << " <curve>" << endl;
+  ts << "  <tag>" << _tag << "</tag>" << endl;
+  ts << "  <xvectag>" << VX->tagName() << "</xvectag>" << endl;
+  ts << "  <yvectag>" << VY->tagName() << "</yvectag>" << endl;
   if (EX.data()) {
-    ts << "  <exVectag>" << EX->tagName() << "</exVectag>";
+    ts << "  <exVectag>" << EX->tagName() << "</exVectag>" << endl;
   }
   if (EY.data()) {
-    ts << "  <eyVectag>" << EY->tagName() << "</eyVectag>";
+    ts << "  <eyVectag>" << EY->tagName() << "</eyVectag>" << endl;
   }
-  ts << "  <color>" << Color.name() << "</color>\n";
-  ts << "  <hasLines>" << HasLines << "</hasLines>\n";
-  ts << "  <hasPoints>" << HasPoints << "</hasPoints>\n";
-  ts << "  <pointType>" << Point.getType() << "</pointType>\n";
-  ts << " </curve>\n";
+  ts << "  <color>" << Color.name() << "</color>" << endl;
+  ts << "  <hasLines>" << HasLines << "</hasLines>" << endl;
+  ts << "  <hasPoints>" << HasPoints << "</hasPoints>" << endl;
+  ts << "  <pointType>" << Point.getType() << "</pointType>" << endl;
+  ts << " </curve>" << endl;
 }
 
@@ -280,2 +280,7 @@ void KstVCurve::_showDialog() {
 }
 
+int KstVCurve::samplesPerFrame() const {
+  const KstRVector *rvp = dynamic_cast<const KstRVector*>(VY.data());
+  return rvp ? rvp->samplesPerFrame() : 1;
+}
+

--- kdeextragear-2/kst/kst/kstvcurve.h  #1.16:1.17
@@ -76,4 +76,6 @@ public:
   virtual double ns_minY()    const { return _ns_miny; }
 
+  virtual int samplesPerFrame() const;
+
 protected:
   virtual void _showDialog();

--- kdeextragear-2/kst/kst/kstview.cpp  #1.75:1.76
@@ -416,12 +416,17 @@ void KstView::updateMouse() {
 
       for (KstBaseCurveList::Iterator i = pPlot->Curves.begin(); i != pPlot->Curves.end(); ++i) {
+        int left = 0;
+        int right = left + (*i)->sampleCount();
         double xpt = 0.0, ypt = 0.0;
-        int pt = int((*i)->sampleCount() * xpos / ((*i)->maxX() - (*i)->minX()));
+        int pt = int((right - left) * xpos / ((*i)->maxX() - (*i)->minX()));
 
-        pt -= int((*i)->minX());
+        pt -= (*i)->samplesPerFrame() * int((*i)->minX());
+
+        //kdDebug() << "[" << (*i)->minX() << ".." << (*i)->maxX() << "] n=" << (*i)->sampleCount() << " SPF: " << (*i)->samplesPerFrame() << " GETTING POINT: " << pt << endl;
+        //kdDebug() << "LEFT: " << left << " RIGHT: " << right << endl;
 
         double ydiff, xdiff, nd;
 
-        if (pt >= 0 && pt < (*i)->sampleCount()) {
+        if (pt >= left && pt < right) {
           (*i)->getPoint(pt, xpt, ypt);
           ydiff = ypos - ypt;
@@ -439,5 +444,5 @@ void KstView::updateMouse() {
         // This doesn't help us with very vertical regions though.
         pt++;
-        if (pt >= (*i)->sampleCount() || pt < 0) {
+        if (pt >= right || pt < left) {
           continue;
         }