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