00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef Impala_Visualization_SimilarityTimeLine_h
00011 #define Impala_Visualization_SimilarityTimeLine_h
00012
00013 #include "Visualization/TimeLineViewStrip.h"
00014 #include "Visualization/SimilarityTimeLineListener.h"
00015 #include "Core/Table/SimilarityTableSet.h"
00016
00017 static char*
00018 sColorNamesSTL[] = {
00019 "red",
00020 "green",
00021 "blue",
00022 "magenta",
00023 "cyan",
00024 "yellow",
00025 "orange",
00026 "teal",
00027 "brown",
00028 "tomato",
00029 "DarkMagenta",
00030 "SoftBlue",
00031 "YellowGreen",
00032 "PeachPuff",
00033 "SaddleBrown",
00034 "SeaGreen",
00035 "SkyBlue",
00036 "Silver",
00037 "SlateBlue",
00038 "Violet",
00039 ""
00040 };
00041
00042
00043 namespace Impala {
00044 namespace Visualization {
00045
00046 class SimilarityTimeLine : public TimeLineViewStrip
00047 {
00048 public:
00049 typedef Core::Table::SimilarityTableSet SimilarityTableSet;
00050 typedef SimilarityTableSet::SimTableType SimTableType;
00051 typedef std::vector<float> FloatVector;
00052 typedef std::vector<FloatVector*> Averages;
00053
00054
00055 SimilarityTimeLine(int x, int y, int w, int h, int nViews) :
00056 TimeLineViewStrip(x,y,w,h,nViews)
00057 {
00058 Init(w,h);
00059 }
00060
00061 SimilarityTimeLine(OglGui::Window* parent, int w, int h, int nViews) :
00062 TimeLineViewStrip(parent,w,h,nViews)
00063 {
00064 Init(w,h);
00065 }
00066
00067 SimilarityTimeLine(OglGui::Window* parent, int x, int y, int w, int h,
00068 int nViews) :
00069 TimeLineViewStrip(parent,x,y,w,h,nViews)
00070 {
00071 Init(w,h);
00072 }
00073
00074 void
00075 SetListener(SimilarityTimeLineListener* listener, void* listenerData = 0)
00076 {
00077 mListener = listener;
00078 mListenerData = listenerData;
00079 }
00080
00081 virtual void PublishCurrentChanged()
00082 {
00083 if (!mListener)
00084 return;
00085 mListener->CurrentChanged(this, mCurrent, mListenerData);
00086 }
00087
00088 void SetSimilarityTableSet(SimilarityTableSet* simSet)
00089 {
00090 if (mSimSet)
00091 mVisibleConcepts.clear();
00092 if ((mSimSet = simSet) == 0)
00093 return;
00094 for (int i=0; i<mSimSet->NrTables(); i++)
00095 mVisibleConcepts.push_back(true);
00096 }
00097
00098 void SetAverages(Averages* averages, FloatVector* maxima, FloatVector* means)
00099 {
00100 mAverages = averages;
00101 mMeans = means;
00102 mMaxima = maxima;
00103 }
00104
00105 void AddSimColor(ULONG col)
00106 {
00107 mSimColors.push_back(col);
00108 }
00109
00110 void SetSimColor(int id, ULONG col)
00111 {
00112 if (id > ((int)mSimColors.size())-1)
00113 return;
00114 mSimColors[id] = col;
00115 }
00116
00117 ULONG GetSimColor(int id)
00118 {
00119 if (id > ((int)mSimColors.size())-1)
00120 return oglBLACK;
00121 return mSimColors[id];
00122 }
00123
00124 int NrColors()
00125 {
00126 return mSimColors.size();
00127 }
00128
00129 void SetShowSim(int id, bool show)
00130 {
00131 if (id<0 || id > ((int)mVisibleConcepts.size())-1)
00132 return;
00133 mVisibleConcepts[id] = show;
00134 }
00135
00136 bool GetShowSim(int id)
00137 {
00138 if (id<0 || id > ((int)mVisibleConcepts.size())-1)
00139 return false;
00140 return mVisibleConcepts[id];
00141 }
00142
00143 void NeedleOverConcepts()
00144 {
00145 OglGui::ZoomShiftRuler::DrawNeedle();
00146 }
00147
00148 void PercMaxVal(float perc) { mPercMax = perc; }
00149 void PercMaxMeanVal(float perc) { mPercMaxMean = perc; }
00150 void ShowClassify(bool mode=true) { mShowClassify = mode; }
00151
00152 bool PassTest(float sim, float maxim, float mean)
00153 {
00154 return (sim > mPercMax*maxim || (sim>mean+(maxim-mean)*mPercMaxMean));
00155 }
00156
00157 void DrawHelpLines(int lineMax, int hRange)
00158 {
00159 OGC myOGC;
00160 OGCSave( &myOGC );
00161
00162 ULONG col = oglGREY;
00163 SetSolidLineColor(col);
00164 SetStipple((short)oglDot);
00165 for (int i=0; i<4; i++)
00166 {
00167 int y = lineMax-i*hRange/4;
00168 DrawLine(24,y,W(),y);
00169 oglSys.PosColPrintf(mOglWnd,0,y-6,col,"%.2f",1.0f-i*0.25f);
00170 }
00171 SetStipple((short)oglSolid);
00172 if (mHelpLineActive)
00173 {
00174 if (mHelpLineY <= lineMax && mHelpLineY >= mAxisY)
00175 {
00176 DrawLine(20,mHelpLineY,W()-20,mHelpLineY);
00177 float val = (mHelpLineY-mAxisY)/(float)hRange;
00178 int offY = (mHelpLineY - mAxisY > 16) ? -16 : 4;
00179 oglSys.ShadowPrintf(mOglWnd,mHelpLineX+14,mHelpLineY+offY,
00180 oglDARKGREY,oglWHITE,"%0.2f",val);
00181 }
00182 }
00183 SetStipple((short)oglSolid);
00184 }
00185
00186 void DrawAverages(int idx, int startFrame, int endFrame, int inc,
00187 bool test, bool norm, int opaq, int hRange, int lineW)
00188 {
00189 if (!mAverages || (*mMaxima)[idx] < 0.20 || !mShowClassify)
00190 return;
00191
00192 FloatVector* avgVector = (*mAverages)[idx];
00193 float maxim = (*mMaxima)[idx];
00194 float means = (*mMeans)[idx];
00195 float lineY = H()-(idx+1)*5;
00196
00197 if (startFrame > (*avgVector).size()-1)
00198 startFrame = (*avgVector).size()-1;
00199
00200 if (endFrame > (*avgVector).size()-1)
00201 endFrame = (*avgVector).size()-1;
00202
00203 int bInfo[3];
00204 oglSys.StartBlend(bInfo);
00205
00206 ULONG col = mSimColors[idx%mSimColors.size()];
00207 UCHAR r,g,b;
00208 COLOR2RGB(col,r,g,b);
00209 UCHAR aR = r, aG = g, aB = b, aA = 0;
00210
00211 glLineWidth(lineW);
00212 glBegin(GL_LINE_STRIP);
00213 for (float i=startFrame; i<endFrame; i+=inc)
00214 {
00215 double sim = (*avgVector)[(int)(i+mFrameError)];
00216 aA = test ? 0 : opaq;
00217 if (test && PassTest(sim,maxim,means))
00218 {
00219 if (norm)
00220 {
00221 float normSim = sim/maxim;
00222 aR = normSim * r;
00223 aG = normSim * g;
00224 aB = normSim * b;
00225 }
00226 aA = opaq;
00227 }
00228 glColor4ub(aR,aG,aB,aA);
00229 float x = (float) Unit2Pixel(i*40);
00230 if (hRange)
00231 lineY = (mAxisY + 2 + sim * hRange);
00232 glVertex2f(x,lineY);
00233 }
00234 glEnd();
00235 oglSys.EndBlend(bInfo);
00236 glLineWidth(1);
00237 }
00238
00239 virtual void DisplayFunc()
00240 {
00241 OGC myOGC;
00242 OGCSave( &myOGC );
00243
00244 TimeLineViewStrip::DisplayFunc();
00245
00246 if (!mSimSet)
00247 return;
00248
00249 int startFrame = FirstVisibleFrame();
00250 int endFrame = LastVisibleFrame();
00251
00252 if (endFrame > mSimSet->TableSize()-mFrameError-1)
00253 endFrame = mSimSet->TableSize()-mFrameError-1;
00254
00255 int range = endFrame - startFrame;
00256 int lineMax = H() - 4 - ((mAverages&&mShowClassify)?65:0);
00257 int hRange = lineMax - mAxisY;
00258 int inc = 1;
00259
00260 if (range >= cMaxVisPerConcept)
00261 inc = (int) ((range / (double)cMaxVisPerConcept)+0.5);
00262
00263
00264 while(startFrame%inc)
00265 startFrame--;
00266
00267 float bigW = 5;
00268 for (int j=0; j<mSimSet->NrTables(); j++)
00269 {
00270 DrawAverages(j,startFrame,endFrame,inc,true,true,200,0,bigW);
00271 DrawAverages(j,startFrame,endFrame,inc,true,false,255,0,1);
00272
00273 if (!mVisibleConcepts[j])
00274 continue;
00275
00276 DrawAverages(j,startFrame,endFrame,inc,false,false,255,hRange,1);
00277 DrawAverages(j,startFrame,endFrame,inc,true,false,128,hRange,bigW);
00278
00279 ULONG col = mSimColors[j%mSimColors.size()];
00280 UCHAR r,g,b;
00281 COLOR2RGB(col,r,g,b);
00282 glColor3ub(r,g,b);
00283 SimTableType* simTable = mSimSet->GetSimTable(j);
00284 glPointSize(range < 300 ? (range<100?5:3) : 2);
00285 glBegin(GL_POINTS);
00286 for (float i=startFrame; i<=endFrame; i+=inc)
00287 {
00288 double sim = simTable->Get1(i+mFrameError);
00289 float x = (float) Unit2Pixel(i*40);
00290 float y = (float) (mAxisY + 2 + sim * hRange);
00291 glVertex2f(x,y);
00292 }
00293 glEnd();
00294
00295 }
00296 glPointSize(1);
00297 glLineWidth(1);
00298
00299 DrawHelpLines(lineMax,hRange);
00300
00301 NeedleOverConcepts();
00302
00303 OGCRestore(&myOGC);
00304 }
00305
00306 virtual void MouseFunc(int msg, int btn, int state, int x, int y)
00307 {
00308 TimeLineViewStrip::MouseFunc(msg,btn,state,x,y);
00309 mHelpLineActive = (state==oglLeftButton);
00310 mHelpLineX = x;
00311 mHelpLineY = y;
00312 }
00313
00314 private:
00315
00316 void Init(int w, int h)
00317 {
00318 mListener = 0;
00319 mSimSet = 0;
00320 SetStart(0);
00321 SetSpan(60000);
00322 mCurrentConcept = 0;
00323 mShowClassify = true;
00324 ShowNeedle(false);
00325 SetNeedleColor(oglBLACK);
00326 SetNeedleUpDownHeight(1000,4);
00327 mNrColors = 0;
00328 while( sColorNamesSTL[mNrColors][0] != 0 )
00329 mSimColors.push_back(OglColorStr(sColorNamesSTL[mNrColors++]));
00330 mAverages = 0;
00331 mPercMax = 0.66f;
00332 mPercMaxMean = 0.25f;
00333 mHelpLineActive = false;
00334 }
00335
00336 static const int cMaxVisPerConcept = 10000;
00337
00338 SimilarityTimeLineListener* mListener;
00339 void* mListenerData;
00340
00341 SimilarityTableSet* mSimSet;
00342 std::vector<ULONG> mSimColors;
00343 std::vector<bool> mVisibleConcepts;
00344
00345 Averages* mAverages;
00346 FloatVector* mMaxima;
00347 FloatVector* mMeans;
00348 float mPercMax;
00349 float mPercMaxMean;
00350 bool mShowClassify;
00351 bool mHelpLineActive;
00352 int mHelpLineY;
00353 int mHelpLineX;
00354
00355 int mCurrentConcept;
00356 int mNrColors;
00357 };
00358 }
00359 }
00360 #endif