TGraphStruct.cxx

Go to the documentation of this file.
00001 // @(#)root/hist:$Id: TGraphStruct.cxx 31144 2009-11-13 08:56:21Z brun $
00002 // Author: Olivier Couet 13/07/09
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include "TPad.h"
00014 #include "TGraphStruct.h"
00015 
00016 #include <stdio.h>
00017 
00018 #include <gvc.h>
00019 #include <gvplugin.h>
00020 
00021 #ifdef GVIZ_STATIC
00022 extern gvplugin_library_t gvplugin_dot_layout_LTX_library;
00023 ///extern gvplugin_library_t gvplugin_neato_layout_LTX_library;
00024 ///extern gvplugin_library_t gvplugin_core_LTX_library;
00025 
00026 
00027 lt_symlist_t lt_preloaded_symbols[] = {
00028    { "gvplugin_dot_layout_LTX_library",   (void*)(&gvplugin_dot_layout_LTX_library) },
00029 ///   { "gvplugin_neato_layout_LTX_library", (void*)(&gvplugin_neato_layout_LTX_library) },
00030 ///   { "gvplugin_core_LTX_library",         (void*)(&gvplugin_core_LTX_library) },
00031    { 0, 0 }
00032 };
00033 #endif
00034 
00035 ClassImp(TGraphStruct)
00036 
00037 
00038 //______________________________________________________________________________
00039 /* Begin_Html
00040 <center><h2>Graph Structure class</h2></center>
00041 The Graph Structure is an interface to the graphviz package.
00042 <p>
00043 The graphviz package is a graph visualization system. This interface consists in
00044 three classes:
00045 <ol>
00046 <li> TGraphStruct: holds the graph structure. It uses the graphiz library to
00047      layout the graphs and the ROOT graphics to paint them.
00048 <li> TGraphNode: Is a graph node object which can be added in a TGraphStruct.
00049 <li> TGraphEdge: Is an edge object connecting two nodes which can be added in 
00050      a TGraphStruct.
00051 </ol>
00052 End_Html
00053 Begin_Macro(source)
00054 ../../../tutorials/graphs/graphstruct.C
00055 End_Macro
00056 Begin_Html
00057 A graph structure can be dumped into a "dot" file using DumpAsDotFile.
00058 End_Html */
00059 
00060 
00061 //______________________________________________________________________________
00062 TGraphStruct::TGraphStruct()
00063 {
00064    // Graph Structure default constructor.
00065 
00066    fNodes   = 0;
00067    fEdges   = 0;
00068    fGVGraph = 0;
00069    fGVC     = 0;
00070 
00071    SetMargin();
00072 }
00073 
00074 
00075 //______________________________________________________________________________
00076 TGraphStruct::~TGraphStruct()
00077 {
00078    // Graph Structure default destructor.
00079 
00080    gvFreeLayout(fGVC,fGVGraph);
00081    agclose(fGVGraph);
00082    gvFreeContext(fGVC);
00083 
00084    if (fNodes) delete fNodes;
00085    if (fEdges) delete fEdges;
00086 
00087 }
00088 
00089 
00090 //______________________________________________________________________________
00091 void TGraphStruct::AddEdge(TGraphEdge *edge)
00092 {
00093    // Add the edge "edge" in this TGraphStruct.
00094 
00095    if (!fEdges) fEdges = new TList;
00096 
00097    fEdges->Add(edge);
00098 }
00099 
00100 
00101 //______________________________________________________________________________
00102 TGraphEdge *TGraphStruct::AddEdge(TGraphNode *n1, TGraphNode *n2)
00103 {
00104    // Create an edge between n1 and n2 and put it in this graph.
00105    //
00106    // Two edges can connect the same nodes the same way, so there
00107    // is no need to check if an edge already exists.
00108 
00109    if (!fEdges) fEdges = new TList;
00110 
00111    TGraphEdge *edge = new TGraphEdge(n1, n2);
00112    fEdges->Add(edge);
00113 
00114    return edge;
00115 }
00116 
00117 
00118 //______________________________________________________________________________
00119 void TGraphStruct::AddNode(TGraphNode *node)
00120 {
00121    // Add the node "node" in this TGraphStruct.
00122 
00123    if (!fNodes) fNodes = new TList;
00124 
00125    fNodes->Add(node);
00126 }
00127 
00128 
00129 //______________________________________________________________________________
00130 TGraphNode *TGraphStruct::AddNode(const char *name, const char *title)
00131 {
00132    // Create the node "name" if it does not exist and add it to this TGraphStruct.
00133 
00134    if (!fNodes) fNodes = new TList;
00135 
00136    TGraphNode *node = (TGraphNode*)fNodes->FindObject(name);
00137 
00138    if (!node) {
00139       node = new TGraphNode(name, title);
00140       fNodes->Add(node);
00141    }
00142 
00143    return node;
00144 }
00145 
00146 
00147 
00148 //______________________________________________________________________________
00149 void TGraphStruct::DumpAsDotFile(const char *filename)
00150 {
00151    // Dump this graph structure as a "dot" file.
00152 
00153    if (!fGVGraph) {
00154      Int_t ierr = Layout();
00155      if (ierr) return;
00156    }
00157    FILE  *file;
00158    file=fopen(filename,"wt");
00159    agwrite(fGVGraph, file);
00160    fclose(file);
00161 }
00162 
00163 
00164 //______________________________________________________________________________
00165 void TGraphStruct::Draw(Option_t *option)
00166 {
00167    // Draw the graph
00168 
00169    if (!fGVGraph) {
00170      Int_t ierr = Layout();
00171      if (ierr) return;
00172    }
00173 
00174    // Get the bounding box
00175    if (gPad) {
00176       gPad->Range(GD_bb(fGVGraph).LL.x-fMargin, GD_bb(fGVGraph).LL.y-fMargin,
00177                   GD_bb(fGVGraph).UR.x+fMargin, GD_bb(fGVGraph).UR.y+fMargin);
00178    }
00179 
00180    AppendPad(option);
00181 
00182    // Draw the nodes
00183    if (fNodes) {
00184       TGraphNode *node;
00185       node = (TGraphNode*) fNodes->First();
00186       node->Draw();
00187       for(Int_t i = 1; i < fNodes->GetSize(); i++){
00188          node = (TGraphNode*)fNodes->After(node);
00189          node->Draw();
00190       }
00191    }
00192 
00193    // Draw the edges
00194    if (fEdges) {
00195       TGraphEdge *edge;
00196       edge = (TGraphEdge*) fEdges->First();
00197       edge->Draw();
00198       for(Int_t i = 1; i < fEdges->GetSize(); i++){
00199          edge = (TGraphEdge*)fEdges->After(edge);
00200          edge->Draw();
00201       }
00202    }
00203 }
00204 
00205 
00206 //______________________________________________________________________________
00207 Int_t TGraphStruct::Layout()
00208 {
00209    // Layout the graph into a GraphViz data structure
00210 
00211    TGraphNode *node;
00212    TGraphEdge *edge;
00213 
00214    // Create the graph context.
00215    if (fGVC) gvFreeContext(fGVC);
00216 #ifdef GVIZ_STATIC
00217    fGVC = gvContextPlugins(lt_preloaded_symbols, 0);
00218 #else
00219    fGVC = gvContext();
00220 #endif
00221 
00222    // Create the graph.
00223    if (fGVGraph) {
00224       gvFreeLayout(fGVC,fGVGraph);
00225       agclose(fGVGraph);
00226    }
00227    fGVGraph = agopen((char*)"GVGraph", AGDIGRAPH);
00228 
00229    // Put the GV nodes into the GV graph
00230    if (fNodes) {
00231       node = (TGraphNode*) fNodes->First();
00232       node->CreateGVNode(fGVGraph);
00233       for(Int_t i = 1; i < fNodes->GetSize(); i++){
00234          node = (TGraphNode*)fNodes->After(node);
00235          node->CreateGVNode(fGVGraph);
00236       }
00237    }
00238 
00239    // Put the edges into the graph
00240    if (fEdges) {
00241       edge = (TGraphEdge*) fEdges->First();
00242       edge->CreateGVEdge(fGVGraph);
00243       for(Int_t i = 1; i < fEdges->GetSize(); i++){
00244          edge = (TGraphEdge*)fEdges->After(edge);
00245          edge->CreateGVEdge(fGVGraph);
00246       }
00247    }
00248 
00249    // Layout the graph
00250    int ierr = gvLayout(fGVC, fGVGraph, (char*)"dot");
00251    if (ierr) return ierr;
00252 
00253    // Layout the nodes
00254    if (fNodes) {
00255       node = (TGraphNode*) fNodes->First();
00256       node->Layout();
00257       for(Int_t i = 1; i < fNodes->GetSize(); i++){
00258          node = (TGraphNode*)fNodes->After(node);
00259          node->Layout();
00260       }
00261    }
00262 
00263    // Layout the edges
00264    if (fEdges) {
00265       edge = (TGraphEdge*) fEdges->First();
00266       edge->Layout();
00267       for(Int_t i = 1; i < fEdges->GetSize(); i++){
00268          edge = (TGraphEdge*)fEdges->After(edge);
00269          edge->Layout();
00270       }
00271    }
00272 
00273    return 0;
00274 }
00275 
00276 
00277 //______________________________________________________________________________
00278 void TGraphStruct::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00279 {
00280    // Save primitive as a C++ statement(s) on output stream out
00281 
00282    out<<"   TGraphStruct *graphstruct = new  TGraphStruct();"<<endl;
00283 
00284    // Save the nodes
00285    if (fNodes) {
00286       TGraphNode *node;
00287       node = (TGraphNode*) fNodes->First();
00288       out<<"   TGraphNode *"<<node->GetName()<<" = graphstruct->AddNode(\""<<
00289                             node->GetName()<<"\",\""<<
00290                             node->GetTitle()<<"\");"<<endl;
00291       node->SaveAttributes(out);
00292       for(Int_t i = 1; i < fNodes->GetSize(); i++){
00293          node = (TGraphNode*)fNodes->After(node);
00294          out<<"   TGraphNode *"<<node->GetName()<<" = graphstruct->AddNode(\""<<
00295                                node->GetName()<<"\",\""<<
00296                                node->GetTitle()<<"\");"<<endl;
00297          node->SaveAttributes(out);
00298       }
00299    }
00300 
00301    // Save the edges
00302    if (fEdges) {
00303       TGraphEdge *edge;
00304       Int_t en = 1;
00305       edge = (TGraphEdge*) fEdges->First();
00306       out<<"   TGraphEdge *"<<"e"<<en<<
00307                             " = new TGraphEdge("<<
00308                             edge->GetNode1()->GetName()<<","<<
00309                             edge->GetNode2()->GetName()<<");"<<endl;
00310       out<<"   graphstruct->AddEdge("<<"e"<<en<<");"<<endl;
00311       edge->SaveAttributes(out,Form("e%d",en));
00312       for(Int_t i = 1; i < fEdges->GetSize(); i++){
00313          en++;
00314          edge = (TGraphEdge*)fEdges->After(edge);
00315          out<<"   TGraphEdge *"<<"e"<<en<<
00316                                " = new TGraphEdge("<<
00317                                edge->GetNode1()->GetName()<<","<<
00318                                edge->GetNode2()->GetName()<<");"<<endl;
00319          out<<"   graphstruct->AddEdge("<<"e"<<en<<");"<<endl;
00320          edge->SaveAttributes(out,Form("e%d",en));
00321       }
00322    }
00323 
00324    out<<"   graphstruct->Draw();"<<endl;
00325 }
00326 
00327 
00328 //______________________________________________________________________________
00329 void TGraphStruct::Streamer(TBuffer &/*b*/)
00330 {
00331 }

Generated on Tue Jul 5 14:14:29 2011 for ROOT_528-00b_version by  doxygen 1.5.1