/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/circogen/circular.c

Go to the documentation of this file.
00001 /* $Id: circular.c,v 1.1.1.1 2004/12/23 04:04:29 ellson Exp $ $Revision: 1.1.1.1 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include    "circular.h"
00019 #include    "blocktree.h"
00020 #include    "circpos.h"
00021 #include        <string.h>
00022 
00023 #define         MINDIST                 1.0
00024 
00025 /* initGraphAttrs:
00026  * Set attributes based on original root graph.
00027  * This is obtained by taking a node of g, finding its node
00028  * in the original graph, and finding that node's graph.
00029  */
00030 static void initGraphAttrs(Agraph_t * g, circ_state * state)
00031 {
00032     static Agraph_t *rootg;
00033     static attrsym_t *N_artpos;
00034     static attrsym_t *N_root;
00035     static double min_dist;
00036     static char *rootname;
00037     Agraph_t *rg;
00038     attrsym_t *G_mindist;
00039     node_t *n = agfstnode(g);
00040 
00041     rg = ORIGN(n)->graph;
00042     if (rg != rootg) {          /* new root graph */
00043         state->blockCount = 0;
00044         rootg = rg;
00045         G_mindist = agfindattr(rootg, "mindist");
00046         min_dist = late_double(rootg, G_mindist, MINDIST, 0.0);
00047         N_artpos = agfindattr(rootg->proto->n, "articulation_pos");
00048         N_root = agfindattr(rootg->proto->n, "root");
00049         rootname = agget(rootg, "root");
00050     }
00051     initBlocklist(&state->bl);
00052     state->orderCount = 1;
00053     state->bcstack = mkStack();
00054     state->min_dist = min_dist;
00055     state->N_artpos = N_artpos;
00056     state->N_root = N_root;
00057     state->rootname = rootname;
00058 }
00059 
00060 /* cleanup:
00061  * We need to cleanup objects created in initGraphAttrs
00062  * and all blocks. All graph objects are components of the
00063  * initial derived graph and will be freed when it is closed. 
00064  */
00065 static void cleanup(block_t * root, circ_state * sp)
00066 {
00067     freeBlocktree(root);
00068     freeStack(sp->bcstack);
00069 }
00070 
00071 /* circularLayout:
00072  * Do circular layout of g.
00073  * Assume g is strict.
00074  * g is a "connected" component of the derived graph of the
00075  * original graph.
00076  * We make state static so that it keeps a record of block numbers used
00077  * in a graph; it gets reset when a new root graph is used.
00078  */
00079 void circularLayout(Agraph_t * g)
00080 {
00081     block_t *root;
00082     static circ_state state;
00083 
00084     if (agnnodes(g) == 1) {
00085         Agnode_t *n = agfstnode(g);
00086         ND_pos(n)[0] = 0;
00087         ND_pos(n)[1] = 0;
00088         return;
00089     }
00090 
00091     initGraphAttrs(g, &state);
00092 
00093     root = createBlocktree(g, &state);
00094     circPos(g, root, &state);
00095 
00096     cleanup(root, &state);
00097 }
00098 
00099 #ifdef DEBUG
00100 void prGraph(Agraph_t * g)
00101 {
00102     Agnode_t *n;
00103     Agedge_t *e;
00104 
00105     fprintf(stderr, "%s\n", g->name);
00106     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00107         fprintf(stderr, "%s (%x)\n", n->name, (unsigned int) n);
00108         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00109             fprintf(stderr, "%s -- %s (%x)\n", n->name, e->head->name,
00110                     (unsigned int) e);
00111         }
00112     }
00113 }
00114 
00115 cdata *cvt(Agnode_t * n)
00116 {
00117     return DATA(n);
00118 }
00119 
00120 void prData(Agnode_t * n, int pass)
00121 {
00122     char *pname;
00123     char *bname;
00124     char *tname;
00125     char *name1;
00126     char *name2;
00127     int dist1, dist2;
00128 
00129     if (PARENT(n))
00130         pname = PARENT(n)->name;
00131     else
00132         pname = "<P0>";
00133     if (BLOCK(n))
00134         bname = BLOCK(n)->sub_graph->name;
00135     else
00136         pname = "<B0>";
00137     fprintf(stderr, "%s: %x %s %s ", n->name, FLAGS(n), pname, bname);
00138     switch (pass) {
00139     case 0:
00140         fprintf(stderr, "%d %d\n", VAL(n), LOWVAL(n));
00141         break;
00142     case 1:
00143         if (TPARENT(n))
00144             tname = TPARENT(n)->name;
00145         else
00146             tname = "<ROOT>";
00147         dist1 = DISTONE(n);
00148         if (dist1 > 0)
00149             name1 = LEAFONE(n)->name;
00150         else
00151             name1 = "<null>";
00152         dist2 = DISTTWO(n);
00153         if (dist2 > 0)
00154             name2 = LEAFTWO(n)->name;
00155         else
00156             name2 = "<null>";
00157         fprintf(stderr, "%s %s %d %s %d\n", tname, name1, dist1, name2,
00158                 dist2);
00159         break;
00160     default:
00161         fprintf(stderr, "%d\n", POSITION(n));
00162         break;
00163     }
00164 }
00165 #endif

Generated on Mon Mar 31 19:03:23 2008 for Graphviz by  doxygen 1.5.1