00001
00002
00003 #ifndef Impala_Application_MediaTable_BarPlot_h
00004 #define Impala_Application_MediaTable_BarPlot_h
00005
00006 #ifndef OglGui_WindowView2D_h
00007 #include "OglGui/WindowView2D.h"
00008 #endif
00009
00010 #include "../TableDataView.h"
00011 #include "../TableViewCache.h"
00012
00013 #include "../TableDataViewController.h"
00014
00015 namespace Impala {
00016 namespace Application {
00017 namespace MediaTable {
00018
00019 class BarPlot : public OglGui::Window,
00020 public OglGui::WindowListener,
00021 public TableDataViewController
00022 {
00023 public:
00024 typedef OglGui::Window Window;
00025 typedef OglGui::WindowView2D WindowView2D;
00026 typedef OglGui::StaticText StaticText;
00027
00028 BarPlot(Window* parent, TableDataView* view,
00029 int x, int y, int w, int h) :
00030 Window(parent,x,y,w,h),
00031 TableDataViewController(view)
00032 {
00033 Init(w,h);
00034 }
00035
00036
00037
00038
00039
00040
00041
00042 void ShowRange(int first, int last)
00043 {
00044 GetTableDataView()->SetStartRow(first);
00045 GetTableDataView()->SetNumberOfRows(last-first+1);
00046 }
00047
00048 void BarColors(ULONG borderCol, ULONG bgCol, ULONG fillCol)
00049 {
00050 mBarBorderColor = borderCol;
00051 mBarBgColor = bgCol;
00052 mBarFillColor = fillCol;
00053 }
00054
00055
00056
00057
00058 int FirstVisible() { return GetTableDataView()->GetStartRow(); }
00059 int LastVisible() {
00060 return GetTableDataView()->GetStartRow() + GetTableDataView()->GetNumberOfRows();
00061 }
00062
00063 void MinimumViewSize(int sz) { mMinViewSize = sz; }
00064 int MinimumViewSize() { return mMinViewSize; }
00065
00066
00067 void Clear()
00068 {
00069 mMax = 0;
00070 mCache = 0;
00071 }
00072
00073 void AddColumnsFromDataSource(String x, String y, String image = "", String fill="")
00074 {
00075 GetTableDataView()->SetStartRow(0);
00076 GetTableDataView()->SetNumberOfRows(GetTableDataView()->GetFilteredRows());
00077 mCache = new TableViewCache(this, GetTableDataView());
00078
00079 mColumnX = x;
00080 mColumnY = y;
00081 mColumnImage = image;
00082 mColumnFill = fill;
00083
00084 ILOG_DEBUG("GetFilteredRows = " << GetTableDataView()->GetFilteredRows());
00085 for (int i=0; i<GetTableDataView()->GetFilteredRows(); i++)
00086 {
00087 int y;
00088 if(GetTableDataView()->GetColumn(mColumnY)->GetType() == TableDataSource::TYPE_INT)
00089 y = GetTableDataView()->GetSortedIntData(mColumnY, FirstVisible()+i);
00090 else
00091 y = GetTableDataView()->GetSortedDoubleData(mColumnY, FirstVisible()+i);
00092 if (y > mMax) mMax = y;
00093 }
00094 ILOG_DEBUG("Max for " << mColumnY << " = " << mMax);
00095 double newMin, newMax;
00096 double step = findStep(0.0, (double) mMax, newMin, newMax);
00097 mStep = ceil(step);
00098 mMax = ceil(newMax);
00099 }
00100
00101 int NrVisible()
00102 {
00103 return LastVisible()-FirstVisible();
00104 }
00105
00106 virtual void DisplayFunc()
00107 {
00108 OGC oldOGC;
00109 OGCSave(&oldOGC);
00110 Window::DisplayFunc();
00111 if (NrVisible() != 0 && mCache != 0)
00112 {
00113 ShowHistogram();
00114 HandleViews();
00115 }
00116 OGCRestore(&oldOGC);
00117 }
00118
00119 TableViewCache* GetCache()
00120 {
00121 return mCache;
00122 }
00123
00124 protected:
00125 void HandleViews()
00126 {
00127 mCache->HideViews();
00128 SetSolidLineColor(mBarBorderColor);
00129
00130 mSlotSize = (W() - AXIS_X) / (float) NrVisible();
00131 if(mColumnImage == "") mSlotSize = 0;
00132 if(mSlotSize < mMinViewSize) {
00133 mSlotSize = 0;
00134 DrawRectangle(AXIS_X, AXIS_Y, W()-AXIS_X, 0);
00135 return;
00136 }
00137
00138 for(int i=0; i < NrVisible(); i++) {
00139 int x = AXIS_X + i * mSlotSize;
00140 mCache->ShowView(mColumnImage, FirstVisible()+i, x, AXIS_Y, mSlotSize-1, mSlotSize-1);
00141 DrawRectangle(x, AXIS_Y, mSlotSize, mSlotSize);
00142 }
00143
00144 if (mCache && mCache->ProcessDelayLoad())
00145 UpdateScene();
00146 }
00147
00148 void ShowXLabel(int value, int x, int slotSz)
00149 {
00150 if (slotSz < 24)
00151 return;
00152
00153 int txtX, txtY;
00154 char buf[12];
00155 sprintf(buf,"%d", value);
00156 oglSys.AlignTextXY(mOglWnd,buf,oglCenterAlign,oglCenterAlign,
00157 slotSz, 20, &txtX, &txtY);
00158 if(txtX >= 0)
00159 oglSys.PosColPrintf(mOglWnd,x+txtX,txtY+2,mBarBorderColor,buf);
00160 }
00161
00162 void ShowYLabel(int value, int y)
00163 {
00164 int txtX, txtY;
00165 char buf[10];
00166 sprintf(buf,"%d", value);
00167 oglSys.AlignTextXY(mOglWnd,buf,oglRightAlign,oglBottomAlign,
00168 AXIS_X-3, 0, &txtX, &txtY);
00169 oglSys.PosColPrintf(mOglWnd,txtX,y-4,mBarBorderColor,buf);
00170 }
00171
00172 void ShowHistogram()
00173 {
00174 if(!NrVisible()) return;
00175 float slotSz = (W() - AXIS_X) / (float) NrVisible();
00176 float binSz = (slotSz >= 2) ? slotSz / 2 : 1;
00177 float viewH = (slotSz >= mMinViewSize) ? slotSz : 0;
00178 bool oneCol = mBarBgColor == mBarFillColor &&
00179 mBarBgColor == mBarBorderColor;
00180
00181 int yHeight = H()-AXIS_Y-viewH-7;
00182
00183 for (int i=0; i < NrVisible(); i++)
00184 {
00185 int x = AXIS_X + i * slotSz;
00186 int y;
00187 if(GetTableDataView()->GetColumn(mColumnY)->GetType() == TableDataSource::TYPE_INT)
00188 y = GetTableDataView()->GetSortedIntData(mColumnY, FirstVisible()+i);
00189 else
00190 y = GetTableDataView()->GetSortedDoubleData(mColumnY, FirstVisible()+i);
00191 int barH = (y/(float) mMax) * yHeight;
00192
00193 int mark = GetTableDataView()->GetMark(FirstVisible()+i);
00194
00195 if (barH >= 1)
00196 {
00197 SetSolidFillColor(mBarBgColor);
00198 if (mark)
00199 SetSolidFillColor(MarkToColor(mark));
00200 FillRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,barH);
00201 }
00202 if (!oneCol) {
00203 double fill = GetTableDataView()->GetSortedNormalizedData(mColumnFill, FirstVisible()+i);
00204 if (fill * barH >= 1)
00205 {
00206 SetSolidFillColor(mBarFillColor);
00207 FillRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,fill*barH);
00208 }
00209 if (barH >= 1)
00210 {
00211 SetSolidLineColor(mBarBorderColor);
00212 if (mark)
00213 SetSolidFillColor(MarkToColor(mark));
00214 DrawRectangle(x+slotSz/4,AXIS_Y+viewH,binSz,barH);
00215 }
00216 }
00217 int xValue;
00218 if(GetTableDataView()->GetColumn(mColumnX)->GetType() == TableDataSource::TYPE_INT)
00219 xValue = GetTableDataView()->GetSortedIntData(mColumnX, FirstVisible()+i);
00220 else
00221 xValue = GetTableDataView()->GetSortedDoubleData(mColumnX, FirstVisible()+i);
00222 ShowXLabel(xValue, x, slotSz);
00223 }
00224
00225 SetSolidLineColor(mBarBorderColor);
00226
00227 DrawRectangle(AXIS_X, AXIS_Y+viewH, 0, yHeight);
00228 for(long i=0; i <= mMax; i+= mStep) {
00229
00230 int y = (i/(float) mMax) * yHeight+AXIS_Y+viewH;
00231 DrawRectangle(AXIS_X, y, -3, 0);
00232 ShowYLabel(i, y);
00233 }
00234 }
00235
00236 virtual void KeyboardFunc(int c, int state)
00237 {
00238 switch (c)
00239 {
00240 case '-':
00241 if(GetTableDataView()->GetNumberOfRows() > 1)
00242 {
00243 GetTableDataView()->SetNumberOfRows(GetTableDataView()->GetNumberOfRows()-1);
00244 UpdateScene();
00245 }
00246 break;
00247 case '=':
00248 GetTableDataView()->SetNumberOfRows(GetTableDataView()->GetNumberOfRows()+1);
00249 UpdateScene();
00250 break;
00251 default:
00252 TableDataViewController::KeyboardFunc(c, state);
00253 }
00254 }
00255
00256 virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00257 {
00258 static bool isDragging = false;
00259 static int lastX;
00260
00261 Window::MouseFunc(msg, btn, state, x, y);
00262 if (msg == oglMouseDown && btn == oglLeftButton)
00263 {
00264 isDragging = true;
00265 lastX = x;
00266 }
00267
00268 if (msg == oglMouseUp)
00269 isDragging = false;
00270
00271 if (state&oglShift)
00272 {
00273 int nrOfRows = GetTableDataView()->GetNumberOfRows() * (1.f+((x - lastX)/50.f));
00274 if(nrOfRows > 5)
00275 {
00276 GetTableDataView()->SetNumberOfRows(nrOfRows);
00277 UpdateScene();
00278 }
00279 }
00280 else if (state&oglControl)
00281 {
00282 int dX = (x - lastX)/10.f;
00283 if(dX != 0)
00284 {
00285 GetTableDataView()->SetStartRow(GetTableDataView()->GetStartRow()+dX);
00286 UpdateScene();
00287 }
00288 }
00289 lastX = x;
00290 }
00291
00292
00293 void UpdateNumberOfRows() {}
00294 void UpdateSelectionEvent() {}
00295
00296 private:
00297 void Init(int w, int h)
00298 {
00299 mFirstVisible = 0;
00300 mLastVisible = 10;
00301 mMinViewSize = 8;
00302 mMax = 0;
00303
00304 mBarBorderColor = oglGREY;
00305 mBarBgColor = oglGREY;
00306 mBarFillColor = oglGREY;
00307 }
00308
00309 double findStep(double min, double max, double& newMin, double& newMax) {
00310 double range = max - min;
00311 if(range < 0) range *= -1;
00312 double exponent = floor(log10(range));
00313 double coefficient = range/pow(10, exponent);
00314
00315 double step = 1;
00316 if(coefficient <= 5) {
00317 step = 0.5;
00318 if(coefficient <= 2.5) {
00319 step = 0.25;
00320 if(coefficient == 1) step = 0.1;
00321 }
00322 }
00323
00324 step *= pow(10, exponent);
00325 if(step == 2.5) step = 2;
00326
00327 newMin = floor(min/step)*step;
00328 newMax = ceil(max/step)*step;
00329
00330 if(min > max) return -step;
00331 return step;
00332 }
00333 double findStep(double& min, double& max) {return findStep(min, max, min, max);}
00334
00335 protected:
00336 TableViewCache* mCache;
00337 String mColumnX, mColumnY, mColumnFill, mColumnImage;
00338
00339 int mNrViews;
00340 int mFirstVisible;
00341 int mLastVisible;
00342 int mMinViewSize;
00343 long mMax;
00344 int mStep;
00345 float mSlotSize;
00346
00347 const static int AXIS_X = 65;
00348 const static int AXIS_Y = 20;
00349
00350 ULONG mBarBorderColor;
00351 ULONG mBarBgColor;
00352 ULONG mBarFillColor;
00353
00354 private:
00355 ILOG_VAR_DEC;
00356 };
00357
00358 ILOG_VAR_INIT(BarPlot, Application.TagsLife);
00359
00360 }
00361 }
00362 }
00363
00364 #endif