cgraph 库生成具有 html 标签属性的点文件?

cgraph library generate dot file with html label attributes?

我正在使用 graphviz cgraph 库在 macbook 上生成一个点文件。

这是 c:

中的一个简单例子
#include "graphviz/cgraph.h"
#include <stdio.h>

int main(void) {
  Agraph_t *g = agopen("Graph", Agdirected, NULL);
  Agsym_t *s = agattr(g, AGNODE, "shape", "record");
  Agnode_t *n = agnode(g, "case", TRUE);
  char *l = "<<TABLE><TR><TD>Integer</TD></TR></TABLE>>";
  agset(n, "label", agstrdup_html(g, l));
  FILE *fp = fopen("test.dot", "w");
  agwrite(g, fp);
  fclose(fp);
  agclose(g);
  return 0;
}

clang test.c -o test.exe -lcgraph 编译,我希望它的输出点文件包含:

digraph {
  node [shape=record];
  case [label=<<TABLE><TR><TD>Integer</TD></TR></TABLE>>];

但它给了我:

digraph "Graph" {
    node [shape=record];
    case;
}

我该如何解决?

您需要先定义属性 label,然后才能将其分配给节点。来自 Graphviz 发行版(第 11 页)中包含的 CGraph 文档:

Setting attributes is a bit more complex. Before attaching an attribute to a graph component, the code must first set up the default case. This is accomplished by a call to agattr. It takes a graph, an object type (AGRAPH, AGNODE, AGEDGE), and two strings as arguments, and return a representation of the attribute. The first string gives the name of the attribute; the second supplies the default value. The graph must be the root graph.

即使对于通常由 Graphviz 定义的属性也是如此,因为 CGraph 库是一个独立的组件。在许多用例中(包括 Graphviz 文档中的用例),图是从基础图初始化的。使用 agread 读取和解析基础图通常会填充标准属性,因此可能并不总是需要使用 agattr。但在这种情况下,您是从头开始定义图表,因此您需要定义所有属性,甚至 label.

我对你的代码做了一些修改;请参阅下面的评论以获取解释。

#include "graphviz/cgraph.h"
#include <stdio.h>

int main(void) {
  Agraph_t *g = agopen("Graph", Agdirected, NULL);
  Agsym_t *attr_shape = agattr(g, AGNODE, "shape", "record");
  /* The following is needed before you can use attribute label */
  Agsym_t *attr_label = agattr(g, AGNODE, "label", "");
  Agnode_t *n = agnode(g, "case", TRUE);
  /* Fixed the label. The outer angle brackets are part of the Graphviz
   * syntax, not part of the label's value. (Just like quotes for normal
   * labels, as the Graphviz documentation says.)
   */
  char *label = "<TABLE><TR><TD>Integer</TD></TR></TABLE>";
  /* Changed agset to agxset since we have the attribute's descriptor.
   * The agset call would have worked, too, but this is a tad more efficient.
   */
  agxset(n, attr_label, agstrdup_html(g, label));
  agwrite(g, stdout);
  agclose(g);
  return 0;
}

这会产生: