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;
}
这会产生:
我正在使用 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;
}
这会产生: