Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
circular.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <circogen/circular.h>
12#include <circogen/blocktree.h>
13#include <circogen/circpos.h>
14#include <util/agxbuf.h>
15
16#define MINDIST 1.0
17
18/* Set attributes based on original root graph.
19 * This is obtained by taking a node of g, finding its node
20 * in the original graph, and finding that node's graph.
21 */
22static void initGraphAttrs(Agraph_t * g, circ_state * state)
23{
24 node_t *n = agfstnode(g);
25
26 Agraph_t *rootg = agraphof(ORIGN(n));
27 attrsym_t *G_mindist = agattr(rootg, AGRAPH, "mindist", NULL);
28 attrsym_t *N_root = agattr(rootg, AGNODE, "root", NULL);
29 char *rootname = agget(rootg, "root");
30 initBlocklist(&state->bl);
31 state->orderCount = 1;
32 state->min_dist = late_double(rootg, G_mindist, MINDIST, 0.0);
33 state->N_root = N_root;
34 state->rootname = rootname;
35}
36
37static block_t*
39{
40 Agraph_t *subg;
41 agxbuf name = {0};
42 block_t *bp;
43 Agnode_t* n;
44
45 agxbprint(&name, "_block_%d", state->blockCount++);
46 subg = agsubg(g, agxbuse(&name), 1);
47 agxbfree(&name);
48 bp = mkBlock(subg);
49
50 for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
51 agsubnode(bp->sub_graph, n, 1);
52 BLOCK(n) = bp;
53 }
54
55 return bp;
56}
57
58/* Do circular layout of g.
59 * Assume g is strict.
60 * g is a "connected" component of the derived graph of the
61 * original graph.
62 * We make state static so that it keeps a record of block numbers used
63 * in a graph; it gets reset when a new root graph is used.
64 */
65void circularLayout(Agraph_t *g, Agraph_t *realg, int *blockCount) {
66 block_t *root;
67
68 if (agnnodes(g) == 1) {
69 Agnode_t *n = agfstnode(g);
70 ND_pos(n)[0] = 0;
71 ND_pos(n)[1] = 0;
72 return;
73 }
74
75 circ_state state = {.blockCount = *blockCount};
76 initGraphAttrs(g, &state);
77
78 if (mapbool(agget(realg, "oneblock")))
79 root = createOneBlock(g, &state);
80 else
81 root = createBlocktree(g, &state);
82 circPos(g, root, &state);
83
84 /* cleanup:
85 * We need to cleanup objects created in initGraphAttrs
86 * and all blocks. All graph objects are components of the
87 * initial derived graph and will be freed when it is closed.
88 */
89 freeBlocktree(root);
90
91 *blockCount = state.blockCount;
92}
93
94#ifdef DEBUG
95void prGraph(Agraph_t * g)
96{
97 Agnode_t *n;
98 Agedge_t *e;
99
100 fprintf(stderr, "%s\n", agnameof(g));
101 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
102 fprintf(stderr, "%s (%p)\n", agnameof(n), n);
103 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
104 fprintf(stderr, "%s", agnameof(n));
105 fprintf(stderr, " -- %s (%p)\n", agnameof(aghead(e)), e);
106 }
107 }
108}
109
110void prData(Agnode_t * n, int pass)
111{
112 char *pname;
113 char *bname;
114 char *tname;
115 char *name1;
116 char *name2;
117 int dist1, dist2;
118
119 if (PARENT(n))
120 pname = agnameof(PARENT(n));
121 else
122 pname = "<P0>";
123 if (BLOCK(n))
124 bname = agnameof(BLOCK(n)->sub_graph);
125 else {
126 pname = "<B0>";
127 bname = "";
128 }
129 fprintf(stderr, "%s: %x %s %s ", agnameof(n), FLAGS(n), pname, bname);
130 switch (pass) {
131 case 0:
132 fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n));
133 break;
134 case 1:
135 if (TPARENT(n))
136 tname = agnameof(TPARENT(n));
137 else
138 tname = "<ROOT>";
139 dist1 = DISTONE(n);
140 if (dist1 > 0)
141 name1 = agnameof(LEAFONE(n));
142 else
143 name1 = "<null>";
144 dist2 = DISTTWO(n);
145 if (dist2 > 0)
146 name2 = agnameof(LEAFTWO(n));
147 else
148 name2 = "<null>";
149 fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2,
150 dist2);
151 break;
152 default:
153 fprintf(stderr, "%d\n", POSITION(n));
154 break;
155 }
156}
157#endif
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
static Agraph_t * mkBlock(Agraph_t *g, bcstate *stp)
Definition bcomps.c:140
void initBlocklist(blocklist_t *bl)
Definition block.c:17
block_t * createBlocktree(Agraph_t *g, circ_state *state)
Definition blocktree.c:140
void freeBlocktree(block_t *bp)
Definition blocktree.c:178
void circPos(Agraph_t *g, block_t *sn, circ_state *state)
Definition circpos.c:423
static block_t * createOneBlock(Agraph_t *g, circ_state *state)
Definition circular.c:38
#define MINDIST
Definition circular.c:16
void circularLayout(Agraph_t *g, Agraph_t *realg, int *blockCount)
Definition circular.c:65
static void initGraphAttrs(Agraph_t *g, circ_state *state)
Definition circular.c:22
#define BLOCK(n)
Definition circular.h:85
#define LOWVAL(n)
Definition circular.h:88
#define FLAGS(n)
Definition circular.h:83
#define LEAFONE(n)
Definition circular.h:91
#define POSITION(n)
Definition circular.h:95
#define ORIGN(n)
Definition circular.h:82
#define DISTONE(n)
Definition circular.h:93
#define PARENT(n)
Definition circular.h:84
#define DISTTWO(n)
Definition circular.h:94
#define VAL(n)
Definition circular.h:87
#define TPARENT(n)
Definition circular.h:90
#define LEAFTWO(n)
Definition circular.h:92
bool mapbool(const char *p)
Definition utils.c:335
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
Definition utils.c:48
node NULL
Definition grammar.y:163
int agnnodes(Agraph_t *g)
Definition graph.c:169
Agsym_t * agattr(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up attributes of a graph
Definition attr.c:338
char * agget(void *obj, char *name)
Definition attr.c:439
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
Agnode_t * agsubnode(Agraph_t *g, Agnode_t *n, int createflag)
Definition node.c:259
#define ND_pos(n)
Definition types.h:520
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
@ AGNODE
Definition cgraph.h:207
@ AGRAPH
Definition cgraph.h:207
Agraph_t * agsubg(Agraph_t *g, char *name, int cflag)
Definition subg.c:58
PATHUTIL_API COORD dist2(Ppoint_t, Ppoint_t)
Definition visibility.c:120
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
Definition block.h:26
Agraph_t * sub_graph
Definition block.h:29
double min_dist
Definition circular.h:24
int orderCount
Definition circular.h:18
char * rootname
Definition circular.h:23
int blockCount
Definition circular.h:19
attrsym_t * N_root
Definition circular.h:22
blocklist_t bl
Definition circular.h:17