[Kst] branches/work/kst/portto4/kst/src/libkstapp

Mike Fenton mike at staikos.net
Fri Feb 15 16:40:17 CET 2008


SVN commit 775347 by fenton:

Add Log Axis drawing.


 M  +120 -52   plotitem.cpp  
 M  +5 -2      plotitem.h  
 M  +2 -0      plotrenderitem.cpp  


--- branches/work/kst/portto4/kst/src/libkstapp/plotitem.cpp #775346:775347
@@ -27,6 +27,8 @@
 #include "dataobjectcollection.h"
 #include "cartesianrenderitem.h"
 
+#include "math_kst.h"
+
 #include "settings.h"
 
 #include <QDebug>
@@ -203,7 +205,8 @@
   QList<qreal> xMinorTicks;
   QList<qreal> yMajorTicks;
   QList<qreal> yMinorTicks;
-  computeTicks(&xMajorTicks, &xMinorTicks, &yMajorTicks, &yMinorTicks);
+  QList<QString> xLabels, yLabels;
+  computeTicks(&xMajorTicks, &xMinorTicks, &yMajorTicks, &yMinorTicks, &xLabels, &yLabels);
   setCalculatedAxisMarginWidth(calculateYTickLabelBound(painter, yMajorTicks).width());
   setCalculatedAxisMarginHeight(calculateXTickLabelBound(painter, xMajorTicks).height());
 
@@ -233,7 +236,7 @@
   paintTopLabel(painter);
 
   paintPlotMarkers(painter, xMajorTicks, xMinorTicks, yMajorTicks, yMinorTicks);
-  paintMajorTickLabels(painter, xMajorTicks, yMajorTicks);
+  paintMajorTickLabels(painter, xMajorTicks, yMajorTicks, xLabels, yLabels);
 
   painter->restore();
 }
@@ -399,7 +402,9 @@
 
 void PlotItem::paintMajorTickLabels(QPainter *painter,
                                     const QList<qreal> &xMajorTicks,
-                                    const QList<qreal> &yMajorTicks) {
+                                    const QList<qreal> &yMajorTicks,
+                                    const QList<QString> &xLabelsIn,
+                                    const QList<QString> &yLabelsIn) {
 
   QRectF yLabelRect, xLabelRect;
   int flags = Qt::TextSingleLine | Qt::AlignVCenter;
@@ -492,6 +497,9 @@
     } else {
       label = yLabels[i];
     }
+    if (_yAxisLog) {
+      label = yLabelsIn[i];
+    }
 
     QRectF bound = painter->boundingRect(QRectF(), flags, label);
     QPointF p = mapToPlotFromProjection(QPointF(projectionRect().left(), y));
@@ -537,6 +545,9 @@
     } else {
       label = xLabels[i];
     }
+    if (_xAxisLog) {
+      label = xLabelsIn[i];
+    }
 
     QRectF bound = painter->boundingRect(QRectF(), flags, label);
     QPointF p = mapToPlotFromProjection(QPointF(x, projectionRect().top()));
@@ -1797,72 +1808,129 @@
 }
 
 
-void PlotItem::computeTicks(QList<qreal> *xMajorTicks, QList<qreal> *xMinorTicks, QList<qreal> *yMajorTicks, QList<qreal> *yMinorTicks) const {
-  qreal xMajorTickSpacing = computedMajorTickSpacing(Qt::Horizontal);
-  qreal yMajorTickSpacing = computedMajorTickSpacing(Qt::Vertical);
+void PlotItem::computeLogTicks(QList<qreal> *MajorTicks, QList<qreal> *MinorTicks, QList<QString> *Labels, qreal min, qreal max, qreal size, MajorTickMode tickMode) const {
+    qreal logMax = logXHi(max);
+    qreal logMin = logXLo(min);
+    qreal m_Log = (size - 1) / (logMax - logMin);
+    qreal b_Log = min - m_Log * logMin;
 
-  QList<qreal> xTicks;
+    qreal tick;
+    if (logMax - logMin <= (double)tickMode*1.5) {
+      // show in logarithmic mode with major ticks nicely labelled and the
+      // specified number of minor ticks between each major label
+      tick = 1.0;
+    } else {
+      // show in logarithmic mode with major ticks nicely labelled and no minor ticks
+      tick = floor((logMax - logMin) / (double)tickMode);
+    }
 
-  qreal firstXTick = ceil(projectionRect().left() / xMajorTickSpacing) * xMajorTickSpacing;
+    qreal origin;
+    // determine location of the origin
+    if (logMin > 0.0) {
+      origin = ceil(logMin / tick) * tick;
+    } else if (logMax < 0.0) {
+      origin = floor(logMax / tick) * tick;
+    } else {
+      origin = 0.0;
+    }
 
-  int ix = 0;
-  qreal nextXTick = firstXTick;
-  while (1) {
-    nextXTick = firstXTick + (ix++ * xMajorTickSpacing);
-    if (!projectionRect().contains(nextXTick, projectionRect().y()))
-      break;
-    xTicks << nextXTick;
-  }
+    int Low = int((logMin-origin)/tick);
+    int High = int((logMax-origin)/tick)+1;
+    qreal gap = ((Low+1) * tick * m_Log + b_Log) - ((Low) * tick * m_Log + b_Log);
 
+    for (int i = Low; i <= High; i++) {
+      double value = i * tick;
+      qreal majorPoint = m_Log * value + b_Log + min;
+      if (majorPoint < max && majorPoint > min) {
+        *MajorTicks << majorPoint;
+        *Labels << QString::number(pow(10, i), 'g', FULL_PRECISION);
+      }
+
+      if (tick == 1.0) {
+        // draw minor lines
+        for (int j = 1; j < 9; j++) {
+          qreal minorPoint = log10((double)j/((double)9)*(pow(10,tick)-1.0)+1.0)/log10(10)/tick *(double)gap + majorPoint;
+          if (minorPoint < max && minorPoint > min) {
+            *MinorTicks << minorPoint;
+          }
+        }
+      }
+    }
+}
+
+void PlotItem::computeTicks(QList<qreal> *xMajorTicks, QList<qreal> *xMinorTicks, QList<qreal> *yMajorTicks, QList<qreal> *yMinorTicks, QList<QString> *xLabels, QList<QString> *yLabels) const {
+
+  QList<qreal> xTicks;
   QList<qreal> xMinTicks;
-  qreal xMinorTickSpacing = 0;
-  if (_xAxisMinorTickCount > 0) {
-    xMinorTickSpacing = xMajorTickSpacing / _xAxisMinorTickCount;
-  }
+  if (_xAxisLog) {
+    computeLogTicks(&xTicks, &xMinTicks, xLabels, projectionRect().left(), projectionRect().right(), projectionRect().width(), _xAxisMajorTickMode);
+  } else {
+    qreal xMajorTickSpacing = computedMajorTickSpacing(Qt::Horizontal);
+    qreal firstXTick = ceil(projectionRect().left() / xMajorTickSpacing) * xMajorTickSpacing;
 
-  if (xMinorTickSpacing != 0) {
-    qreal firstXMinorTick = firstXTick + xMinorTickSpacing;
-
-    ix = 0;
-    qreal nextXMinorTick = firstXMinorTick;
+    int ix = 0;
+    qreal nextXTick = firstXTick;
     while (1) {
-      nextXMinorTick = firstXMinorTick + (ix++ * xMinorTickSpacing);
-      if (!projectionRect().contains(nextXMinorTick, projectionRect().y()))
+      nextXTick = firstXTick + (ix++ * xMajorTickSpacing);
+      if (!projectionRect().contains(nextXTick, projectionRect().y()))
         break;
-      if (!xTicks.contains(nextXMinorTick)) {
-        xMinTicks << nextXMinorTick;
+      xTicks << nextXTick;
+    }
+
+    qreal xMinorTickSpacing = 0;
+    if (_xAxisMinorTickCount > 0) {
+      xMinorTickSpacing = xMajorTickSpacing / _xAxisMinorTickCount;
+    }
+
+    if (xMinorTickSpacing != 0) {
+      qreal firstXMinorTick = firstXTick + xMinorTickSpacing;
+
+      ix = 0;
+      qreal nextXMinorTick = firstXMinorTick;
+      while (1) {
+        nextXMinorTick = firstXMinorTick + (ix++ * xMinorTickSpacing);
+        if (!projectionRect().contains(nextXMinorTick, projectionRect().y()))
+          break;
+        if (!xTicks.contains(nextXMinorTick)) {
+          xMinTicks << nextXMinorTick;
+        }
       }
     }
   }
 
   QList<qreal> yTicks;
-  qreal firstYTick = ceil(projectionRect().top() / yMajorTickSpacing) * yMajorTickSpacing;
-
-  int iy = 0;
-  qreal nextYTick = firstYTick;
-  while (1) {
-    nextYTick = firstYTick + (iy++ * yMajorTickSpacing);
-    if (!projectionRect().contains(projectionRect().x(), nextYTick))
-      break;
-    yTicks << nextYTick;
-  }
-
   QList<qreal> yMinTicks;
-  qreal yMinorTickSpacing = 0;
-  if (_yAxisMinorTickCount > 0) {
-    yMinorTickSpacing = yMajorTickSpacing / _yAxisMinorTickCount;
-  }
-  qreal firstYMinorTick = firstYTick + yMinorTickSpacing;
+  if (_yAxisLog) {
+    computeLogTicks(&yTicks, &yMinTicks, yLabels, projectionRect().top(), projectionRect().bottom(), projectionRect().height(), _yAxisMajorTickMode);
+  } else {
+    qreal yMajorTickSpacing = computedMajorTickSpacing(Qt::Vertical);
+    qreal firstYTick = ceil(projectionRect().top() / yMajorTickSpacing) * yMajorTickSpacing;
 
-  if (xMinorTickSpacing != 0) {
-    iy = 0;
-    qreal nextYMinorTick = firstYMinorTick;
+    int iy = 0;
+    qreal nextYTick = firstYTick;
     while (1) {
-      nextYMinorTick = firstYMinorTick + (iy++ * yMinorTickSpacing);
-      if (!projectionRect().contains(projectionRect().x(), nextYMinorTick))
+      nextYTick = firstYTick + (iy++ * yMajorTickSpacing);
+      if (!projectionRect().contains(projectionRect().x(), nextYTick))
         break;
-      if (!yTicks.contains(nextYMinorTick)) {
-        yMinTicks << nextYMinorTick;
+      yTicks << nextYTick;
+    }
+
+    qreal yMinorTickSpacing = 0;
+    if (_yAxisMinorTickCount > 0) {
+      yMinorTickSpacing = yMajorTickSpacing / _yAxisMinorTickCount;
+    }
+    qreal firstYMinorTick = firstYTick + yMinorTickSpacing;
+
+    if (yMinorTickSpacing != 0) {
+      iy = 0;
+      qreal nextYMinorTick = firstYMinorTick;
+      while (1) {
+        nextYMinorTick = firstYMinorTick + (iy++ * yMinorTickSpacing);
+        if (!projectionRect().contains(projectionRect().x(), nextYMinorTick))
+          break;
+        if (!yTicks.contains(nextYMinorTick)) {
+          yMinTicks << nextYMinorTick;
+        }
       }
     }
   }
--- branches/work/kst/portto4/kst/src/libkstapp/plotitem.h #775346:775347
@@ -257,7 +257,9 @@
 
     virtual void paintMajorTickLabels(QPainter *painter,
                                       const QList<qreal> &xMajorTicks,
-                                      const QList<qreal> &yMajorTicks);
+                                      const QList<qreal> &yMajorTicks,
+                                      const QList<QString> &xLabels,
+                                      const QList<QString> &yLabels);
 
     qreal calculatedLabelMarginWidth() const;
     void setCalculatedLabelMarginWidth(qreal marginWidth);
@@ -289,8 +291,9 @@
     qreal calculatedAxisMarginHeight() const;
     void setCalculatedAxisMarginHeight(qreal marginHeight);
 
-    void computeTicks(QList<qreal> *xMajorTicks, QList<qreal> *xMinorTicks, QList<qreal> *yMajorTicks, QList<qreal> *yMinorTicks) const;
+    void computeTicks(QList<qreal> *xMajorTicks, QList<qreal> *xMinorTicks, QList<qreal> *yMajorTicks, QList<qreal> *yMinorTicks, QList<QString> *xLabels, QList<QString> *yLabels) const;
     qreal computedMajorTickSpacing(Qt::Orientation orientation) const;
+    void computeLogTicks(QList<qreal> *MajorTicks, QList<qreal> *MinorTicks, QList<QString> *Labels, qreal min, qreal max, qreal size, MajorTickMode tickMode) const;
 
     QSizeF calculateXTickLabelBound(QPainter *painter, const QList<qreal> &xMajorTicks);
     QSizeF calculateYTickLabelBound(QPainter *painter, const QList<qreal> &yMajorTicks);
--- branches/work/kst/portto4/kst/src/libkstapp/plotrenderitem.cpp #775346:775347
@@ -121,6 +121,7 @@
 
 void PlotRenderItem::setXAxisLog(bool log) {
   _isXAxisLog = log;
+  plotItem()->setXAxisLog(log);
 }
 
 
@@ -141,6 +142,7 @@
 
 void PlotRenderItem::setYAxisLog(bool log) {
   _isYAxisLog = log;
+  plotItem()->setYAxisLog(log);
 }
 
 


More information about the Kst mailing list