00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdlib.h>
00012 #include <math.h>
00013
00014 #ifndef INCLUDED_AIDAPLOTTER_H
00015 #include "AIDA_Plotter/AIDAPlotter.h"
00016 #endif
00017
00018 #include "Interfaces/IScatter2D.h"
00019 #include "Interfaces/IVector.h"
00020 #include "Interfaces/IAnnotation.h"
00021
00022 #include "Qplotter/viewer/viewerFactory.h"
00023 #include <algorithm>
00024
00025 using Anaphe::AIDAPlotter;
00026
00027 AIDAPlotter::AIDAPlotter(int nX, int nY) : myViewer(0), myPage(0), myZone(0), whichZone(0)
00028 {
00029 init(nX, nY);
00030 }
00031
00032 AIDAPlotter::~AIDAPlotter()
00033 {
00034 delete myViewer;
00035 }
00036
00037 void AIDAPlotter::init(int nX, int nY)
00038 {
00039 if (myViewer == 0) myViewer = ViewerFactory::Viewer();
00040 nZonesX = nX;
00041 nZonesY = nY;
00042 myPage = myViewer->createPage(nZonesX, nZonesY);
00043 whichZone = -1;
00044
00045 }
00046
00047 void AIDAPlotter::reset()
00048 {
00049 zoneOption("","");
00050 resetMinMax();
00051 dataOption("","");
00052 dataStyle();
00053 textStyle();
00054 xAxisOption("","");
00055 yAxisOption("","");
00056 }
00057
00058 void AIDAPlotter::refresh()
00059 {
00060 if (myViewer == 0) return;
00061
00062 myViewer->draw();
00063 myViewer->draw();
00064 }
00065
00066
00067 void AIDAPlotter::pageTitle(const char *title) {
00068 IText *pText = myPage->setTitle(title);
00069
00070 applyTextProperties(pText->getStyle());
00071 myViewer->draw();
00072 }
00073
00074 void AIDAPlotter::zoneTitle(const char *title, int selZone) {
00075 selZone -= 1;
00076 if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00077 IText *zText = myPage->selectZone(selZone)->setTitle(title);
00078
00079 applyTextProperties(zText->getStyle());
00080 myViewer->draw();
00081 }
00082
00083 void AIDAPlotter::applyTextProperties(ITextStyle *itx) {
00084 typedef std::multimap<std::string,std::string>::iterator MI;
00085 MI mItr;
00086 for (mItr = textStyles.begin(); mItr != textStyles.end(); mItr++ ) {
00087 itx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00088 }
00089 }
00090
00091 void AIDAPlotter::pageText(double xC, double yC, const char *text) {
00092 IText *pText = myPage->addText(xC,yC,text);
00093
00094 applyTextProperties(pText->getStyle());
00095 myViewer->draw();
00096 }
00097
00098 void AIDAPlotter::zoneText(double xC, double yC, const char *text, int selZone) {
00099 selZone -= 1;
00100 if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00101 IText *zText = myPage->selectZone(selZone)->addText(xC,yC,text);
00102
00103 applyTextProperties(zText->getStyle());
00104 myViewer->draw();
00105 }
00106
00107 void AIDAPlotter::psPrint(const char *file)
00108 {
00109 std::string fileName = "lizard.ps";
00110 if (file != 0) fileName = file;
00111
00112 myViewer->makePS(const_cast<char *>(fileName.c_str()));
00113
00114
00115 if (file == 0) system("/usr/local/bin/xprint lizard.ps");
00116 }
00117
00118 void AIDAPlotter::makePicture(const char *file)
00119 {
00120 myViewer->makePicture(file);
00121 }
00122
00123 void AIDAPlotter::resetZones(int nx, int ny) {
00124 myViewer->clear();
00125 init(nx, ny);
00126 }
00127
00128 void AIDAPlotter::createRegion(double x, double y, double w, double h)
00129 {
00130 myPage->createIrregularZone(x,y,w,h);
00131 }
00132
00133 void AIDAPlotter::zone(int nx, int ny, int iSel, const char *opt)
00134 {
00135 resetZones(nx,ny);
00136 iSel -= 1;
00137 if (iSel < 0)
00138 whichZone = -1;
00139 else
00140 whichZone = ( iSel % (nZonesX*nZonesY) ) - 1;
00141
00142 xMinMax.clear();
00143 yMinMax.clear();
00144 }
00145
00146 void AIDAPlotter::setMinMaxX(double xMin, double xMax, int selZone)
00147 {
00148 selZone -= 1;
00149 if (selZone < 0 || selZone >= nZonesX*nZonesY) {
00150 std::cerr << "illegal zone for setMinMaxX : " << selZone << std::endl;
00151 return;
00152 }
00153
00154
00155
00156
00157
00158 std::pair <double, double> minMax(xMin, xMax);
00159 xMinMax[selZone] = minMax;
00160 }
00161
00162 void AIDAPlotter::setMinMaxY(double yMin, double yMax, int selZone)
00163 {
00164 selZone -= 1;
00165 if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00166
00167
00168
00169
00170
00171 std::pair <double, double> minMax(yMin, yMax);
00172 yMinMax[selZone] = minMax;
00173 }
00174
00175 void AIDAPlotter::resetMinMax()
00176 {
00177 xMinMax.clear();
00178 yMinMax.clear();
00179 }
00180
00181 void AIDAPlotter::textStyle(const char *opt, const char *val)
00182 {
00183 if (opt == 0 && val == 0) {
00184 textStyles.clear();
00185 return;
00186 }
00187
00188 if (val == 0 || (strlen(val) == 0)) {
00189 textStyles.erase(opt);
00190 return;
00191 }
00192
00193 std::pair<const std::string, std::string> option(opt, val);
00194 textStyles.erase(opt);
00195 textStyles.insert( option );
00196 }
00197
00198 void AIDAPlotter::dataStyle(const char *opt, const char *val)
00199 {
00200 if (opt == 0 && val == 0) {
00201 dataStyles.clear();
00202 return;
00203 }
00204
00205 if (val == 0 || (strlen(val) == 0)) {
00206 dataStyles.erase(opt);
00207 return;
00208 }
00209
00210 std::pair<const std::string, std::string> option(opt, val);
00211 dataStyles.erase(opt);
00212 dataStyles.insert( option );
00213 }
00214
00215 void AIDAPlotter::dataOption(const char *opt, const char *val)
00216 {
00217 handleOption(dataProperties, opt, val);
00218 }
00219
00220 void AIDAPlotter::zoneOption(const char *opt, const char *val)
00221 {
00222 handleOption(zoneProperties, opt, val);
00223 }
00224
00225 void AIDAPlotter::xAxisOption(const char *opt, const char *val)
00226 {
00227 handleOption(xAxisProperties, opt, val);
00228 }
00229
00230 void AIDAPlotter::yAxisOption(const char *opt, const char *val)
00231 {
00232 handleOption(yAxisProperties, opt, val);
00233 }
00234
00235 void AIDAPlotter::handleOption(Property_t &pList, const char *opt, const char *val)
00236 {
00237
00238 if ( (opt == 0 && val == 0) ||
00239 (std::string(opt) == "" && ( val != 0 && std::string(val) == "" ) ) ) {
00240 pList.clear();
00241 return;
00242 }
00243
00244
00245 std::string name(opt);
00246 #ifdef __sun
00247 std::string::iterator itr = name.begin();
00248 while (itr != name.end()) {
00249 *itr = tolower(*itr);
00250 itr++;
00251 }
00252 #else
00253 std::transform(name.begin(),name.end(),name.begin(), tolower);
00254 #endif
00255
00256 if (val == 0 || std::string(val) == "") {
00257 pList.erase(name);
00258 return;
00259 }
00260
00261 std::pair<const std::string, std::string> option(name, val);
00262
00263 if ((name != "option") && (pList.find(name )!= pList.end()))
00264 pList.erase(name);
00265 pList.insert( option );
00266
00267 }
00268
00269
00270 void AIDAPlotter::listOptions(std::ostream& os)
00271 {
00272 os << "\nOptions for Zones" << std::endl;
00273 myPage->selectZone(whichZone)->listOptions(os);
00274
00275 os << "\nOptions for Datasets (curves)" << std::endl;
00276 IDataset *ds = myPage->selectZone(whichZone)->getDataset(0);
00277 if (ds != 0) {
00278 ds->listOptions(os);
00279 } else
00280 os << "\nNo Dataset available" << std::endl;
00281
00282 os << "\nDraw style options" << std::endl;
00283 myPage->selectZone(whichZone)->getDrawStyle()->listOptions(os);
00284
00285 os << "\nText style options" << std::endl;
00286 myPage->selectZone(whichZone)->getTextStyle()->listOptions(os);
00287
00288 }
00289
00290 void AIDAPlotter::setAxisProperty(IZone *z, Anaphe::IVector *v1, const std::string ax, const std::string prop, Property_t &pList)
00291 {
00292
00293
00294 if ( (pList.find(prop) != pList.end()) &&
00295 (pList.find(prop)->second != "") ) {
00296 z->getAxis( ax )->setProperty(prop, pList.find(prop)->second);
00297
00298 } else {
00299
00300 std::string what = ax + "axis" + prop;
00301 if (v1->annotation() != 0) {
00302 for (int index=0; index < v1->annotation()->size(); index++) {
00303
00304 std::string lowerKey(v1->annotation()->key(index));
00305 std::transform(lowerKey.begin(),lowerKey.end(),lowerKey.begin(),tolower);
00306 if ( (what == lowerKey) && (v1->annotation()->value(index).size() != 0 )) {
00307 z->getAxis( ax )->setProperty(prop, v1->annotation()->value(index));
00308 }
00309 }
00310 }
00311 }
00312 }
00313
00314 void AIDAPlotter::plot(Anaphe::IScatter2D *scat) {
00315 if (scat == 0) return;
00316
00317
00318 if (whichZone == 0) {
00319 resetZones(nZonesX, nZonesY);
00320 whichZone = 0;
00321 }
00322
00323
00324 IZone *z = myPage->selectZone(whichZone);
00325 z->addScatter(scat);
00326
00327 myViewer->draw();
00328
00329 whichZone++;
00330
00331 if ( whichZone > (nZonesX*nZonesY)-1 ) {
00332 whichZone = 0;
00333 }
00334 }
00335
00336 void AIDAPlotter::plot(Anaphe::IVector *v1, Anaphe::IVector *v2)
00337 {
00338 if (v1 == 0) return;
00339
00340 if (v1->dimension() == 0) return;
00341 if (v1->nPoints () == 0) return;
00342
00343 whichZone++;
00344
00345 if ( whichZone > (nZonesX*nZonesY)-1 ) {
00346
00347 whichZone = 0;
00348 }
00349
00350
00351 if (whichZone == 0) {
00352 resetZones(nZonesX, nZonesY);
00353 whichZone = 0;
00354 }
00355
00356
00357
00358 typedef std::multimap<std::string,std::string>::iterator MI;
00359
00360 MI mItr;
00361 IZone *z = myPage->selectZone(whichZone);
00362
00363
00364 IDataset *ds = z->addDataset(*v1);
00365 for (mItr = dataProperties.begin(); mItr != dataProperties.end(); mItr++ ) {
00366 ds->setProperty(mItr->first.c_str(), mItr->second.c_str());
00367 }
00368
00369 IDrawStyle *idx = ds->getStyle();
00370 for (mItr = dataStyles.begin(); mItr != dataStyles.end(); mItr++ ) {
00371 idx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00372 }
00373
00374
00375 ITextStyle *itx = z->getTextStyle();
00376 for (mItr = textStyles.begin(); mItr != textStyles.end(); mItr++ ) {
00377 itx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00378 }
00379
00380 for (mItr = zoneProperties.begin(); mItr != zoneProperties.end(); mItr++ ) {
00381 z->setProperty(mItr->first.c_str(), mItr->second.c_str());
00382 }
00383
00384 setAxisProperty(z, v1, "x", "title", xAxisProperties);
00385 setAxisProperty(z, v1, "y", "title", yAxisProperties);
00386
00387 setAxisProperty(z, v1, "x", "label", xAxisProperties);
00388 setAxisProperty(z, v1, "y", "label", yAxisProperties);
00389
00390
00391 if (xMinMax.find(whichZone) != xMinMax.end())
00392 z->xMinMax (xMinMax[whichZone].first, xMinMax[whichZone].second);
00393
00394 if (yMinMax.find(whichZone) != yMinMax.end())
00395 z->yMinMax (yMinMax[whichZone].first, yMinMax[whichZone].second);
00396
00397 myViewer->draw();
00398
00399 if (v2 != 0) {
00400
00401
00402 MI lineMode = dataProperties.find("Representation");
00403 std::string lm;
00404 if (lineMode != dataProperties.end()) {
00405 lm = lineMode->second;
00406 } else {
00407 lm = "histo";
00408 }
00409
00410 MI lineColour = dataStyles.find("lineColor");
00411 std::string lc;
00412 if (lineColour != dataStyles.end()) {
00413 lc = lineColour->second;
00414 } else {
00415 lc = "black";
00416 }
00417
00418
00419 dataOption("Representation",0);
00420 dataOption("Representation","Line");
00421 dataStyle ("lineColor", "red");
00422
00423
00424 overlay(v2);
00425
00426
00427 dataOption("Representation",0);
00428 dataOption("Representation", lm.c_str());
00429 dataStyle ("lineColor" , lc.c_str());
00430
00431 }
00432
00433 return;
00434 }
00435
00436 void AIDAPlotter::overlay(Anaphe::IVector *v2, int selZone)
00437 {
00438 if (selZone == -1) {
00439 selZone = whichZone;
00440 } else {
00441 selZone -= 1;
00442 if (selZone < 0 || selZone >= nZonesX*nZonesY) return;
00443 }
00444
00445 if (v2 == 0) return;
00446
00447 if (v2->dimension() == 0) return;
00448 if (v2->nPoints () == 0) return;
00449
00450 typedef std::multimap<std::string,std::string>::iterator MI;
00451
00452 IZone *z = myPage->selectZone(selZone);
00453
00454 IDataset *ds = z->addDataset(*v2);
00455 for (MI mItr = dataProperties.begin(); mItr != dataProperties.end(); mItr++ ) {
00456 ds->setProperty(mItr->first.c_str(), mItr->second.c_str());
00457 }
00458 IDrawStyle *idx = ds->getStyle();
00459 for (MI mItr = dataStyles.begin(); mItr != dataStyles.end(); mItr++ ) {
00460 idx->setProperty(mItr->first.c_str(), mItr->second.c_str());
00461 }
00462
00463 myViewer->draw();
00464
00465 return;
00466 }
00467
00468 void AIDAPlotter::interact()
00469 {
00470 myViewer->activateOutline();
00471 return;
00472 }
00473
00474
00475
00476 Anaphe::IPlotter * createIPlotter() { return new AIDAPlotter(); }
00477
00478
00479