00001
00012
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017 #include "PlotterBaseXML.h"
00018
00019 #include "AxisModelXML.h"
00020 #include "DataRepXML.h"
00021 #include "FontXML.h"
00022 #include "PointRepXML.h"
00023 #include "TransformXML.h"
00024 #include "TupleCutXML.h"
00025 #include "XmlController.h"
00026 #include "XmlDocument.h"
00027 #include "XmlElement.h"
00028
00029 #include "axes/AxisModelLog.h"
00030 #include "controllers/DisplayController.h"
00031 #include "controllers/FunctionController.h"
00032 #include "datareps/DataRepException.h"
00033 #include "datareps/FunctionRep.h"
00034 #include "datasrcs/TupleCut.h"
00035
00036 #include "plotters/Cut1DPlotter.h"
00037 #include "plotters/Cut2DPlotter.h"
00038 #include "plotters/PlotterFactory.h"
00039 #include "plotters/TextPlotter.h"
00040 #include "plotters/XyPlotter.h"
00041
00042 #include "projectors/NTupleProjector.h"
00043
00044 #include "pattern/string_convert.h"
00045
00046 #include <typeinfo>
00047
00048 #include <cassert>
00049
00050 using std::list;
00051 using std::string;
00052
00053 using namespace hippodraw;
00054
00055 PlotterBaseXML::PlotterBaseXML ( XmlController * controller )
00056 : BaseXML ( "PlotterBase", controller ),
00057 m_axis ( "axis" ),
00058 m_title ( "title" ),
00059 m_x_label ( "xlabel" ),
00060 m_y_label ( "ylabel" ),
00061 m_z_label ( "zlabel" ),
00062 m_pindex ( "pindex" )
00063 {
00064 m_axismodel = new AxisModelXML ( controller );
00065 m_datarep = new DataRepXML ( controller );
00066 m_font = new FontXML ( controller );
00067 m_pointrep = new PointRepXML ( controller );
00068 m_transform_xml = new TransformXML ( controller );
00069 m_tuple_cut_xml = new TupleCutXML ( controller );
00070 }
00071
00072 PlotterBaseXML::
00073 PlotterBaseXML ( const std::string & name,
00074 XmlController * controller )
00075 : BaseXML ( name, controller ),
00076 m_axis ( "axis" )
00077 {
00078 m_axismodel = new AxisModelXML ( controller );
00079 m_datarep = new DataRepXML ( controller );
00080 m_font = new FontXML ( controller );
00081 }
00082
00083 PlotterBaseXML::
00084 ~PlotterBaseXML ()
00085 {
00086 delete m_axismodel;
00087 delete m_datarep;
00088 delete m_font;
00089 delete m_pointrep;
00090 delete m_transform_xml;
00091 delete m_tuple_cut_xml;
00092 }
00093
00094 bool PlotterBaseXML::areDataSourcesSaved ( const PlotterBase & plotter )
00095 {
00096 DisplayController * controller = DisplayController::instance ();
00097
00098 return controller->areDataSourcesSaved ( & plotter );
00099 }
00100
00101 void PlotterBaseXML::createChildren ( XmlElement &tag,
00102 const PlotterBase & plotter )
00103 {
00104 createAxisModel ( tag, plotter, Axes::X );
00105 createAxisModel ( tag, plotter, Axes::Y );
00106 if ( plotter.hasAxis ( Axes::Z ) ) createAxisModel ( tag, plotter, Axes::Z );
00107
00108 try {
00109 const XyPlotter & xyplotter
00110 = dynamic_cast < const XyPlotter & > ( plotter );
00111 createFontElements ( tag, xyplotter );
00112 }
00113 catch ( ... ) {
00114
00115 }
00116
00117 TransformBase * transform = plotter.getTransform ();
00118 if ( transform != 0 ) {
00119 XmlElement * element = m_transform_xml->createElement ( *transform );
00120 tag.appendChild ( *element );
00121 delete element;
00122 }
00123
00124 int number = plotter.getNumDataReps ();
00125 for ( int i = 0; i < number; i++ ) {
00126 DataRep * rep = plotter.getDataRep ( i );
00127
00128 XmlElement * element = m_datarep->createElement ( *rep );
00129
00130 tag.appendChild ( *element );
00131 delete element;
00132 }
00133
00134 if ( typeid ( plotter ) == typeid ( Cut1DPlotter ) ||
00135 typeid ( plotter ) == typeid ( Cut2DPlotter ) ) {
00136 try {
00137 const CutPlotter & cut_plotter
00138 = dynamic_cast < const CutPlotter & > ( plotter );
00139
00140 createCutChildren ( tag, cut_plotter );
00141 }
00142 catch ( ... ) {
00143
00144 }
00145 }
00146
00147 if ( plotter.name() == "TextPlotter" ) {
00148 try {
00149 const TextPlotter & text_plotter
00150 = dynamic_cast < const TextPlotter & > ( plotter );
00151 createTextChildren ( tag, text_plotter );
00152 }
00153 catch ( ... ) {
00154
00155 }
00156 }
00157 return;
00158 }
00159
00160 void PlotterBaseXML::createCutChildren ( XmlElement & tag,
00161 const CutPlotter & plotter )
00162 {
00163 const vector < TupleCut > & cuts = plotter.getCuts ();
00164 for ( unsigned int i = 0; i < cuts.size (); i++ ) {
00165 XmlElement * element = m_tuple_cut_xml -> createElement ( i, cuts[i] );
00166 tag.appendChild ( *element );
00167 delete element;
00168 }
00169
00170 const list < DataRep * > & targets = plotter.getCutTargets ();
00171 #ifdef ITERATOR_MEMBER_DEFECT
00172 std::
00173 #endif
00174 list < DataRep * >::const_iterator first = targets.begin();
00175
00176 for ( ; first != targets.end(); ++first ) {
00177 DataRep * rep = *first;
00178 const void * addr = reinterpret_cast < const void * > ( rep );
00179 int id = m_controller -> getId ( addr );
00180 XmlElement * element
00181 = XmlController::m_xml_doc->createElement ( "CutTarget" );
00182 element->setAttribute ( "id", id );
00183 tag.appendChild ( *element );
00184 delete element;
00185 }
00186 }
00187
00188 void
00189 PlotterBaseXML::
00190 createTextChildren ( XmlElement & tag,
00191 const TextPlotter & plotter )
00192 {
00193 const DataRep * rep = plotter.getParentDataRep ();
00194
00195 const void * addr = reinterpret_cast < const void * > ( rep );
00196 int id = m_controller -> getId ( addr );
00197 XmlElement * element
00198 = XmlController::m_xml_doc->createElement ( "TextTarget" );
00199 element->setAttribute ( "id", id );
00200
00201 tag.appendChild ( *element );
00202 delete element;
00203 }
00204
00205 void
00206 PlotterBaseXML::
00207 createFontElements ( XmlElement & tag,
00208 const XyPlotter & plotter )
00209 {
00210 const FontBase * font = plotter.titleFont ();
00211 if ( font != 0 ) {
00212 XmlElement * element = m_font -> createElement ();
00213 const string t ( "t" );
00214 element -> setAttribute ( m_axis, t );
00215 m_font -> setAttributes ( *element, *font );
00216 tag.appendChild ( *element );
00217 delete element;
00218 }
00219
00220 for ( unsigned int i = 0; i < 3; i++ ) {
00221 Axes::Type type = Axes::convert ( i );
00222 createFontElement ( tag, plotter, type );
00223 }
00224 }
00225
00226 void
00227 PlotterBaseXML::
00228 createFontElement ( XmlElement & tag,
00229 const XyPlotter & plotter,
00230 hippodraw::Axes::Type axis )
00231 {
00232 const FontBase * font = plotter.labelFont ( axis );
00233 if ( font != 0 ) {
00234 XmlElement * element = m_font -> createElement ();
00235 string s;
00236 switch ( axis )
00237 {
00238 case Axes::X :
00239 s = "x";
00240 break;
00241 case Axes::Y :
00242 s = "y";
00243 break;
00244 case Axes::Z :
00245 s = "z";
00246 break;
00247 default:
00248 assert ( false );
00249 break;
00250 }
00251 element -> setAttribute ( m_axis, s );
00252 m_font -> setAttributes ( *element, *font );
00253
00254 tag.appendChild ( *element );
00255 delete element;
00256 }
00257 }
00258
00259 void
00260 PlotterBaseXML::
00261 createAxisModel ( XmlElement & tag,
00262 const PlotterBase & plotter,
00263 hippodraw::Axes::Type axis )
00264 {
00265 const AxisModelBase * model = plotter.getAxisModel ( axis );
00266 if ( model == 0 ) return;
00267
00268 XmlElement * element = m_axismodel->createElement ();
00269 string tmp;
00270 if ( axis == Axes::X ) {
00271 tmp = "x";
00272 }
00273 else if ( axis == Axes::Y ) {
00274 tmp = "y";
00275 }
00276 else if ( axis == Axes::Z ) {
00277 tmp = "z";
00278 }
00279 element -> setAttribute ( m_axis, tmp );
00280 m_axismodel->setAttributes ( *element, *model );
00281 tag.appendChild ( *element );
00282 delete element;
00283 }
00284
00285 XmlElement * PlotterBaseXML::createElement ( const PlotterBase & plotter )
00286 {
00287 XmlElement * tag = BaseXML::createElement ();
00288 const void * addr = reinterpret_cast < const void * > ( & plotter );
00289 int id = m_controller -> getId ( addr );
00290 setId ( *tag, id );
00291
00292 tag->setAttribute ( m_type, plotter.name () );
00293
00294 const string & title = plotter.getInternalTitle ();
00295 const string & x_label = plotter.getInternalLabel ( Axes::X );
00296 const string & y_label = plotter.getInternalLabel ( Axes::Y );
00297 const string & z_label = plotter.getInternalLabel ( Axes::Z );
00298
00299 tag -> setAttribute ( m_title, title );
00300 tag -> setAttribute ( m_x_label, x_label );
00301 tag -> setAttribute ( m_y_label, y_label );
00302 tag -> setAttribute ( m_z_label, z_label );
00303
00304 PlotterBase * parent = plotter.getParentPlotter ();
00305 if ( parent != 0 ) {
00306 const void * addr = reinterpret_cast < const void * > ( parent );
00307 int ref = m_controller -> getId ( addr );
00308 tag -> setAttribute ( "ref", ref );
00309 int index = plotter.getParentDataRepIndex ( );
00310 tag -> setAttribute ( m_pindex, index );
00311 }
00312
00313 createChildren ( *tag, plotter );
00314
00315 return tag;
00316 }
00317
00318 PlotterBase * PlotterBaseXML::getObject ( const XmlElement * plot_element )
00319 {
00320 PlotterBase * plotter = createPlotter ( plot_element );
00321
00322 if ( plotter == 0 ) return 0;
00323
00324 const XmlElement * element = m_transform_xml->getNode ( plot_element );
00325 if ( element != 0 ) {
00326 TransformBase * transform = m_transform_xml->createObject ( element );
00327 plotter->setTransform ( transform );
00328 }
00329
00330 createAxisModels ( plot_element, plotter );
00331 createFontObjects ( plot_element, plotter );
00332
00333 list < XmlElement * > nodelist;
00334 m_datarep->fillNodeList ( plot_element, nodelist );
00335
00336 FunctionController * controller = FunctionController::instance();
00337 DataRep * rep = 0;
00338
00339 #ifdef ITERATOR_MEMBER_DEFECT
00340 std::
00341 #endif
00342 list < XmlElement * > ::const_iterator first = nodelist.begin ();
00343 for ( ; first != nodelist.end(); ++first ) {
00344 XmlElement * element = *first;
00345 int id = element->getID ();
00346 rep = m_controller->getDataRep ( id );
00347 if ( rep == 0 ) {
00348 string what ( "Unable to find data representation" );
00349 throw DataRepException ( what );
00350 }
00351
00352 assert ( rep );
00353 handleFunction ( element, rep );
00354 controller->addDataRep ( plotter, rep );
00355 }
00356
00357 CutPlotter * cutplotter = dynamic_cast < CutPlotter * > ( plotter );
00358 if ( cutplotter != 0 ) {
00359 cutplotter -> addTupleCut ( rep );
00360 handleCutPlotter ( plot_element, cutplotter );
00361 }
00362
00363 TextPlotter * textplotter = dynamic_cast < TextPlotter * > ( plotter );
00364 if ( textplotter != 0 ) {
00365 if ( ! ( handleTextPlotter ( plot_element, textplotter ) ) ){
00366 return 0;
00367 }
00368 }
00369
00370 return plotter;
00371 }
00372
00373 void
00374 PlotterBaseXML::
00375 createFontObjects ( const XmlElement * plot_element, PlotterBase * plotter )
00376 {
00377 list < XmlElement * > nodelist;
00378 m_font -> fillNodeList ( plot_element, nodelist );
00379 if ( nodelist.empty () == false ) {
00380 XyPlotter * xypl = dynamic_cast < XyPlotter * > ( plotter );
00381 assert ( xypl );
00382
00383 list < XmlElement * > ::const_iterator first = nodelist.begin ();
00384
00385 while ( first != nodelist.end () ) {
00386 XmlElement * element = *first++;
00387 FontBase * font = m_controller -> createFont ();
00388 m_font -> setAttributes ( element, font );
00389 Axes::Type axis = m_font -> getAxis ( element, m_axis );
00390 if ( axis == Axes::T ) {
00391 xypl -> setTitleFont ( font );
00392 }
00393 else {
00394 xypl -> setLabelFont ( font, axis );
00395 }
00396 }
00397 }
00398 }
00399
00400 void
00401 PlotterBaseXML::
00402 createAxisModels ( const XmlElement * pl_element, PlotterBase * plotter )
00403 {
00404 list < XmlElement * > nodelist;
00405 m_axismodel->fillNodeList ( pl_element, nodelist );
00406 if ( nodelist.empty () == false ) {
00407
00408 #ifdef ITERATOR_MEMBER_DEFECT
00409 std::
00410 #endif
00411 list < XmlElement * > :: const_iterator first = nodelist.begin();
00412 for ( ; first != nodelist.end (); ++first ) {
00413 XmlElement * element = *first;
00414 Axes::Type axis = m_axismodel->getAxis ( element, m_axis );
00415 if ( axis == Axes::Z ) plotter -> setEnableZ ( true );
00416 AxisModelBase * model = plotter->getAxisModel ( axis );
00417
00418 if ( m_axismodel->isLog ( element ) == true ) {
00419 AxisLoc label = model->getLabelLocation();
00420 AxisLoc scale = model->getScaleLocation ();
00421 AxisModelBase * tmp = new AxisModelLog ( label, scale );
00422 std::swap ( tmp, model );
00423 delete tmp;
00424 plotter->setAxisModel ( model, axis );
00425 }
00426
00427 m_axismodel->setAttributes ( model, element );
00428 }
00429 }
00430 }
00431
00432 PlotterBase * PlotterBaseXML::createPlotter ( const XmlElement * element )
00433 {
00434 string type;
00435 bool ok = element->attribute ( m_type, type );
00436 assert ( ok );
00437
00438 bool has_Z = type == "XYColorPlotter";
00439 if ( type == "XYPlotter" ||
00440 type == "XYColorPlotter" ) {
00441 type = "XyPlotter";
00442 }
00443 PlotterBase * plotter = 0;
00444 PlotterFactory * factory = PlotterFactory::instance ();
00445 try {
00446 plotter = factory->create ( type );
00447 if ( has_Z ) plotter ->setEnableZ ();
00448 int id = element -> getID ();
00449 m_controller -> registerPlotter ( id, plotter );
00450
00451 string value;
00452 bool needMargin;
00453
00454 ok = element -> attribute ( m_title, value );
00455 plotter -> setTitle ( value );
00456 needMargin = String::ci_find(value, "tex:")==0;
00457 plotter->setTopMargin(needMargin?10.0:0.0);
00458
00459 ok = element -> attribute ( m_x_label, value );
00460 plotter -> setLabel ( Axes::X, value );
00461 needMargin = String::ci_find(value, "tex:")==0;
00462 plotter->setBottomMargin(needMargin?8.0:0.0);
00463
00464 ok = element -> attribute ( m_y_label, value );
00465 plotter -> setLabel ( Axes::Y, value );
00466 needMargin = String::ci_find(value, "tex:")==0;
00467 plotter->setLeftMargin(needMargin?0.0:0.0);
00468
00469 ok = element -> attribute ( m_z_label, value );
00470 plotter -> setLabel ( Axes::Z, value );
00471 needMargin = String::ci_find(value, "tex:")==0;
00472 plotter->setZMargin(needMargin?7.0:0.0);
00473
00474 int index;
00475 ok = element -> attribute ( m_pindex, index );
00476 if ( ok ) {
00477 plotter -> setParentDataRepIndex ( index );
00478 }
00479 }
00480 catch ( const FactoryException & ) {
00481 assert ( false );
00482 }
00483
00484 return plotter;
00485 }
00486
00487 void
00488 PlotterBaseXML::
00489 getCutTargets ( const XmlElement * plot_element, CutPlotter * plotter )
00490 {
00491 list < XmlElement * > nodelist;
00492 plot_element->fillNodeList ( "CutTarget", nodelist );
00493 if ( nodelist.empty() ) return;
00494
00495 #ifdef ITERATOR_MEMBER_DEFECT
00496 std::
00497 #endif
00498 list < XmlElement * > :: const_iterator first = nodelist.begin();
00499 for ( ; first != nodelist.end(); ++first ) {
00500 XmlElement * element = *first;
00501 int ref = element->getID ();
00502 DataRep * target = m_controller->getDataRep ( ref );
00503 if ( target != 0 ) {
00504 ProjectorBase * pb = target -> getProjector ();
00505 NTupleProjector * projector
00506 = dynamic_cast < NTupleProjector * > ( pb );
00507
00508 const vector < TupleCut > & cuts = plotter -> getCuts ();
00509 for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00510 projector -> addCut ( &cuts[i] );
00511 }
00512 target -> setDirty ( true );
00513 plotter->addCutTarget ( target );
00514 }
00515 }
00516 }
00517
00520 void PlotterBaseXML::handleFunction ( const XmlElement * dr_element,
00521 DataRep * rep )
00522 {
00523 FunctionRep * frep = dynamic_cast < FunctionRep * > ( rep );
00524 if ( frep == 0 ) return;
00525
00526 XmlElement * element = dr_element->getNode ( "FunctionTarget" );
00527 int id = element->getID ();
00528 DataRep * target = m_controller->getDataRep ( id );
00529 assert ( target );
00530 frep->setTarget ( target );
00531 }
00532
00536 void
00537 PlotterBaseXML::
00538 handleCutPlotter ( const XmlElement * plot_element, CutPlotter * plotter )
00539 {
00540 vector < const TupleCut * > cuts;
00541
00542
00543 list < XmlElement * > node_list;
00544 m_tuple_cut_xml -> fillNodeList ( plot_element, node_list );
00545 list < XmlElement * >::const_iterator first = node_list.begin();
00546
00547 while ( first != node_list.end() ) {
00548 const XmlElement * element = *first++;
00549 unsigned int a = 0;
00550
00551 element -> attribute ( "axis", a );
00552 Axes::Type axis = Axes::convert ( a );
00553 const string & label = plotter -> getLabel ( axis );
00554
00555 int id = element->getID ();
00556 const TupleCut * tuplecut = m_controller->getTupleCut ( id );
00557 TupleCut * tc = const_cast < TupleCut * > ( tuplecut );
00558 tc -> setLabel ( label );
00559 cuts.push_back ( tuplecut );
00560 tuplecut = m_controller -> getTupleCut ( -id );
00561 if ( tuplecut != 0 ) {
00562 cuts.push_back ( tuplecut );
00563 }
00564 }
00565 plotter->setCuts ( cuts );
00566
00567 getCutTargets ( plot_element, plotter );
00568 }
00569
00570 int
00571 PlotterBaseXML::
00572 handleTextPlotter ( const XmlElement * plot_element, TextPlotter * plotter )
00573 {
00574
00575 XmlElement * element = plot_element->getNode ( "TextTarget" );
00576 int id = element->getID ();
00577 DataRep * target = m_controller->getDataRep ( id );
00578
00579 if ( !target ){
00580 return 0;
00581 }
00582
00583 assert ( target );
00584 plotter->setParentDataRep ( target );
00585
00586 return 1;
00587 }