#include "Riostream.h"
#include "TPad.h"
#include "TGraphStruct.h"
#include <stdio.h>
#include <gvc.h>
#include <gvplugin.h>
#ifdef GVIZ_STATIC
extern gvplugin_library_t gvplugin_dot_layout_LTX_library;
lt_symlist_t lt_preloaded_symbols[] = {
{ "gvplugin_dot_layout_LTX_library", (void*)(&gvplugin_dot_layout_LTX_library) },
{ 0, 0 }
};
#endif
ClassImp(TGraphStruct)
TGraphStruct::TGraphStruct()
{
fNodes = 0;
fEdges = 0;
fGVGraph = 0;
fGVC = 0;
SetMargin();
}
TGraphStruct::~TGraphStruct()
{
gvFreeLayout(fGVC,(Agraph_t*)fGVGraph);
agclose((Agraph_t*)fGVGraph);
gvFreeContext(fGVC);
if (fNodes) delete fNodes;
if (fEdges) delete fEdges;
}
void TGraphStruct::AddEdge(TGraphEdge *edge)
{
if (!fEdges) fEdges = new TList;
fEdges->Add(edge);
}
TGraphEdge *TGraphStruct::AddEdge(TGraphNode *n1, TGraphNode *n2)
{
if (!fEdges) fEdges = new TList;
TGraphEdge *edge = new TGraphEdge(n1, n2);
fEdges->Add(edge);
return edge;
}
void TGraphStruct::AddNode(TGraphNode *node)
{
if (!fNodes) fNodes = new TList;
fNodes->Add(node);
}
TGraphNode *TGraphStruct::AddNode(const char *name, const char *title)
{
if (!fNodes) fNodes = new TList;
TGraphNode *node = (TGraphNode*)fNodes->FindObject(name);
if (!node) {
node = new TGraphNode(name, title);
fNodes->Add(node);
}
return node;
}
void TGraphStruct::DumpAsDotFile(const char *filename)
{
if (!fGVGraph) {
Int_t ierr = Layout();
if (ierr) return;
}
FILE *file;
file=fopen(filename,"wt");
if (file) {
agwrite((Agraph_t*)fGVGraph, file);
fclose(file);
}
}
void TGraphStruct::Draw(Option_t *option)
{
if (!fGVGraph) {
Int_t ierr = Layout();
if (ierr) return;
}
if (gPad) {
gPad->Range(GD_bb((Agraph_t*)fGVGraph).LL.x-fMargin, GD_bb((Agraph_t*)fGVGraph).LL.y-fMargin,
GD_bb((Agraph_t*)fGVGraph).UR.x+fMargin, GD_bb((Agraph_t*)fGVGraph).UR.y+fMargin);
}
AppendPad(option);
if (fNodes) {
TGraphNode *node;
node = (TGraphNode*) fNodes->First();
node->Draw();
for(Int_t i = 1; i < fNodes->GetSize(); i++){
node = (TGraphNode*)fNodes->After(node);
if (node) node->Draw();
}
}
if (fEdges) {
TGraphEdge *edge;
edge = (TGraphEdge*) fEdges->First();
edge->Draw();
for(Int_t i = 1; i < fEdges->GetSize(); i++){
edge = (TGraphEdge*)fEdges->After(edge);
if (edge) edge->Draw();
}
}
}
Int_t TGraphStruct::Layout()
{
TGraphNode *node;
TGraphEdge *edge;
if (fGVC) gvFreeContext(fGVC);
#ifdef GVIZ_STATIC
fGVC = gvContextPlugins(lt_preloaded_symbols, 0);
#else
fGVC = gvContext();
#endif
if (fGVGraph) {
gvFreeLayout(fGVC,(Agraph_t*)fGVGraph);
agclose((Agraph_t*)fGVGraph);
}
#ifdef WITH_CGRAPH
fGVGraph = (GVizAgraph_t*)agopen((char*)"GVGraph", Agdirected, 0);
#else
fGVGraph = (GVizAgraph_t*)agopen((char*)"GVGraph", AGDIGRAPH);
#endif
if (fNodes) {
node = (TGraphNode*) fNodes->First();
node->CreateGVNode(fGVGraph);
for(Int_t i = 1; i < fNodes->GetSize(); i++){
node = (TGraphNode*)fNodes->After(node);
if (node) node->CreateGVNode(fGVGraph);
}
}
if (fEdges) {
edge = (TGraphEdge*) fEdges->First();
edge->CreateGVEdge(fGVGraph);
for(Int_t i = 1; i < fEdges->GetSize(); i++){
edge = (TGraphEdge*)fEdges->After(edge);
if (edge) edge->CreateGVEdge(fGVGraph);
}
}
int ierr = gvLayout(fGVC, (Agraph_t*)fGVGraph, (char*)"dot");
if (ierr) return ierr;
if (fNodes) {
node = (TGraphNode*) fNodes->First();
node->Layout();
for(Int_t i = 1; i < fNodes->GetSize(); i++){
node = (TGraphNode*)fNodes->After(node);
if (node) node->Layout();
}
}
if (fEdges) {
edge = (TGraphEdge*) fEdges->First();
edge->Layout();
for(Int_t i = 1; i < fEdges->GetSize(); i++){
edge = (TGraphEdge*)fEdges->After(edge);
if (edge) edge->Layout();
}
}
return 0;
}
void TGraphStruct::SavePrimitive(std::ostream &out, Option_t * )
{
out<<" TGraphStruct *graphstruct = new TGraphStruct();"<<std::endl;
if (fNodes) {
TGraphNode *node;
node = (TGraphNode*) fNodes->First();
out<<" TGraphNode *"<<node->GetName()<<" = graphstruct->AddNode(\""<<
node->GetName()<<"\",\""<<
node->GetTitle()<<"\");"<<std::endl;
node->SaveAttributes(out);
for(Int_t i = 1; i < fNodes->GetSize(); i++){
node = (TGraphNode*)fNodes->After(node);
if (node) {
out<<" TGraphNode *"<<node->GetName()<<" = graphstruct->AddNode(\""<<
node->GetName()<<"\",\""<<
node->GetTitle()<<"\");"<<std::endl;
node->SaveAttributes(out);
}
}
}
if (fEdges) {
TGraphEdge *edge;
Int_t en = 1;
edge = (TGraphEdge*) fEdges->First();
out<<" TGraphEdge *"<<"e"<<en<<
" = new TGraphEdge("<<
edge->GetNode1()->GetName()<<","<<
edge->GetNode2()->GetName()<<");"<<std::endl;
out<<" graphstruct->AddEdge("<<"e"<<en<<");"<<std::endl;
edge->SaveAttributes(out,Form("e%d",en));
for(Int_t i = 1; i < fEdges->GetSize(); i++){
en++;
edge = (TGraphEdge*)fEdges->After(edge);
if (edge) {
out<<" TGraphEdge *"<<"e"<<en<<
" = new TGraphEdge("<<
edge->GetNode1()->GetName()<<","<<
edge->GetNode2()->GetName()<<");"<<std::endl;
out<<" graphstruct->AddEdge("<<"e"<<en<<");"<<std::endl;
edge->SaveAttributes(out,Form("e%d",en));
}
}
}
out<<" graphstruct->Draw();"<<std::endl;
}
void TGraphStruct::Streamer(TBuffer &)
{
}