Сгенерировать изображение графика GraphViz с учетом точечного текста C++
У меня есть строка в приложении C++ Qt (в Ubuntu), которая содержит правильный синтаксис GraphViz/dot graph. Я хочу сгенерировать файл изображения / объект из этого текста, аналогично изображениям, которые выкладываются различными онлайн-инструментами (например, http://www.webgraphviz.com/). Может быть, я использую неправильные условия поиска, но не могу найти соответствующую помощь в этом.
Что я в основном хочу, это что-то вроде этого:
generate_dot_graph_image(std::string dot_text, std::string image_file_path)
Дополнительные детали: у меня есть решатель Дейкстры, решение которого (в основном исходный график после удаления неиспользуемых ребер) я хочу визуализировать внутри своего приложения. У решателя уже есть опция для преобразования решения в строку, которую можно проанализировать как точечный граф с помощью утилиты, такой как та, которую я связал выше. Но я хочу иметь возможность делать это изнутри C++.
2 ответа
Так что я смог сделать именно то, что хотел, используя библиотеки GraphViz. Вы можете установить их на Ubuntu, используя sudo apt-get install graphviz-lib
а также sudo apt-get install libgraphviz-dev
, Как только это будет сделано:
#include <graphviz/gvc.h>
bool DotGraphGenerator::saveImage()
{
std::string o_arg = std::string("-o") + "/path/to/image_file.png";
char* args[] = {const_cast<char*>("dot"), const_cast<char*>("Tpng"), const_cast<char*>("-Gsize=8,4!"), const_cast<char*>("-Gdpi=100"),
const_cast<char*>(DOT_TEXT_FILE.c_str()), //DOT_TEXT_FILE is the file path in which the graph is saved as valid DOT syntax
const_cast<char*>(o_arg.c_str()) };
const int argc = sizeof(args)/sizeof(args[0]);
Agraph_t *g, *prev = NULL;
GVC_t *gvc;
gvc = gvContext();
gvParseArgs(gvc, argc, args);
while ((g = gvNextInputGraph(gvc)))
{
if (prev)
{
gvFreeLayout(gvc, prev);
agclose(prev);
}
gvLayoutJobs(gvc, g);
gvRenderJobs(gvc, g);
prev = g;
}
return !gvFreeContext(gvc);
}
gvc - это библиотека C, и функции принимают в качестве аргументов неконстантные строки C, поэтому вначале const_casts. Вы также можете редактировать размер изображения, изменив -Gsize=8,4
а также -Gdpi=100
арг. В текущей конфигурации вы получите файл изображения 8*100 x 4*100 = 800x400. В любом случае, эти аргументы такие же, как и при запуске dot
команда от Баш.
Кроме этого, этот код в основном скопирован из одного из примеров в GraphViz в виде руководства для библиотеки: http://www.graphviz.org/pdf/libguide.pdf
Я нашел способ, я использовал следующую функцию, и она работает:
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));
}