]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Issue 0001626: External 20643: 2d plot axis logarithmic.
authorouv <ouv@opencascade.com>
Thu, 18 Apr 2013 14:25:16 +0000 (14:25 +0000)
committerouv <ouv@opencascade.com>
Thu, 18 Apr 2013 14:25:16 +0000 (14:25 +0000)
src/Plot2d/Plot2d_Curve.cxx
src/Plot2d/Plot2d_Curve.h
src/Plot2d/Plot2d_ViewFrame.cxx
src/Plot2d/Plot2d_ViewFrame.h
src/Plot2d/resources/Plot2d_msg_en.ts

index fec9762686b65dd7d32945e42c09fa972faa4185..d1ab1755c3551ac5dfed621ee152e831c870733b 100755 (executable)
@@ -23,6 +23,8 @@
 #include "Plot2d_Curve.h"
 #include <QColor>
 
+#include <float.h>
+
 /*!
   Constructor
 */
@@ -214,6 +216,14 @@ pointList Plot2d_Curve::getPointList() const
   return myPoints;
 }
 
+/*!
+  Gets curve's data : abscissas of points
+*/
+pointList& Plot2d_Curve::getPointList()
+{
+  return myPoints;
+}
+
 /*!
   Sets curve's data. 
 */
@@ -442,6 +452,36 @@ double Plot2d_Curve::getMaxY() const
   return aMaxY;
 }
 
+/*!
+  Gets curve's minimal positive abscissa
+*/
+double Plot2d_Curve::getMinPositiveX() const
+{
+  pointList::const_iterator aIt;
+  double aMinX = 1e150;
+  //int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if ( (*aIt).x < aMinX && (*aIt).x > DBL_MIN )
+      aMinX = (*aIt).x;
+  }
+  return aMinX;
+}
+
+/*!
+  Gets curve's minimal positive ordinate
+*/
+double Plot2d_Curve::getMinPositiveY() const
+{
+  pointList::const_iterator aIt;
+  double aMinY = 1e150;
+  //int aCurrent = 0;
+  for(aIt = myPoints.begin(); aIt != myPoints.end(); ++aIt) {
+    if ( (*aIt).y < aMinY && (*aIt).y > DBL_MIN )
+      aMinY = (*aIt).y;
+  }
+  return aMinY;
+}
+
 /*!
   Changes text assigned to point of curve
   \param ind -- index of point
index 8692be8c947cd7f91e6e269df7bf64a20b8c55cf..0b981997157fb9fbb2695438eb387402ccf9b11a 100755 (executable)
@@ -64,6 +64,7 @@ public:
   void               deletePoint( int );
   void               clearAllPoints();
   pointList          getPointList() const;
+  pointList&         getPointList();
 
   void               setData( const double*, const double*, 
                              long, const QStringList& = QStringList() );
@@ -106,6 +107,11 @@ public:
   double             getMaxX() const;
   double             getMaxY() const;
 
+  // Values required for calculating a "negligible" value, by which the non-positive
+  // values will be replaced during switch to logarithmic scale mode
+  double             getMinPositiveX() const;
+  double             getMinPositiveY() const;
+
 protected:
   bool               myAutoAssign;
   QString            myHorTitle;
index e397b6326a865b277055da04da17017c9e979883..cfe758f606d839e539483ce16040e64049a706b1 100755 (executable)
@@ -57,6 +57,7 @@
 #include <qwt_curve_fitter.h>
 
 #include <iostream>
+#include <float.h>
 #include <stdlib.h>
 #include <QPrinter>
 
@@ -69,6 +70,8 @@
 
 #define FITALL_EVENT           ( QEvent::User + 9999 )
 
+#define NEGLIGIBLE_VALUE 1e-6
+
 const char* imageZoomCursor[] = { 
 "32 32 3 1",
 ". c None",
@@ -1503,6 +1506,63 @@ void Plot2d_ViewFrame::setFont( const QFont& font, ObjectType type, bool update)
   if ( update )
     myPlot->replot();
 }
+/*!
+  Remove the curve's non-positive values or replace them by a negligible small value
+  (to make it possible to enable logarithmic scale mode).
+*/
+void Plot2d_ViewFrame::cutCurveNonPositiveValues( const bool theIsXAxis,
+                                                  const bool theIsReplaceWithSmallValues )
+{
+  const CurveDict& aCurves = myPlot->getCurves();
+  CurveDict::ConstIterator it, itEnd = aCurves.end();
+
+  double aSmallValue = NEGLIGIBLE_VALUE;
+  if( theIsReplaceWithSmallValues )
+  {
+    // first, calculate the value the non-positive values will be cut to
+    for( it = aCurves.begin(); it != itEnd; it++ )
+    {
+      if( Plot2d_Curve* aCurve = it.value() )
+      {
+        double aMinPositiveValue = theIsXAxis ?
+          aCurve->getMinPositiveX() : aCurve->getMinPositiveY();
+
+        if( aMinPositiveValue < aSmallValue )
+        {
+          double aLog = log10( aMinPositiveValue );
+          double aFloor = floor( aLog );
+          aSmallValue = pow( 10, aFloor );
+        }
+      }
+    }
+  }
+
+  for( it = aCurves.begin(); it != itEnd; it++ )
+  {
+    if( Plot2d_Curve* aCurve = it.value() )
+    {
+      pointList& aPointList = aCurve->getPointList();
+      pointList::iterator pIt, pItEnd = aPointList.end();
+      for( pIt = aPointList.begin(); pIt != pItEnd; )
+      {
+        Plot2d_Point& aPoint = *pIt;
+        double& value = theIsXAxis ? aPoint.x : aPoint.y;
+        if( value < DBL_MIN )
+        {
+          if( theIsReplaceWithSmallValues )
+            value = aSmallValue;
+          else // remove value
+          {
+            pIt = aPointList.erase( pIt );
+            continue; // do not increment the iterator
+          }
+        }
+        pIt++;
+      }
+      updateCurve( aCurve, false );
+    }
+  }
+}
 /*!
   Sets scale mode for horizontal axis: 0 - linear, 1 - logarithmic
 */
@@ -1515,8 +1575,15 @@ void Plot2d_ViewFrame::setHorScaleMode( const int mode, bool update )
   // it crashes if switched to X/Y logarithmic mode, when one or more points have
   // non-positive X/Y coordinate
   if ( mode && !isXLogEnabled() ){
-    SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"));
-    return;
+    int answer = SUIT_MessageBox::question(this, tr("WARNING"), tr("WRN_XLOG_NOT_ALLOWED"),
+                                           tr("REMOVE_POINTS"), tr("REPLACE_VALUES"),
+                                           tr("CANCEL"), 2, 2);
+    if( answer == 0 )
+      cutCurveNonPositiveValues( true, false );
+    else if( answer == 1 )
+      cutCurveNonPositiveValues( true, true );
+    else
+      return;
   }
 
   myXMode = mode;
@@ -1539,8 +1606,15 @@ void Plot2d_ViewFrame::setVerScaleMode( const int mode, bool update )
   // it crashes if switched to X/Y logarithmic mode, when one or more points have
   // non-positive X/Y coordinate
   if ( mode && !isYLogEnabled() ){
-    SUIT_MessageBox::warning(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"));
-    return;
+    int answer = SUIT_MessageBox::question(this, tr("WARNING"), tr("WRN_YLOG_NOT_ALLOWED"),
+                                           tr("REMOVE_POINTS"), tr("REPLACE_VALUES"),
+                                           tr("CANCEL"), 2, 2);
+    if( answer == 0 )
+      cutCurveNonPositiveValues( false, false );
+    else if( answer == 1 )
+      cutCurveNonPositiveValues( false, true );
+    else
+      return;
   }
 
   myYMode = mode;
index 3d585bbfaf0fa95ecdb73d1fe3aaa0e8e6590f29..620a3c81d7f592fe2dabd07cbbfb8e619fb3abe3 100755 (executable)
@@ -152,6 +152,8 @@ protected:
   QwtPlotCurve* getPlotCurve( Plot2d_Curve* curve );
   bool    hasPlotCurve( Plot2d_Curve* curve );
   void    setCurveType( QwtPlotCurve* curve, int curveType );
+  void    cutCurveNonPositiveValues( const bool theIsXAxis,
+                                     const bool theIsReplaceWithSmallValues );
 
 public slots:
   void    onViewPan(); 
index 41983b772e9837606dd1bfcbdc984baf64e70298..ab6fcd6ec453ab96fcc0ca0b8961aba591f07df6 100644 (file)
     <message>
         <source>WRN_XLOG_NOT_ALLOWED</source>
         <translation>Some points with non-positive abscissa values have been detected.
-Logarithmic scale for abscissa axis is not allowed.</translation>
+Do you want to remove these points from the curve presentation or
+to replace the non-positive values with negligible positive values?</translation>
     </message>
     <message>
         <source>WRN_YLOG_NOT_ALLOWED</source>
         <translation>Some points with non-positive ordinate values have been detected.
-Logarithmic scale for ordinate axis is not allowed.</translation>
+Do you want to remove these points from the curve presentation or
+to replace the non-positive values with negligible positive values?</translation>
+    </message>
+    <message>
+        <source>REMOVE_POINTS</source>
+        <translation>Remove points</translation>
+    </message>
+    <message>
+        <source>REPLACE_VALUES</source>
+        <translation>Replace values</translation>
     </message>
     <message>
         <source>DSC_FITRECT</source>