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

Barth Netterfield netterfield at astro.utoronto.ca
Thu Jan 29 17:31:30 CET 2009


SVN commit 918204 by netterfield:

Fix some label and axis alignment issues.



 M  +1 -3      devel-docs/Kst2Specs/Bugs  
 M  +5 -1      devel-docs/Kst2Specs/FixedBugs  
 M  +75 -33    src/libkstapp/plotitem.cpp  
 M  +9 -6      src/libkstapp/plotitem.h  


--- branches/work/kst/portto4/kst/devel-docs/Kst2Specs/Bugs #918203:918204
@@ -11,10 +11,8 @@
 ---------
 
 Formatting/spacing issues:
-  -The spacing between the X-axis numbers and the axis is too small.
-  -The spacing between the Y-axis numbers and the axis doesn't seem to scale with window size.
   -The plot selection buttons are too small.
-
+*cbn*
 ---------
 
 Tooltips everywhere.
--- branches/work/kst/portto4/kst/devel-docs/Kst2Specs/FixedBugs #918203:918204
@@ -416,4 +416,8 @@
 to larger than some fixed minimum.  Now it defaults too small, but can
 be resized.
 *Mike*
---------
\ No newline at end of file
+---------
+
+Formatting/spacing issues:
+  -The spacing between the X-axis numbers and the axis is too small.
+  -The spacing between the Y-axis numbers and the axis doesn't seem to scale with window size.
--- branches/work/kst/portto4/kst/src/libkstapp/plotitem.cpp #918203:918204
@@ -48,10 +48,9 @@
 // Label Region Debugging.  0 Off, 1 On.
 #define DEBUG_LABEL_REGION 0
 
-static qreal TOP_MARGIN = 20.0;
+// FIXME:no magic numbers in pixels
 static qreal BOTTOM_MARGIN = 0.0;
 static qreal LEFT_MARGIN = 0.0;
-static qreal RIGHT_MARGIN = 20.0;
 
 namespace Kst {
 
@@ -71,6 +70,10 @@
   _calculatedLabelMarginHeight(0.0),
   _calculatedAxisMarginWidth(0.0),
   _calculatedAxisMarginHeight(0.0),
+  _calculatedAxisMarginVLead(0.0),
+  _calculatedAxisMarginHLead(0.0),
+  _calculatedAxisMarginROverflow(0.0),
+  _calculatedAxisMarginTOverflow(0.0),
   _leftPadding(0.0),
   _bottomPadding(0.0),
   _rightPadding(0.0),
@@ -519,8 +522,9 @@
   painter->save();
   painter->setFont(calculatedNumberLabelFont());
 
-  setCalculatedAxisMarginWidth(calculateLeftTickLabelBound(painter).width());
-  setCalculatedAxisMarginHeight(calculateBottomTickLabelBound(painter).height());
+  calculateBottomTickLabelBound(painter);
+  calculateLeftTickLabelBound(painter);
+  //setCalculatedAxisMarginWidth(calculateLeftTickLabelBound(painter).width());
 
   setCalculatedLeftLabelMargin(calculateLeftLabelBound(painter).width());
   setCalculatedRightLabelMargin(calculateRightLabelBound(painter).width());
@@ -720,9 +724,10 @@
     xLabelIt.next();
 
     QRectF bound = painter->boundingRect(QRectF(), flags, xLabelIt.value());
-    QPointF p = QPointF(mapXToPlot(xLabelIt.key()), plotRect().bottom() + bound.height() / 2.0);
+    bound.setWidth(bound.width());
+    QPointF p = QPointF(mapXToPlot(xLabelIt.key()), plotRect().bottom() + 
+        bound.height()*0.5 + _calculatedAxisMarginVLead);
     bound.moveCenter(p);
-
     if (xLabelRect.isValid()) {
       xLabelRect = xLabelRect.united(bound);
     } else {
@@ -737,7 +742,7 @@
 
   if (!_xAxis->baseLabel().isEmpty()) {
     QRectF bound = painter->boundingRect(QRectF(), flags, _xAxis->baseLabel());
-    QPointF p = QPointF(plotRect().left(), plotRect().bottom() + bound.height() * 2.0);
+    QPointF p = QPointF(plotRect().left(), plotRect().bottom() + bound.height() * 2.0 + _calculatedAxisMarginVLead);
     bound.moveBottomLeft(p);
 
     if (xLabelRect.isValid()) {
@@ -773,8 +778,8 @@
     yLabelIt.next();
 
     QRectF bound = painter->boundingRect(QRectF(), flags, yLabelIt.value());
-    bound.setWidth(bound.width() + 6);
-    QPointF p = QPointF(plotRect().left() - (bound.width() / 2.0), mapYToPlot(yLabelIt.key()));
+    bound.setWidth(bound.width());
+    QPointF p = QPointF(plotRect().left() - (bound.width() / 2.0) - _calculatedAxisMarginHLead, mapYToPlot(yLabelIt.key()));
     bound.moveCenter(p);
 
     if (yLabelRect.isValid()) {
@@ -1590,7 +1595,7 @@
 
 
 qreal PlotItem::calculatedRightLabelMargin() const {
-  qreal m = qMax(RIGHT_MARGIN, _calculatedRightLabelMargin);
+  qreal m = qMax(_calculatedAxisMarginROverflow, _calculatedRightLabelMargin);
 
   //No more than 1/4 the width of the plot
   if (width() < m * 4)
@@ -1628,7 +1633,7 @@
 
 
 qreal PlotItem::calculatedTopLabelMargin() const {
-  qreal m = qMax(TOP_MARGIN, _calculatedTopLabelMargin);
+  qreal m = qMax(_calculatedAxisMarginTOverflow, _calculatedTopLabelMargin);
 
   //No more than 1/4 the height of the plot
   if (height() < m * 4)
@@ -1732,7 +1737,6 @@
 QFont PlotItem::calculatedNumberLabelFont() {
   QFont font(_numberLabelFont);
   font.setPixelSize(parentView()->defaultFont(_numberLabelFontScale).pixelSize());
-
   return font;
 }
 
@@ -1834,8 +1838,7 @@
     rc.y = fm.ascent();
     Label::renderLabel(rc, parsed->chunk);
 
-    bottomLabel.moveTopLeft(plotAxisRect().bottomLeft());
-    bottomLabel.moveTopLeft(QPointF(bottomLabel.topLeft().x() + ((bottomLabel.width() / 2) - (rc.x / 2)), bottomLabel.topLeft().y()));
+    bottomLabel.moveBottomLeft(QPointF(plotRect().center().x()-rc.x/2, rect().bottomLeft().y()));
 
     if (rc.x > 0)
       painter->drawPixmap(bottomLabel.topLeft(), pixmap, QRectF(0, 0, rc.x, bottomLabel.height()));
@@ -1981,9 +1984,7 @@
       rc.y = fm.ascent();
       Label::renderLabel(rc, parsed->chunk);
 
-      topLabel.moveBottomLeft(plotAxisRect().topLeft());
-      topLabel.moveTopLeft(QPointF(topLabel.topLeft().x() + ((topLabel.width() / 2) - (rc.x / 2)), topLabel.topLeft().y()));
-
+      topLabel.moveTopLeft(QPointF(plotRect().center().x()-rc.x/2, 0));
       if (rc.x > 0)
         painter->drawPixmap(topLabel.topLeft(), pixmap, QRectF(0, 0, rc.x, topLabel.height()));
     }
@@ -2046,26 +2047,30 @@
   return _calculatedAxisMarginHeight;
 }
 
+/** This function calculates and sets three things:
+      _calculatedAxisMarginVLead: spacing between bottom of plotRect and top of axis labels
+      _calculatedAxisMarginROverflow: rightmost axis number extension beyond plotRect 
+      _calculatedAxisMarginHeight: the height of the axis numbers
+*/
+void PlotItem::calculateBottomTickLabelBound(QPainter *painter) {
+  qreal inHeight = _calculatedAxisMarginHeight;
+  qreal inVLead = _calculatedAxisMarginVLead;
+  qreal inROver = _calculatedAxisMarginROverflow;
+  QRectF xLabelRect;
 
-void PlotItem::setCalculatedAxisMarginHeight(qreal marginHeight) {
-  qreal before = this->calculatedAxisMarginHeight();
-  _calculatedAxisMarginHeight = marginHeight;
-  if (before != this->calculatedAxisMarginHeight())
-    emit marginsChanged();
-}
+  int flags = Qt::TextSingleLine | Qt::AlignCenter;
 
+  _calculatedAxisMarginVLead = painter->fontMetrics().boundingRect('0').height()/2;
 
-QSizeF PlotItem::calculateBottomTickLabelBound(QPainter *painter) {
-  QRectF xLabelRect;
-  int flags = Qt::TextSingleLine | Qt::AlignCenter;
-
   if (_xAxis->isAxisVisible()) {
+    // future potential optimization: only get bounds of the rightmost label 
+    // but remember: the axis may be reversed.
     QMapIterator<qreal, QString> xLabelIt(_xAxis->axisLabels());
     while (xLabelIt.hasNext()) {
       xLabelIt.next();
 
       QRectF bound = painter->boundingRect(QRectF(), flags, xLabelIt.value());
-      QPointF p(mapXToPlot(xLabelIt.key()), plotRect().bottom() + bound.height() / 2.0);
+      QPointF p(mapXToPlot(xLabelIt.key()), plotRect().bottom() + bound.height() / 2.0 + _calculatedAxisMarginVLead);
       bound.moveCenter(p);
 
       if (xLabelRect.isValid()) {
@@ -2075,6 +2080,7 @@
       }
     }
   }
+  xLabelRect.setHeight(xLabelRect.height() + _calculatedAxisMarginVLead);
 
   if (!_xAxis->baseLabel().isEmpty()) {
     qreal height = painter->boundingRect(QRectF(), flags, _xAxis->baseLabel()).height();
@@ -2082,13 +2088,36 @@
       xLabelRect.setHeight(xLabelRect.height() + (height - calculatedBottomLabelMargin()));
     }
   }
-  return xLabelRect.size();
+
+  _calculatedAxisMarginHeight = xLabelRect.height();
+  if (xLabelRect.right() > plotRect().right()) {
+    _calculatedAxisMarginROverflow = qMax(ViewItem::sizeOfGrip().width()/1.2, xLabelRect.right() - plotRect().right());
+  } else {
+    _calculatedAxisMarginROverflow = ViewItem::sizeOfGrip().width()/1.2;
+  }
+
+  if ((inHeight != _calculatedAxisMarginHeight) 
+       || (inVLead != _calculatedAxisMarginVLead) 
+       || (inROver != _calculatedAxisMarginROverflow)) {
+    emit marginsChanged();
+  }
 }
 
+/** This function calculates and sets three things:
+      _calculatedAxisMarginHLead: spacing between left of plotRect and right of axis labels
+      _calculatedAxisMarginVOverflow: topmost axis number extension beyond plotRect 
+      _calculatedAxisMarginWidth: the width of the widest axis number
+*/
+void PlotItem::calculateLeftTickLabelBound(QPainter *painter) {
+  qreal inWidth = _calculatedAxisMarginWidth;
+  qreal inHLead = _calculatedAxisMarginHLead;
+  qreal inTOver = _calculatedAxisMarginTOverflow;
 
-QSizeF PlotItem::calculateLeftTickLabelBound(QPainter *painter) {
   QRectF yLabelRect;
   int flags = Qt::TextSingleLine | Qt::AlignCenter;
+
+  _calculatedAxisMarginHLead = painter->fontMetrics().boundingRect('[').height()/2;
+
   if (_yAxis->isAxisVisible()) {
 
     QMapIterator<qreal, QString> yLabelIt(_yAxis->axisLabels());
@@ -2096,8 +2125,8 @@
       yLabelIt.next();
 
       QRectF bound = painter->boundingRect(QRectF(), flags, yLabelIt.value());
-      bound.setWidth(bound.width() + 6);
-      QPointF p(plotRect().left() - bound.width() / 2.0, mapYToPlot(yLabelIt.key()));
+      //bound.setWidth(bound.width() + 6);
+      QPointF p(plotRect().left() - bound.width() / 2.0 - _calculatedAxisMarginHLead, mapYToPlot(yLabelIt.key()));
       bound.moveCenter(p);
 
       if (yLabelRect.isValid()) {
@@ -2107,13 +2136,26 @@
       }
     }
   }
+
+  yLabelRect.setWidth(yLabelRect.width() + _calculatedAxisMarginHLead);
   if (!_yAxis->baseLabel().isEmpty()) {
     qreal height = painter->boundingRect(QRectF(), flags, _yAxis->baseLabel()).height();
     if (calculatedLeftLabelMargin() < height) {
       yLabelRect.setWidth(yLabelRect.width() + (height - calculatedLeftLabelMargin()));
     }
   }
-  return yLabelRect.size();
+  _calculatedAxisMarginWidth = yLabelRect.width();
+  if (yLabelRect.top() < plotRect().top()) {
+    _calculatedAxisMarginTOverflow = qMax(ViewItem::sizeOfGrip().width()/1.2, -yLabelRect.top() + plotRect().top());
+  } else {
+    _calculatedAxisMarginTOverflow = ViewItem::sizeOfGrip().width()/1.2;
+  }
+  qDebug() << "marginWidth: " << _calculatedAxisMarginWidth << " plotWidth: " << rect().width();
+  if ((inWidth != _calculatedAxisMarginWidth) 
+       || (inHLead != _calculatedAxisMarginHLead) 
+       || (inTOver != _calculatedAxisMarginTOverflow)) {
+     emit marginsChanged();
+  }
 }
 
 
--- branches/work/kst/portto4/kst/src/libkstapp/plotitem.h #918203:918204
@@ -125,7 +125,7 @@
     void setLabelsVisible(bool visible);
 
     qreal axisMarginWidth() const;
-    qreal axisMarginHeight() const;
+    qreal axisMarginHeight() const; // zzz
 
     QString bottomLabelOverride() const;
     void setBottomLabelOverride(const QString &label);
@@ -294,7 +294,7 @@
     virtual void paintMinorTicks(QPainter *painter);
 
     virtual void paintTickLabels(QPainter *painter);
-    virtual void paintBottomTickLabels(QPainter *painter);
+    virtual void paintBottomTickLabels(QPainter *painter); // zzz
     virtual void paintLeftTickLabels(QPainter *painter);
 
     virtual void paintPlotMarkers(QPainter *painter);
@@ -337,11 +337,10 @@
     qreal calculatedAxisMarginWidth() const;
     void setCalculatedAxisMarginWidth(qreal marginWidth);
 
-    qreal calculatedAxisMarginHeight() const;
-    void setCalculatedAxisMarginHeight(qreal marginHeight);
+    qreal calculatedAxisMarginHeight() const; // zzz
 
-    QSizeF calculateBottomTickLabelBound(QPainter *painter);
-    QSizeF calculateLeftTickLabelBound(QPainter *painter);
+    void calculateBottomTickLabelBound(QPainter *painter); // zzz
+    void calculateLeftTickLabelBound(QPainter *painter);
 
     void setCurrentZoomState(ZoomState zoomState);
 
@@ -362,6 +361,10 @@
     qreal _calculatedLabelMarginHeight;
     qreal _calculatedAxisMarginWidth;
     qreal _calculatedAxisMarginHeight;
+    qreal _calculatedAxisMarginVLead; 
+    qreal _calculatedAxisMarginHLead; 
+    qreal _calculatedAxisMarginROverflow;
+    qreal _calculatedAxisMarginTOverflow;
 
     qreal _leftPadding;
     qreal _bottomPadding;


More information about the Kst mailing list