I am constructing graph with Boost Graph Library and Graphviz. In my code, I have a class that export a Graph to a .dot format. I setup the properties of the graph with the following lines:
dynamic_properties dp;
dp.property("rankdir", boost::make_constant_property<Graph*>(std::string("TB")));
dp.property("node_id", get(&VertexP::tag, m_graph));
dp.property("label", get(&VertexP::tag, m_graph));
dp.property("shape", get(&VertexP::shape, m_graph));
dp.property("style", get(&VertexP::style, m_graph));
dp.property("pos", get(&VertexP::pos, m_graph));
dp.property("label", get(&ArrowP::symbol, m_graph));
dp.property("color", get(&ArrowP::color, m_graph));
dp.property("style", get(&ArrowP::style, m_graph));
write_graphviz_dp(ss, m_graph, dp);
I am trying to use the fixedsize
keyword of graphviz and the width
and height
keywords to fix the size of my node (they have different sizes depending on the quantity of text in the label).
I would like to setup it from the dp.property
method. The objective being to add the following line in my .dot document:
node [ fixedsize = true, width = 1.1, height = 1.1]
I have tried the following but it does not work:
dp.property("fixedsize", boost::make_constant_property<VertexP*>(std::string("true")));
dp.property("width", boost::make_constant_property<VertexP*>(std::string("1")));
dp.property("height", boost::make_constant_property<VertexP*>(std::string("1")));
Do you know how I can set the attribute fixedsize to my vertex in my dot file from dp.property.
In the property maps, the key_type (boost::property_traits<PMap>::key_type
) informs the library what type of object the property belongs to:
graph_traits<G>::vertex_descriptor
attaches the attribute to objects of node type (vertices)graph_traits<G>::edge_descriptor
attaches attributes to the edgesG*
attaches attributes at the graph levelTherefore you need to use vertex_descriptor
instead of VertexP*
for these maps:
dp.property("fixedsize", boost::make_constant_property<Graph::vertex_descriptor>(+"true"));
dp.property("width", boost::make_constant_property<Graph::vertex_descriptor>(1));
dp.property("height", boost::make_constant_property<Graph::vertex_descriptor>(1));
Note that default streaming operations are used so there is no need to specifically convert to std::string
Note though that the attributes are being written to temporary streams, so
std::boolalpha
is not honored. Also note that using a string literal would lead to the propertymap instantiating withchar const(&)[5]
, which is why+"true"
is used (decaying tochar const*
).
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct VertexP {
std::string tag, shape, style, pos;
};
struct ArrowP {
std::string symbol, color, style;
};
using Graph = boost::adjacency_list<
boost::vecS, boost::vecS, boost::directedS,
VertexP, ArrowP>;
int main() {
Graph g;
boost::dynamic_properties dp;
dp.property("rankdir", boost::make_constant_property<Graph*>(+"TB"));
dp.property("node_id", get(&VertexP::tag, g));
dp.property("label", get(&VertexP::tag, g));
dp.property("shape", get(&VertexP::shape, g));
dp.property("style", get(&VertexP::style, g));
dp.property("pos", get(&VertexP::pos, g));
dp.property("label", get(&ArrowP::symbol, g));
dp.property("color", get(&ArrowP::color, g));
dp.property("style", get(&ArrowP::style, g));
dp.property("fixedsize", boost::make_constant_property<Graph::vertex_descriptor>(+"true"));
dp.property("width", boost::make_constant_property<Graph::vertex_descriptor>(1));
dp.property("height", boost::make_constant_property<Graph::vertex_descriptor>(1));
add_edge(
add_vertex({"foo", "diamond", "dotted", "0,1"}, g),
add_vertex({"bar", "circle", "dashed", "1,1"}, g),
{"foo-bar", "blue", "dashed"},
g);
write_graphviz_dp(std::cout, g, dp);
}
Prints
digraph G {
rankdir=TB;
bar [fixedsize=true, height=1, label=bar, pos="1,1", shape=circle, style=dashed, width=1];
foo [fixedsize=true, height=1, label=foo, pos="0,1", shape=diamond, style=dotted, width=1];
foo->bar [color=blue, label="foo-bar", style=dashed];
}