00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "util/graph_export.h"
00015
00016 #include "base/logging.h"
00017 #include "base/macros.h"
00018 #include "base/scoped_ptr.h"
00019 #include "base/stringprintf.h"
00020
00021 namespace operations_research {
00022
00023 GraphExporter::~GraphExporter() {}
00024
00025 namespace {
00026 class GraphSyntax {
00027 public:
00028 virtual ~GraphSyntax() {}
00029
00030
00031 virtual string Node(const string& name,
00032 const string& label,
00033 const string& shape,
00034 const string& color) = 0;
00035
00036 virtual string Link(const string& source,
00037 const string& destination,
00038 const string& label) = 0;
00039
00040 virtual string Header(const string& name) = 0;
00041
00042
00043 virtual string Footer() = 0;
00044 };
00045
00046 class DotSyntax : public GraphSyntax {
00047 public:
00048 virtual ~DotSyntax() {}
00049
00050 virtual string Node(const string& name,
00051 const string& label,
00052 const string& shape,
00053 const string& color) {
00054 return StringPrintf("%s [shape=%s label=\"%s\" color=%s]\n",
00055 name.c_str(),
00056 shape.c_str(),
00057 label.c_str(),
00058 color.c_str());
00059 }
00060
00061
00062 virtual string Link(const string& source,
00063 const string& destination,
00064 const string& label) {
00065 return StringPrintf("%s -> %s [label=%s]\n",
00066 source.c_str(),
00067 destination.c_str(),
00068 label.c_str());
00069 }
00070
00071
00072 virtual string Header(const string& name) {
00073 return StringPrintf("graph %s {\n", name.c_str());
00074 }
00075
00076
00077 virtual string Footer() {
00078 return "}\n";
00079 }
00080 };
00081
00082 class GmlSyntax : public GraphSyntax {
00083 public:
00084 virtual ~GmlSyntax() {}
00085
00086 virtual string Node(const string& name,
00087 const string& label,
00088 const string& shape,
00089 const string& color) {
00090 return StringPrintf(" node [\n"
00091 " name \"%s\"\n"
00092 " label \"%s\"\n"
00093 " graphics [\n"
00094 " type \"%s\"\n"
00095 " fill \"%s\"\n"
00096 " ]\n"
00097 " ]\n",
00098 name.c_str(),
00099 label.c_str(),
00100 shape.c_str(),
00101 color.c_str());
00102 }
00103
00104
00105 virtual string Link(const string& source,
00106 const string& destination,
00107 const string& label) {
00108 return StringPrintf(" edge [\n"
00109 " label \"%s\"\n"
00110 " source \"%s\"\n"
00111 " target \"%s\"\n"
00112 " ]\n",
00113 label.c_str(),
00114 source.c_str(),
00115 destination.c_str());
00116 }
00117
00118
00119 virtual string Header(const string& name) {
00120 return StringPrintf("graph [\n"
00121 " name \"%s\"\n"
00122 , name.c_str());
00123 }
00124
00125
00126 virtual string Footer() {
00127 return "]\n";
00128 }
00129 };
00130
00131
00132
00133 class FileGraphExporter : public GraphExporter {
00134 public:
00135 FileGraphExporter(File* const file, GraphSyntax* const syntax)
00136 : file_(file), syntax_(syntax) {}
00137
00138 virtual ~FileGraphExporter() {}
00139
00140
00141 virtual void WriteNode(const string& name,
00142 const string& label,
00143 const string& shape,
00144 const string& color) {
00145 Append(syntax_->Node(name, label, shape, color));
00146 }
00147
00148
00149 virtual void WriteLink(const string& source,
00150 const string& destination,
00151 const string& label) {
00152 Append(syntax_->Link(source, destination, label));
00153 }
00154
00155 virtual void WriteHeader(const string& name) {
00156 Append(syntax_->Header(name));
00157 }
00158
00159 virtual void WriteFooter() {
00160 Append(syntax_->Footer());
00161 }
00162
00163 private:
00164 void Append(const string& string) {
00165 file_->Write(string.c_str(), string.size());
00166 }
00167
00168 File* const file_;
00169 scoped_ptr<GraphSyntax> syntax_;
00170 };
00171 }
00172
00173 GraphExporter* GraphExporter::MakeFileExporter(
00174 File* const file,
00175 GraphExporter::GraphFormat format) {
00176 GraphSyntax* syntax = NULL;
00177 switch (format) {
00178 case GraphExporter::DOT_FORMAT: {
00179 syntax = new DotSyntax();
00180 break;
00181 }
00182 case GraphExporter::GML_FORMAT: {
00183 syntax = new GmlSyntax();
00184 break;
00185 }
00186 default:
00187 LOG(FATAL) << "Unknown graph format";
00188 }
00189 CHECK(syntax != NULL);
00190 return new FileGraphExporter(file, syntax);
00191 }
00192 }