lib/ScalePlot.cpp

Go to the documentation of this file.
00001 /*
00002  *  Qtstalker stock charter
00003  *
00004  *  Copyright (C) 2001-2007 Stefan S. Stratigakos
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00019  *  USA.
00020  */
00021 
00022 #include "ScalePlot.h"
00023 #include <qpainter.h>
00024 #include <qpen.h>
00025 #include <qpoint.h>
00026 #include <qpointarray.h>
00027 #include <math.h>
00028 #include <qpaintdevicemetrics.h>
00029 #include <qstring.h>
00030 #include <qmemarray.h>
00031 
00032 #define SCALE_WIDTH 60
00033 
00034 ScalePlot::ScalePlot (QWidget *w) : QWidget(w)
00035 {
00036   setBackgroundMode(NoBackground);
00037   scaleWidth = SCALE_WIDTH;
00038   backgroundColor.setNamedColor("black");
00039   borderColor.setNamedColor("white");
00040   mainFlag = FALSE;
00041   scaleToScreen = FALSE;
00042   logScale = FALSE;
00043   close = 0;
00044   activeFlag = FALSE;
00045 
00046   plotFont.setFamily("Helvetica");
00047   plotFont.setPointSize(12);
00048   plotFont.setWeight(50);
00049   
00050   setMinimumWidth(scaleWidth);
00051   setMaximumWidth(scaleWidth);
00052 }
00053 
00054 ScalePlot::~ScalePlot ()
00055 {
00056 }
00057 
00058 void ScalePlot::clear ()
00059 {
00060   close = 0;
00061 }
00062 
00063 void ScalePlot::setData (double c)
00064 {
00065   close = c;
00066   activeFlag = TRUE;
00067 }
00068 
00069 void ScalePlot::setMainFlag (bool d)
00070 {
00071   mainFlag = d;
00072 }
00073 
00074 void ScalePlot::setScaleToScreen (bool d)
00075 {
00076   scaleToScreen = d;
00077 }
00078 
00079 void ScalePlot::setLogScale (bool d)
00080 {
00081   logScale = d;
00082 }
00083 
00084 void ScalePlot::draw ()
00085 {
00086   buffer.fill(backgroundColor);
00087 
00088   if (activeFlag)
00089   {
00090     if (buffer.isNull())
00091     {
00092       buffer.resize(this->width(), this->height());
00093       buffer.fill(backgroundColor);
00094     }
00095   
00096     drawScale();
00097   }
00098 
00099   paintEvent(0);
00100 }
00101 
00102 void ScalePlot::drawRefresh ()
00103 {
00104   paintEvent(0);
00105 }
00106 
00107 void ScalePlot::paintEvent (QPaintEvent *)
00108 {
00109   bitBlt(this, 0, 0, &buffer);
00110 }
00111 
00112 void ScalePlot::resizeEvent (QResizeEvent *event)
00113 {
00114   buffer.resize(event->size());
00115   draw();
00116 }
00117 
00118 void ScalePlot::setScaleWidth (int d)
00119 {
00120   if (d > 999 || d < SCALE_WIDTH)
00121     return;
00122   else
00123     scaleWidth = d;
00124 }
00125 
00126 void ScalePlot::setBackgroundColor (QColor &d)
00127 {
00128   backgroundColor = d;
00129 }
00130 
00131 void ScalePlot::setBorderColor (QColor &d)
00132 {
00133   borderColor = d;
00134 }
00135 
00136 void ScalePlot::setPlotFont (QFont &d)
00137 {
00138   plotFont = d;
00139 }
00140 
00141 void ScalePlot::drawScale ()
00142 {
00143   QPainter painter;
00144   painter.begin(&buffer);
00145   painter.setFont(plotFont);
00146   painter.setPen(QPen(borderColor, 1, QPen::SolidLine));
00147 
00148   painter.fillRect(0, 0, buffer.width(), buffer.height(), backgroundColor);
00149   
00150   QMemArray<double> scaleArray;
00151   scaler.getScaleArray(scaleArray);
00152   
00153   QFontMetrics fm(plotFont);
00154 
00155   int x = 0;
00156   int loop;
00157   for (loop = 0; loop < (int) scaleArray.size(); loop++)
00158   {
00159     int y = scaler.convertToY(scaleArray[loop]);
00160     painter.drawLine (x, y, x + 4, y);
00161 
00162     // draw the text
00163     QString s;
00164     strip(scaleArray[loop], 4, s);
00165     
00166     // abbreviate too many (>=3) trailing zeroes in large numbers on y-axes
00167     if (! mainFlag)
00168     {
00169       bool flag = FALSE;
00170       
00171       if (s.toDouble() < 0)
00172       {
00173         flag = TRUE;
00174         s.remove(0, 1);  
00175       }
00176       
00177       if (s.toDouble() >= 1000000000)
00178       {
00179         strip(s.toDouble() / 1000000000, 4, s);
00180         s.append("b");
00181       }
00182       else
00183       {
00184         if (s.toDouble() >= 1000000)
00185         {
00186           strip(s.toDouble() / 1000000, 4, s);
00187           s.append("m");
00188         }
00189 //        else
00190 //        {
00191 //          if (s.toDouble() >= 1000)
00192 //          {
00193 //            strip(s.toDouble() / 1000, 4, s);
00194 //            s.append("k");
00195 //          }
00196 //        }
00197       }
00198       
00199       if (flag)
00200         s.prepend("-");
00201     }
00202     
00203     painter.drawText(x + 7, y + (fm.height() / 2), s);
00204   }
00205 
00206   painter.drawLine (x, 0, x, buffer.height());
00207   
00208   // draw the last value pointer on the scale of main plot
00209   int y = scaler.convertToY(close);
00210     
00211   QPointArray array;
00212   array.setPoints(3, x + 2, y,
00213                   x + 8, y - 4,
00214                   x + 8, y + 4);
00215   painter.setBrush(borderColor);
00216   painter.drawPolygon(array, TRUE, 0, -1);
00217 
00218   painter.end();
00219 }
00220 
00221 void ScalePlot::strip (double d, int p, QString &s)
00222 {
00223   s = QString::number(d, 'f', p);
00224 
00225   while (1)
00226   {
00227     if (s.find('.', -1, TRUE) != -1)
00228     {
00229       s.truncate(s.length() - 1);
00230       break;
00231     }
00232     else
00233     {
00234       if (s.find('0', -1, TRUE) != -1)
00235         s.truncate(s.length() - 1);
00236       else
00237         break;
00238     }
00239   }
00240 }
00241 
00242 void ScalePlot::slotScaleToScreenChanged (bool d)
00243 {
00244   setScaleToScreen(d);
00245   draw();
00246 }
00247 
00248 void ScalePlot::slotLogScaleChanged (bool d)
00249 {
00250   setLogScale(d);
00251   draw();
00252 }
00253 
00254 void ScalePlot::setScaler (Scaler &d)
00255 {
00256   scaler = d;
00257 }
00258