lib/DatePlot.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 "DatePlot.h"
00023 #include <qpainter.h>
00024 #include <qpaintdevicemetrics.h>
00025 #include <qstring.h>
00026 #include <qdatetime.h>
00027 
00028 #define SCALE_WIDTH 60
00029 #define DATE_HEIGHT 30
00030 
00031 DatePlot::DatePlot (QWidget *w) : QWidget(w)
00032 {
00033   setBackgroundMode(NoBackground);
00034   scaleWidth = SCALE_WIDTH;
00035   startX = 2;
00036   backgroundColor.setNamedColor("black");
00037   borderColor.setNamedColor("white");
00038   pixelspace = 0;
00039   interval = BarData::DailyBar;
00040   startIndex = 0;
00041   data = 0;
00042 //  setMouseTracking(TRUE);
00043   setFocusPolicy(QWidget::ClickFocus);
00044 
00045   plotFont.setFamily("Helvetica");
00046   plotFont.setPointSize(12);
00047   plotFont.setWeight(50);
00048   
00049   setMinimumHeight(DATE_HEIGHT);
00050   setMaximumHeight(DATE_HEIGHT);
00051   
00052   dateList.setAutoDelete(TRUE);
00053 }
00054 
00055 DatePlot::~DatePlot ()
00056 {
00057 }
00058 
00059 void DatePlot::clear ()
00060 {
00061   data = 0;
00062   dateList.clear();
00063 }
00064 
00065 void DatePlot::setData (BarData *l)
00066 {
00067   if (! l->count())
00068     return;
00069     
00070   data = l;
00071   dateList.clear();
00072     
00073   switch (interval)
00074   {
00075     case BarData::Minute1:
00076     case BarData::Minute5:
00077     case BarData::Minute10:
00078     case BarData::Minute15:
00079     case BarData::Minute30:
00080     case BarData::Minute60:
00081       getMinuteDate();
00082       break;
00083     case BarData::WeeklyBar:
00084       getWeeklyDate();
00085       break;
00086     case BarData::MonthlyBar:
00087       getMonthlyDate();
00088       break;
00089     default:
00090       getDailyDate();
00091       break;
00092   }
00093 }
00094 
00095 void DatePlot::draw ()
00096 {
00097   buffer.fill(backgroundColor);
00098 
00099   if (dateList.count() && isShown())
00100   {
00101     QPainter painter;
00102     painter.begin(&buffer);
00103     painter.setPen(borderColor);
00104     painter.setFont(plotFont);
00105 
00106     QFontMetrics fm(plotFont);
00107     int x = startX;
00108     int loop = startIndex;
00109   
00110     // clear date area
00111     painter.fillRect(0, buffer.height(), buffer.width() - scaleWidth, buffer.height(), backgroundColor);
00112 
00113     // draw the seperator line
00114     painter.drawLine (0, 0, buffer.width() - scaleWidth, 0);
00115 
00116     while(x <= (buffer.width() - scaleWidth) && loop < (int) dateList.count())
00117     {
00118       TickItem *item = dateList.at(loop);
00119       
00120       if (item->flag)
00121       {
00122         if (! item->tick)
00123         {
00124           // draw the short tick
00125           painter.drawLine (x, 1, x, 4);
00126           
00127           painter.drawText (x - (fm.width(item->text, -1) / 2),
00128                             fm.height() + 2,
00129                             item->text,
00130                             -1);
00131         }
00132         else
00133         {
00134           // draw the long tick
00135           painter.drawLine (x, 1, x, buffer.height() - fm.height() - 2);
00136           
00137           painter.drawText (x - (fm.width(item->text, -1) / 2),
00138                             buffer.height() - 2,
00139                             item->text,
00140                             -1);
00141         }
00142       }
00143               
00144       x = x + pixelspace;
00145       loop++;
00146     }
00147     
00148     painter.end();
00149   }
00150 
00151   paintEvent(0);
00152 }
00153 
00154 void DatePlot::drawRefresh ()
00155 {
00156   paintEvent(0);
00157 }
00158 
00159 void DatePlot::paintEvent (QPaintEvent *)
00160 {
00161   bitBlt(this, 0, 0, &buffer);
00162 }
00163 
00164 void DatePlot::resizeEvent (QResizeEvent *event)
00165 {
00166   buffer.resize(event->size());
00167   draw();
00168 }
00169 
00170 void DatePlot::setBackgroundColor (QColor d)
00171 {
00172   backgroundColor = d;
00173 }
00174 
00175 void DatePlot::setBorderColor (QColor d)
00176 {
00177   borderColor = d;
00178 }
00179 
00180 void DatePlot::setPlotFont (QFont d)
00181 {
00182   plotFont = d;
00183 }
00184 
00185 void DatePlot::setPixelspace (int d)
00186 {
00187   pixelspace = d;
00188 }
00189 
00190 void DatePlot::setIndex (int d)
00191 {
00192   startIndex = d;
00193 }
00194 
00195 void DatePlot::setInterval (BarData::BarLength d)
00196 {
00197   interval = d;
00198 }
00199 
00200 void DatePlot::getMinuteDate ()
00201 {
00202   xGrid.resize(0);
00203   int loop = 0;
00204   QDateTime nextHour, oldDay;
00205   data->getDate(loop, nextHour);
00206   data->getDate(loop, oldDay);
00207   nextHour.setTime(QTime(nextHour.time().hour(), 0, 0, 0));
00208   
00209 //  if ((nextHour.getHour() % 2) == 0)
00210   if (interval != BarData::Minute1)
00211     nextHour = nextHour.addSecs(7200);
00212   else
00213     nextHour = nextHour.addSecs(3600);
00214 
00215   while(loop < (int) data->count())
00216   {
00217     QDateTime date;
00218     data->getDate(loop, date);
00219     
00220     TickItem *item = new TickItem;
00221     item->flag = 0;
00222     
00223     if (date.date().day() != oldDay.date().day())
00224     {
00225       item->flag = 1;
00226       item->tick = 1;
00227       item->text = date.date().toString("MMM d");
00228       oldDay = date;
00229       
00230       xGrid.resize(xGrid.size() + 1);
00231       xGrid[xGrid.size() - 1] = loop;
00232     }
00233     else
00234     {
00235       if (date >= nextHour)
00236       {
00237         if (interval < BarData::Minute30)
00238         {
00239           item->flag = 1;
00240           item->tick = 0;
00241           item->text = QString::number(date.time().hour()) + ":00";
00242           
00243           xGrid.resize(xGrid.size() + 1);
00244           xGrid[xGrid.size() - 1] = loop;
00245         }
00246       }
00247     }
00248     
00249     if (date >= nextHour)
00250     {
00251       nextHour = date;
00252       nextHour.setTime(QTime(date.time().hour(), 0, 0, 0));
00253 //      if ((date.getHour() % 2) == 0)
00254       if (interval != BarData::Minute1)
00255         nextHour = nextHour.addSecs(7200);
00256       else
00257         nextHour = nextHour.addSecs(3600);
00258     }
00259 
00260     dateList.append(item);
00261     loop++;
00262   }
00263 }
00264 
00265 void DatePlot::getDailyDate ()
00266 {
00267   int loop = 0;
00268   xGrid.resize(0);
00269 
00270   QDateTime dt;
00271   data->getDate(loop, dt);
00272   QDate oldDate = dt.date();
00273   QDate oldWeek = oldDate;
00274   oldWeek = oldWeek.addDays(7 - oldWeek.dayOfWeek());
00275 
00276   while(loop < (int) data->count())
00277   {
00278     TickItem *item = new TickItem;
00279     item->flag = 0;
00280   
00281     data->getDate(loop, dt);
00282     QDate date = dt.date();
00283 
00284     if (date.month() != oldDate.month())
00285     {
00286       item->flag = 1;
00287       item->tick = 1;
00288       item->text = date.toString("MMM'yy");
00289       oldDate = date;
00290       oldWeek = date;
00291       oldWeek = oldWeek.addDays(7 - oldWeek.dayOfWeek());
00292       
00293       xGrid.resize(xGrid.size() + 1);
00294       xGrid[xGrid.size() - 1] = loop;
00295     }
00296     else
00297     {
00298       // if start of new week make a tick
00299       if (date > oldWeek)
00300       {
00301         item->flag = 1;
00302         item->tick = 0;
00303         item->text = date.toString("d");
00304         oldWeek = date;
00305         oldWeek = oldWeek.addDays(7 - oldWeek.dayOfWeek());
00306       }
00307     }
00308 
00309     dateList.append(item);
00310     loop++;
00311   }
00312 }
00313 
00314 void DatePlot::getWeeklyDate ()
00315 {
00316   xGrid.resize(0);
00317   int loop = 0;
00318 
00319   QDateTime dt;
00320   data->getDate(loop, dt);
00321   QDate oldMonth = dt.date();
00322 
00323   while(loop < (int) data->count())
00324   {
00325     TickItem *item = new TickItem;
00326     item->flag = 0;
00327   
00328     data->getDate(loop, dt);
00329     QDate date = dt.date();
00330 
00331     if (date.year() != oldMonth.year())
00332     {
00333       xGrid.resize(xGrid.size() + 1);
00334       xGrid[xGrid.size() - 1] = loop;
00335     }
00336     
00337     if (date.month() != oldMonth.month())
00338     {
00339       oldMonth = date;
00340       item->flag = 1;
00341       item->tick = 0;
00342 //      item->text = date.toString("MMM");
00343       item->text = date.toString("M");
00344       
00345       if (date.month() == 1)
00346       {
00347         item->tick = 1;
00348 //        item->text = date.toString("MMM'yy");
00349         item->text = date.toString("yy");
00350       }
00351     }
00352     
00353     dateList.append(item);
00354     loop++;
00355   }
00356 }
00357 
00358 void DatePlot::getMonthlyDate ()
00359 {
00360   xGrid.resize(0);
00361   int loop = 0;
00362   QDateTime dt;
00363   data->getDate(loop, dt);
00364   QDate oldYear = dt.date();
00365 
00366   while(loop < (int) data->count())
00367   {
00368     TickItem *item = new TickItem;
00369     item->flag = 0;
00370   
00371     data->getDate(loop, dt);
00372     QDate date = dt.date();
00373 
00374     if (date.year() != oldYear.year())
00375     {
00376       oldYear = date;
00377       item->flag = 1;
00378       item->tick = 1;
00379       item->text = date.toString("yyyy");
00380       
00381       xGrid.resize(xGrid.size() + 1);
00382       xGrid[xGrid.size() - 1] = loop;
00383     }
00384 
00385     dateList.append(item);
00386     loop++;
00387   }
00388 }
00389 
00390 QMemArray<int> & DatePlot::getXGrid ()
00391 {
00392   return xGrid;
00393 }
00394