Bug 64894

Summary: lower right mouse data should have "snap to real data" mode
Product: [Applications] kst Reporter: Matthew Truch <matt>
Component: generalAssignee: George Staikos <staikos>
Status: RESOLVED FIXED    
Severity: wishlist    
Priority: NOR    
Version: 1.x   
Target Milestone: ---   
Platform: RedHat Enterprise Linux   
OS: Linux   
Latest Commit: Version Fixed In:

Description Matthew Truch 2003-09-25 04:55:46 UTC
Version:           0.92 (using KDE KDE 3.1)
Installed from:    RedHat RPMs

When the mouse is over a plot, the location of the cursor is shown in the lower right of the kst window.  It would be very nice to have the ability to also show actual data points.  That is, either in a different mouse mode, or just as another co-ordinate pair at the bottom of the kst window, when the mouse is near a curve, it indicate the nearest actual data point to where the mouse is.  Perhaps a little circle or some other marker could appear on the curve to indicate which point (and curve) is being indicated at the bottom.
Comment 1 George Staikos 2003-09-27 01:50:15 UTC
Adding this as a toggle action. 
Comment 2 George Staikos 2003-09-28 00:37:36 UTC
What do we do if there are multiple curves in a plot?  Show the Y coordinate of all of 
them, the closest one to the mouse, or keep state and require the user to switch the 
"current" curve?  (or something else?) 
Comment 3 George Staikos 2003-09-28 00:41:57 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

Most of the implementation require for this feature.  Requires more design in
order to complete.

CCMAIL: 64894@bugs.kde.org


  M +8 -0      kst.cpp   1.53
  M +7 -1      kst.h   1.20
  M +10 -0     kstview.cpp   1.49
  M +4 -0      kstview.h   1.22


--- kdeextragear-2/kst/kst/kst.cpp  #1.52:1.53
@@ -390,4 +390,8 @@ void KstApp::initActions() {
                                  actionCollection(), "pluginmanager_action");
 
+  DataMode = new KToggleAction(i18n("DataMode"), 0, 0,
+                                 this, SLOT(toggleDataMode()),
+                                 actionCollection(), "datamode_action");
+
   createGUI();
 }
@@ -703,4 +707,8 @@ void KstApp::slotUpdateFrameMsg(int fram
 void KstApp::slotUpdateDataMsg(const QString &msg) {
   statusBar()->changeItem(msg, KST_STATUSBAR_DATA);
+}
+
+void KstApp::toggleDataMode() {
+  view->setDataMode(DataMode->isChecked());
 }
 

--- kdeextragear-2/kst/kst/kst.h  #1.19:1.20
@@ -151,4 +151,7 @@ private slots:
   void updateActions();
 
+  // for the kaction
+  void toggleDataMode();
+
 public slots:
     void slotConfigureKeys();
@@ -324,4 +327,7 @@ private:
   /* Vector Save Action */
   KAction *_vectorSaveAction;
+
+  /* Data mode */
+  KToggleAction *DataMode;
 
   /** Change File Action: brings up the change file dialog box */

--- kdeextragear-2/kst/kst/kstview.cpp  #1.48:1.49
@@ -56,4 +56,5 @@ KstView::KstView(KstApp *parent, const c
   first_time = true;
   _minMove = 3;
+  _dataMode = false;
 
   ZoomCurrentPlot = false;
@@ -364,4 +365,8 @@ void KstView::update() {
   needrecreate = true;
   paintEvent(NULL);
+  updateMouse();
+}
+
+void KstView::updateMouse() {
   int plot = MouseInfo->getPlotNum();
   KstPlot* pPlot;
@@ -1341,4 +1346,9 @@ void KstView::cleanupLayout() {
   KST::plotList.arrangePlots(KST::plotList.getPlotCols());
   update();
+}
+
+void KstView::setDataMode(bool on) {
+  _dataMode = on;
+  updateMouse();
 }
 

--- kdeextragear-2/kst/kst/kstview.h  #1.21:1.22
@@ -82,4 +82,5 @@ public slots:
   void zoomPlotSlot();
 
+  void setDataMode(bool on);
   void forceUpdate();
 
@@ -118,4 +119,6 @@ private:
   int ZoomPlotNum;
 
+  bool _dataMode;
+
   /** the smallest move to consider as a box */
   int _minMove;
@@ -137,4 +140,5 @@ private slots:
   void dynamicMenuEdit(int);
   void deleteCurrentPlot();
+  void updateMouse();
 
 signals:


Comment 4 Matthew Truch 2003-09-28 09:40:17 UTC
> What do we do if there are multiple curves in a plot? Show the Y coordinate of 
> all of them, the closest one to the mouse, or keep state and require the user to 
> switch the "current" curve? (or something else?) 

I think it would be best to show the Y coordinate of the closest point to the
mouse, and it should be (at least semi-) obvious which curve is being indicated.  
Comment 5 George Staikos 2003-09-29 23:08:09 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

Add support for most of #64894.  It's not functional, but this removes much of
the code duplication in kstview and adds a stub "data mode" to be filled in
later.  Might require some minor semantic changes to kstbasecurve and/or kstplot.

CCMAIL: 64894@bugs.kde.org


  M +1 -0      kstui.rc   1.8
  M +62 -106   kstview.cpp   1.50
  M +4 -0      kstview.h   1.23



Comment 6 George Staikos 2003-09-30 03:18:05 UTC
Subject: kdeextragear-2/kst/kst

CVS commit by staikos: 

Implement the rest of #64894.  There is still room for improvement (right now
it only handles integral x coordinates, it's probably not the most efficient,
etc), but it works.

CCMAIL: 64894-done@bugs.kde.org


  M +26 -14    kstview.cpp   1.51


--- kdeextragear-2/kst/kst/kstview.cpp  #1.50:1.51
@@ -370,4 +370,5 @@ void KstView::update() {
 void KstView::updateMouse() {
   int plot = MouseInfo->getPlotNum();
+  QString msg;
   KstPlot* pPlot;
   if (plot >= 0 && (pPlot = KST::plotList.at(plot))) {
@@ -383,11 +384,4 @@ void KstView::updateMouse() {
     }
 
-    QString msg;
-    if (_dataMode) {
-      ypos = -1;
-      // Use curve name FIXME
-      QString plotName = pPlot->tagName();
-      msg = i18n("%3 (%1, %2)").arg(xpos,0,'G').arg(ypos,0,'G').arg(plotName);
-    } else {
       ypos = (double)(pos.y() - plot_rect.top())/(double)plot_rect.height();
       ypos = ypos * (ymin - ymax) + ymax;
@@ -396,11 +390,29 @@ void KstView::updateMouse() {
         ypos = pow(10.0, ypos);
       }
-      msg = i18n("(%1, %2)").arg(xpos,0,'G').arg(ypos,0,'G');
-    }
 
+    if (_dataMode) {
+      double newypos = ypos;
+      KstBaseCurvePtr curve;
+      double delta = 9e99;
+
+      for (KstBaseCurveList::Iterator i = pPlot->Curves.begin(); i != pPlot->Curves.end(); ++i) {
+        double xpt, ypt;
+        (*i)->getPoint(int(xpos), xpt, ypt);
+        if (fabs(ypos - ypt) < delta) {
+          delta = fabs(ypos - ypt);
+          newypos = ypt;
+          curve = *i;
+        }
+      }
+      if (curve.data()) {
+        msg = i18n("%3 (%1, %2)").arg(int(xpos)).arg(newypos,0,'G').arg(curve->tagName());
     emit newDataMsg(msg);
-  } else {
-    emit newDataMsg(QString::null);
+        return;
+      }
   }
+
+    msg = i18n("(%1, %2)").arg(xpos,0,'G').arg(ypos,0,'G');
+  }
+  emit newDataMsg(msg);
 }