Сгенерировать изображение графика 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));
}
Другие вопросы по тегам