OR-Tools  9.6
graph_export.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <memory>
17 #include <string>
18 
19 #include "absl/status/status.h"
20 #include "absl/strings/str_format.h"
21 #include "ortools/base/file.h"
22 #include "ortools/base/helpers.h"
23 #include "ortools/base/logging.h"
24 #include "ortools/base/macros.h"
25 
26 namespace operations_research {
27 
29 
30 namespace {
31 class GraphSyntax {
32  public:
33  virtual ~GraphSyntax() {}
34 
35  // Node in the right syntax.
36  virtual std::string Node(const std::string& name, const std::string& label,
37  const std::string& shape,
38  const std::string& color) = 0;
39  // Adds one link in the generated graph.
40  virtual std::string Link(const std::string& source,
41  const std::string& destination,
42  const std::string& label) = 0;
43  // File header.
44  virtual std::string Header(const std::string& name) = 0;
45 
46  // File footer.
47  virtual std::string Footer() = 0;
48 };
49 
50 class DotSyntax : public GraphSyntax {
51  public:
52  ~DotSyntax() override {}
53 
54  std::string Node(const std::string& name, const std::string& label,
55  const std::string& shape,
56  const std::string& color) override {
57  return absl::StrFormat("%s [shape=%s label=\"%s\" color=%s]\n", name, shape,
58  label, color);
59  }
60 
61  // Adds one link in the generated graph.
62  std::string Link(const std::string& source, const std::string& destination,
63  const std::string& label) override {
64  return absl::StrFormat("%s -> %s [label=%s]\n", source, destination, label);
65  }
66 
67  // File header.
68  std::string Header(const std::string& name) override {
69  return absl::StrFormat("graph %s {\n", name);
70  }
71 
72  // File footer.
73  std::string Footer() override { return "}\n"; }
74 };
75 
76 class GmlSyntax : public GraphSyntax {
77  public:
78  ~GmlSyntax() override {}
79 
80  std::string Node(const std::string& name, const std::string& label,
81  const std::string& shape,
82  const std::string& color) override {
83  return absl::StrFormat(
84  " node [\n"
85  " name \"%s\"\n"
86  " label \"%s\"\n"
87  " graphics [\n"
88  " type \"%s\"\n"
89  " fill \"%s\"\n"
90  " ]\n"
91  " ]\n",
92  name, label, shape, color);
93  }
94 
95  // Adds one link in the generated graph.
96  std::string Link(const std::string& source, const std::string& destination,
97  const std::string& label) override {
98  return absl::StrFormat(
99  " edge [\n"
100  " label \"%s\"\n"
101  " source \"%s\"\n"
102  " target \"%s\"\n"
103  " ]\n",
104  label, source, destination);
105  }
106 
107  // File header.
108  std::string Header(const std::string& name) override {
109  return absl::StrFormat(
110  "graph [\n"
111  " name \"%s\"\n",
112  name);
113  }
114 
115  // File footer.
116  std::string Footer() override { return "]\n"; }
117 };
118 
119 // Graph exporter that will write to a file with a given format.
120 // Takes ownership of the GraphSyntax parameter.
121 class FileGraphExporter : public GraphExporter {
122  public:
123  FileGraphExporter(File* const file, GraphSyntax* const syntax)
124  : file_(file), syntax_(syntax) {}
125 
126  ~FileGraphExporter() override {}
127 
128  // Write node in GML or DOT format.
129  void WriteNode(const std::string& name, const std::string& label,
130  const std::string& shape, const std::string& color) override {
131  Append(syntax_->Node(name, label, shape, color));
132  }
133 
134  // Adds one link in the generated graph.
135  void WriteLink(const std::string& source, const std::string& destination,
136  const std::string& label) override {
137  Append(syntax_->Link(source, destination, label));
138  }
139 
140  void WriteHeader(const std::string& name) override {
141  Append(syntax_->Header(name));
142  }
143 
144  void WriteFooter() override { Append(syntax_->Footer()); }
145 
146  private:
147  void Append(const std::string& str) {
148  file::WriteString(file_, str, file::Defaults()).IgnoreError();
149  }
150 
151  File* const file_;
152  std::unique_ptr<GraphSyntax> syntax_;
153 };
154 } // namespace
155 
157  File* const file, GraphExporter::GraphFormat format) {
158  GraphSyntax* syntax = nullptr;
159  switch (format) {
161  syntax = new DotSyntax();
162  break;
163  }
165  syntax = new GmlSyntax();
166  break;
167  }
168  default:
169  LOG(FATAL) << "Unknown graph format";
170  }
171  CHECK(syntax != nullptr);
172  return new FileGraphExporter(file, syntax);
173 }
174 } // namespace operations_research
Definition: base/file.h:33
static GraphExporter * MakeFileExporter(File *const file, GraphExporter::GraphFormat format)
const std::string name
absl::Status WriteString(File *file, const absl::string_view &contents, int flags)
Definition: base/file.cc:194
Options Defaults()
Definition: base/file.h:123
Collection of objects used to extend the Constraint Solver library.