1

I have a string in a C++ Qt application (on Ubuntu) which contains valid GraphViz/dot graph syntax. I want to generate an image file/object from this text, similar to the images that various online tools (like this one: http://www.webgraphviz.com/) spit out. Maybe I'm using wrong search terms, but I can't seem to find relevant help with this.

What I basically want is something like this:

generate_dot_graph_image(std::string dot_text, std::string image_file_path)

Additional details: I have a Dijkstra solver whose solution (basically the original graph after removing non-used edges) I want to visualize inside my application. The solver already includes an option to convert the solution to a string that can be parsed as a dot graph using a utility such as the one I linked above. But what I want is to be able to do this from inside C++.

Ali250
  • 652
  • 1
  • 5
  • 19
  • I'm not sure what you want. Are you looking to invoke graphviz from a console app? Which os? From wxWidgets, QT, MFC and display in the application? – lakeweb Jul 20 '17 at 21:59
  • I'm working on a QT application in Linux (ubuntu). I have a solution from a DIjkstra solver as a dot graph (text string) that I want to visualize inside my application. For this I need to convert it to an image. – Ali250 Jul 20 '17 at 22:06
  • Added additional details to the original question. – Ali250 Jul 20 '17 at 22:10
  • Does [this](https://www.codeproject.com/Articles/1164156/WebControls/) help? – lakeweb Jul 21 '17 at 22:23

2 Answers2

3

So I was able to do exactly what I wanted using the GraphViz libraries. You can install them on Ubuntu using sudo apt-get install graphviz-lib and sudo apt-get install libgraphviz-dev. Once that's done:

#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 is a C library, and the functions take non-const C strings as arguments, hence the const_casts in the beginning. You can also edit the image size by altering the -Gsize=8,4 and -Gdpi=100 args. With the current configuration you'll get an 8*100 x 4*100 = 800x400 image file. Anyway, these arguments are the same as you would apply when running the dot command from bash.

Other than that, this code is basically copied from one of the examples in the graphViz as a library manual: http://www.graphviz.org/pdf/libguide.pdf

Ali250
  • 652
  • 1
  • 5
  • 19
3

I found a way, I used the following function and it works:

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));
}
froz
  • 163
  • 1
  • 12