在没有系统命令的情况下使用 graphviz 和 C++ 生成 png 格式的多个图形
Generate multiple graph in png format with graphviz and C++ without system command
我正在尝试在 C++ 应用程序中从 graphviz 生成图片格式的图形。
我的处理方式如下。
从 boost 库中,我创建了一个 adjancy_list:
struct VertexP { std::string tag; std::string shape;std::string style; };
struct EdgeP { std::string symbol; std::string color; };
struct GraphP { };
typedef adjacency_list<vecS, vecS, directedS, VertexP, EdgeP, GraphP> Graph;
我有一个函数可以从外部数据递归构建我的图表
Graph addnode_progeny(data, Graph );
然后,我有一个生成这个图的点文件的函数。
void printGraphDot(Graph g, std::string file_path){
std::ofstream dot_file(file_path+".dot");
dynamic_properties dp;
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("label", get(&EdgeP::symbol, g));
dp.property("color", get(&EdgeP::color, g));
dp.property("rankdir", boost::make_constant_property<Graph*>(std::string("TB")));
write_graphviz_dp(dot_file, g, dp);
}
至此,一切顺利。
现在,我想把这个点文件转换成png文件。
我不想通过系统("dot -Tpng input -o output")命令传递,因为我不想强迫用户安装 graphviz。
我在下面post找到了第一个想法:
我已经修改了代码。我已将它添加到上一个函数中,当我需要生成一个图形时它可以工作。
新函数是:
void printGraphDot(Graph g, std::string file_path){
std::ofstream dot_file(file_path+".dot");
dynamic_properties dp;
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("label", get(&EdgeP::symbol, g));
dp.property("color", get(&EdgeP::color, g));
dp.property("rankdir", boost::make_constant_property<Graph*>(std::string("TB")));
write_graphviz_dp(dot_file, g, dp);
std::string o_arg = "-o" +file_path+".png";
std::string i_arg = file_path+".dot";
char* args[] = {const_cast<char*>("dot"),
const_cast<char*>("-Tpng"),
const_cast<char*>(i_arg.c_str()),
const_cast<char*>(o_arg.c_str()) };
const int argc = sizeof(args)/sizeof(args[0]);
Agraph_t *h, *prev = NULL;
GVC_t *gvc;
gvc = gvContext();
gvParseArgs(gvc, argc, args);
while ((h = gvNextInputGraph(gvc)))
{
if (prev)
{
gvFreeLayout(gvc, prev);
agclose(prev);
}
gvLayoutJobs(gvc, h);
gvRenderJobs(gvc, h);
prev = h;
}
}
但是,对于多图,如果我再次调用这个函数,它不起作用并且我有一个分割错误。事实上,我们在一个应用程序中只能使用一个 GVC_t,在以下文档第 25 页中写道:http://www.graphviz.org/pdf/libguide.pdf.
因此在以下情况下,它会停止程序并出现段错误:
printGraphDot( g1, file_path1);
printGraphDot( g2, file_path2);
是否有另一种方法可以在不使用命令的情况下从 C++ 应用程序中的点文件生成 png 图形?
非常感谢您的帮助。
干杯
我找到了一种方法,我使用了以下函数并且它起作用了,我也在 中添加了这个答案:
bool saveImageGV(std::string file_path){
GVC_t *gvc;
Agraph_t *g;
FILE *fp;
gvc = gvContext();
fp = fopen((file_path+".dot").c_str(), "r");
g = agread(fp, 0);
gvLayout(gvc, g, "dot");
gvRender(gvc, g, "png", fopen((file_path+".png").c_str(), "w"));
gvFreeLayout(gvc, g);
agclose(g);
return (gvFreeContext(gvc));
}
我正在尝试在 C++ 应用程序中从 graphviz 生成图片格式的图形。
我的处理方式如下。 从 boost 库中,我创建了一个 adjancy_list:
struct VertexP { std::string tag; std::string shape;std::string style; };
struct EdgeP { std::string symbol; std::string color; };
struct GraphP { };
typedef adjacency_list<vecS, vecS, directedS, VertexP, EdgeP, GraphP> Graph;
我有一个函数可以从外部数据递归构建我的图表
Graph addnode_progeny(data, Graph );
然后,我有一个生成这个图的点文件的函数。
void printGraphDot(Graph g, std::string file_path){
std::ofstream dot_file(file_path+".dot");
dynamic_properties dp;
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("label", get(&EdgeP::symbol, g));
dp.property("color", get(&EdgeP::color, g));
dp.property("rankdir", boost::make_constant_property<Graph*>(std::string("TB")));
write_graphviz_dp(dot_file, g, dp);
}
至此,一切顺利。
现在,我想把这个点文件转换成png文件。 我不想通过系统("dot -Tpng input -o output")命令传递,因为我不想强迫用户安装 graphviz。
我在下面post找到了第一个想法:
我已经修改了代码。我已将它添加到上一个函数中,当我需要生成一个图形时它可以工作。
新函数是:
void printGraphDot(Graph g, std::string file_path){
std::ofstream dot_file(file_path+".dot");
dynamic_properties dp;
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("label", get(&EdgeP::symbol, g));
dp.property("color", get(&EdgeP::color, g));
dp.property("rankdir", boost::make_constant_property<Graph*>(std::string("TB")));
write_graphviz_dp(dot_file, g, dp);
std::string o_arg = "-o" +file_path+".png";
std::string i_arg = file_path+".dot";
char* args[] = {const_cast<char*>("dot"),
const_cast<char*>("-Tpng"),
const_cast<char*>(i_arg.c_str()),
const_cast<char*>(o_arg.c_str()) };
const int argc = sizeof(args)/sizeof(args[0]);
Agraph_t *h, *prev = NULL;
GVC_t *gvc;
gvc = gvContext();
gvParseArgs(gvc, argc, args);
while ((h = gvNextInputGraph(gvc)))
{
if (prev)
{
gvFreeLayout(gvc, prev);
agclose(prev);
}
gvLayoutJobs(gvc, h);
gvRenderJobs(gvc, h);
prev = h;
}
}
但是,对于多图,如果我再次调用这个函数,它不起作用并且我有一个分割错误。事实上,我们在一个应用程序中只能使用一个 GVC_t,在以下文档第 25 页中写道:http://www.graphviz.org/pdf/libguide.pdf.
因此在以下情况下,它会停止程序并出现段错误:
printGraphDot( g1, file_path1);
printGraphDot( g2, file_path2);
是否有另一种方法可以在不使用命令的情况下从 C++ 应用程序中的点文件生成 png 图形?
非常感谢您的帮助。 干杯
我找到了一种方法,我使用了以下函数并且它起作用了,我也在
bool saveImageGV(std::string file_path){
GVC_t *gvc;
Agraph_t *g;
FILE *fp;
gvc = gvContext();
fp = fopen((file_path+".dot").c_str(), "r");
g = agread(fp, 0);
gvLayout(gvc, g, "dot");
gvRender(gvc, g, "png", fopen((file_path+".png").c_str(), "w"));
gvFreeLayout(gvc, g);
agclose(g);
return (gvFreeContext(gvc));
}