Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

LabeledGraph.h

Go to the documentation of this file.
00001 #include "OglGui/Graph.h"
00002 
00003 #include <string>
00004 #include <map>
00005 #include <vector>
00006 
00007 #include "Tag.h"
00008 
00009 using namespace OglGui;
00010 using namespace std;
00011 
00012 class LabeledGraph : public Graph {
00013 public:
00014         LabeledGraph(Window* parent, int w, int h, int drawShape=0, strconst txt="") : Graph(parent, w, h, drawShape, txt) {}
00015 
00016         void addNodes(map<string, vector<string> > labels) {
00017                 map<string, vector<string> >::iterator iter;
00018                 for(iter = labels.begin(); iter != labels.end(); iter++) {
00019                         string label = iter->first;
00020                         if(nodes.count(label) == 0) addNode(label);
00021                         for(uint i = 0; i < iter->second.size(); i++) {
00022                                 string related = iter->second[i];
00023                                 if(nodes.count(related) == 0) addNode(related);
00024                                 this->ConnectNode(nodes[label], nodes[related]);
00025                         }
00026                 }
00027         }
00028 
00029     virtual void DisplayFunc()
00030     {
00031         if(!layoutDone) layoutDone = doLayout();
00032         Graph::DisplayFunc();
00033     }
00034 
00035     virtual void OnLayoutChange()
00036     {
00037                 layoutDone = false;
00038         Graph::OnLayoutChange();
00039     }
00040 
00041 private:
00042         void addNode(string label) {
00043                 int width, height;
00044                 this->GetDimensions(width, height);
00045                 int x  = ABSRND(width-20);
00046                 int y  = ABSRND(height-20);
00047 
00048                 nodes[label] = new Graph(this,x,y,75,20,1);
00049                 nodes[label]->ShapeBg(ARGB2COLOR(196,255,0,0));
00050                 nodes[label]->SetBorderType(0);
00051                 nodes[label]->SetText(label);
00052                 nodes[label]->ActOnModifier(0);
00053                 nodes[label]->SetAllowSizeDirections(AllDir, false);
00054 
00055                 this->AddNode(nodes[label]);
00056         }
00057 
00058         bool doLayout() {
00059                 return doForceDirectedLayout();
00060                 return doRadialLayout();
00061         }
00062 
00063         bool doRadialLayout() {
00064                 int x, y, w, h;
00065                 mNodes[0].nodeVector[0]->GetDimensions(x, y, w, h);
00066                 uint cx = (W()-w)/2, cy = (H()-h)/2;
00067                 mNodes[0].nodeVector[0]->SetDimensions(cx, cy, w, h);
00068                 uint count = mNodes[0].nodeVector.size()-1;
00069                 float count_2_pi = count/(M_PI*2);
00070                 float rx = 1.0-0.5*w/W(), ry = 1.0-0.5*h/H();
00071                 for(float i=1; i <= count; i++) {
00072                         mNodes[0].nodeVector[i]->GetDimensions(x, y, w, h);
00073                         x = cx * (1 + rx*sin(i/count_2_pi));
00074                         y = cy * (1 + ry*cos(i/count_2_pi));
00075                         mNodes[0].nodeVector[i]->SetDimensions(x, y, w, h);
00076                 }
00077                 return true;
00078         }
00079 
00080         bool doForceDirectedLayout() {
00081                 int x, y, w, h;
00082                 mNodes[0].nodeVector[0]->GetDimensions(x, y, w, h);
00083                 uint cx = (W()-w)/2, cy = (H()-h)/2;
00084                 mNodes[0].nodeVector[0]->SetDimensions(cx, cy, w, h);
00085 
00086                 float energy = 0;
00087                 float alpha = 0.01;
00088                 for(uint i = 0; i < mNodes.size(); i++) {
00089                         mNodes[i].nodeVector[0]->GetDimensions(x, y, w, h);
00090 
00091                         int nX, nY, nW, nH;
00092                         // Move away nodes that are too close
00093                         for(uint j = 0; j < mNodes.size(); j++) {
00094                                 if(i==j) continue;
00095                                 mNodes[j].nodeVector[0]->GetDimensions(nX, nY, nW, nH);
00096                                 int distX = nX-x, distY = nY-y;
00097                                 /*if(ABSRND(20) == 1) {
00098                                         nX = (distX > 0) ? nX + 1 : nX - 1;
00099                                         nY = (distY > 0) ? nY + 1 : nY - 1;
00100                                 }*/
00101                                 int pX = nX, pY = nY;
00102                                 if((abs(distX) < (nW)) && (abs(distY) < (nH))) {
00103                                         nX += (distX > 0) ? nW: -nW;
00104                                         nY += (distY > 0) ? nH : -nH;
00105                                 }
00106                                 nX = cap(nX, 0, W()-nW);
00107                                 nY = cap(nY, 0, H()-nH);
00108                                 float delta = sqrt(pow(nX-pX, 2.0) + pow(nY-pY, 2.0));
00109                                 if(delta > 0) {
00110                                         energy += delta;
00111                                         mNodes[j].nodeVector[0]->SetDimensions(nX, nY, nW, nH);
00112                                 }
00113                         }
00114                         for(uint j = 1; j < mNodes[i].nodeVector.size(); j++){
00115                                 mNodes[i].nodeVector[j]->GetDimensions(nX, nY, nW, nH);
00116                                 //if(sqrt(pow(nX-x, 2) + pow(nY-y, 2)) < 2*nW) continue;
00117                                 mNodes[i].nodeVector[0]->SetDimensions(nX*alpha+x*(1-alpha), nY*alpha+y*(1-alpha), w, h);
00118                                 mNodes[i].nodeVector[j]->SetDimensions(x*alpha+nX*(1-alpha), y*alpha+nY*(1-alpha), nW, nH);
00119                         }
00120                 }
00121                 return(energy == 0);
00122         }
00123 
00124     float cap(float v, float min, float max) {
00125         if(v < min) return min;
00126         if(v > max) return max;
00127         return v;
00128     }
00129 
00130     map<string, Graph* > nodes;
00131 
00132     bool layoutDone;
00133 
00134     ILOG_VAR_DEC;
00135 };
00136 
00137 ILOG_VAR_INIT(LabeledGraph, Impala.Application.TagsLife);

Generated on Fri Mar 19 09:30:39 2010 for ImpalaSrc by  doxygen 1.5.1