void do_graph_label(graph_t* g) { char *p, *pos; int pos_ix; /* it would be nice to allow multiple graph labels in the future */ if ((p = agget(g,"label"))) { g->u.label = make_label(p, late_float(g,agfindattr(g,"fontsize"),DEFAULT_FONTSIZE,MIN_FONTSIZE), late_nnstring(g,agfindattr(g,"fontname"),DEFAULT_FONTNAME), late_nnstring(g,agfindattr(g,"fontcolor"),DEFAULT_COLOR),g); pos = agget(g,"labelloc"); if (!g->u.left_to_right) { if (!pos || (pos[0] != 'b')) pos_ix = TOP_IX; else pos_ix = BOTTOM_IX; g->u.border[pos_ix] = cvt2pt(g->u.label->dimen); } else { /* when rotated, the labels will be restored to TOP or BOTTOM */ if (!pos || (pos[0] != 'b')) pos_ix = RIGHT_IX; else pos_ix = LEFT_IX; g->u.border[pos_ix].x = g->u.label->dimen.y; g->u.border[pos_ix].y = g->u.label->dimen.x; } } }
void agwredge(Agraph_t * g, FILE * fp, Agedge_t * e, int list_all) { char *myval, *defval, *tport, *hport; int i, nprint = 0; Agdict_t *d = e->tail->graph->univ->edgeattr; Agsym_t *a; if (e->attr) { tport = e->attr[TAILX]; hport = e->attr[HEADX]; } else tport = hport = ""; writenodeandport(fp, e->tail->name, tport); agputs(((g->kind & AGFLAG_DIRECTED) ? " -> " : " -- "), fp); writenodeandport(fp, e->head->name, hport); if (list_all) { for (i = 0; i < dtsize(d->dict); i++) { a = d->list[i]; if ((a->printed == FALSE) || ((i == KEYX) && (e->printkey != MUSTPRINT))) continue; myval = agget(e, a->name); if (g == g->root) defval = a->value; else defval = agget(g->proto->e, a->name); if (strcmp(defval, myval)) writeattr(fp, &nprint, a->name, myval); } } agputs(nprint > 0 ? "];\n" : ";\n", fp); }
static char *getPenColor(void *obj) { char *str; if (((str = agget(obj, "pencolor")) != 0) && str[0]) return str; else if (((str = agget(obj, "color")) != 0) && str[0]) return str; else return NULL; }
static aspect_t* setAspect (Agraph_t * g, aspect_t* adata) { double rv; char *p; int r, passes = DEF_PASSES; p = agget (g, "aspect"); if (!p || ((r = sscanf (p, "%lf,%d", &rv, &passes)) <= 0)) { adata->nextIter = 0; adata->badGraph = 0; return NULL; } if (rv < MIN_AR) rv = MIN_AR; else if (rv > MAX_AR) rv = MAX_AR; adata->targetAR = rv; adata->nextIter = -1; adata->nPasses = passes; adata->badGraph = 0; if (Verbose) fprintf(stderr, "Target AR = %g\n", adata->targetAR); return adata; }
/* emit_html_label: */ void emit_html_label(GVJ_t * job, htmllabel_t * lp, textlabel_t * tp) { htmlenv_t env; allocObj (job); env.pos = tp->pos; env.finfo.color = tp->fontcolor; env.finfo.name = tp->fontname; env.finfo.size = tp->fontsize; env.finfo.size = tp->fontsize; env.imgscale = agget (job->obj->u.n, "imagescale"); env.objid = job->obj->id; env.objid_set = 0; if ((env.imgscale == NULL) || (env.imgscale[0] == '\0')) env.imgscale = "false"; if (lp->kind == HTML_TBL) { htmltbl_t *tbl = lp->u.tbl; /* set basic graphics context */ /* Need to override line style set by node. */ gvrender_set_style(job, job->gvc->defaultlinestyle); if (tbl->data.pencolor) gvrender_set_pencolor(job, tbl->data.pencolor); else gvrender_set_pencolor(job, DEFAULT_COLOR); emit_html_tbl(job, tbl, &env); } else { emit_html_txt(job, lp->u.txt, &env); } if (env.objid_set) free (env.objid); freeObj (job); }
/* tuneControl: * Use user values to reset control * * Possible parameters: * ctrl->use_node_weights */ static void tuneControl (graph_t* g, spring_electrical_control ctrl) { long seed; int init; seed = ctrl->random_seed; init = setSeed (g, INIT_RANDOM, &seed); if (init != INIT_RANDOM) { agerr(AGWARN, "sfdp only supports start=random\n"); } ctrl->random_seed = seed; ctrl->K = late_double(g, agfindgraphattr(g, "K"), -1.0, 0.0); ctrl->p = -1.0*late_double(g, agfindgraphattr(g, "repulsiveforce"), -AUTOP, 0.0); ctrl->multilevels = late_int(g, agfindgraphattr(g, "levels"), INT_MAX, 0); ctrl->smoothing = late_smooth(g, agfindgraphattr(g, "smoothing"), SMOOTHING_NONE); ctrl->tscheme = late_quadtree_scheme(g, agfindgraphattr(g, "quadtree"), QUAD_TREE_NORMAL); /* ctrl->method = late_mode(g, agfindgraphattr(g, "mode"), METHOD_SPRING_ELECTRICAL); */ ctrl->method = METHOD_SPRING_ELECTRICAL; ctrl->beautify_leaves = mapBool (agget(g, "beautify"), FALSE); ctrl->rotation = late_double(g, agfindgraphattr(g, "rotation"), 0.0, -MAXDOUBLE); ctrl->edge_labeling_scheme = late_int(g, agfindgraphattr(g, "label_scheme"), 0, 0); if (ctrl->edge_labeling_scheme > 4) { agerr (AGWARN, "label_scheme = %d > 4 : ignoring\n", ctrl->edge_labeling_scheme); ctrl->edge_labeling_scheme = 0; } }
/* * Generic object newindex metamethod handler. * Lua Stack: ud, key, value */ int object_newindex_handler(lua_State *L) { char sskey[16], *skey; if ((!lua_isstring(L, 2)) || (!lua_isstring(L, 3))){ gr_object_t *ud = toobject(L, 1, NULL, STRICT); skey = agget(ud->p.p, ".attrib"); if (!skey || (strlen(skey) == 0)){ /* Let's create an attrib table on the fly if none exists */ sprintf(sskey, "%p", ud->p.p); skey = agstrdup(sskey); agset(ud->p.p, ".attrib", skey); lua_pushstring(L, skey); /* ud, key, value, skey */ lua_newtable(L); /* ud, key, value, skey, stab */ lua_rawset(L, LUA_REGISTRYINDEX); /* ud, key, value, */ } lua_pushstring(L, skey); /* ud, key, value, skey */ lua_rawget(L, LUA_REGISTRYINDEX); /* ud, key, value, stab */ lua_pushvalue(L, 2); /* ud, key, value, stab, key */ lua_pushvalue(L, 3); /* ud, key, value, stab, key, value */ lua_rawset(L, -3); /* ud, key, value, stab */ lua_pop(L, -1); /* ud, key, value */ return 0; } return setval(L); }
int main() { FILE * fp = fopen("test", "r"); assert(fp); Agraph_t * graph = agread(fp, NULL); assert(graph); printf("Number of nodes is %d\n", agnnodes(graph)); printf("Number of edges is %d\n", agnedges(graph)); /* Iterate through nodes */ Agnode_t * node = agfstnode(graph); while (node != NULL) { assert(node); printf("Iterating through yet another node\n"); char * label = agget(node, "label"); printf("Node label is %s\n", label); Agedge_t * edge = agfstout(graph, node); while (edge != NULL) { assert(edge); printf("Iterating through yet another edge \n"); assert(agtail(edge) == node); edge = agnxtout(graph, edge); } /* Move on to the next node */ printf("\n"); node = agnxtnode(graph, node); } /* Free graph structure */ agclose(graph); return 0; }
static void svg_begin_job(GVJ_t * job) { char *s; gvputs(job, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); if ((s = agget(job->gvc->g, "stylesheet")) && s[0]) { gvputs(job, "<?xml-stylesheet href=\""); gvputs(job, s); gvputs(job, "\" type=\"text/css\"?>\n"); } #if 0 gvputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"); gvputs(job, " \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\""); /* This is to work around a bug in the SVG 1.0 DTD */ gvputs(job, " [\n <!ATTLIST svg xmlns:xlink CDATA #FIXED \"http://www.w3.org/1999/xlink\">\n]"); #else gvputs(job, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"); gvputs(job, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); #endif gvputs(job, "<!-- Generated by "); gvputs(job, xml_string(job->common->info[0])); gvputs(job, " version "); gvputs(job, xml_string(job->common->info[1])); gvputs(job, " ("); gvputs(job, xml_string(job->common->info[2])); gvputs(job, ")\n"); gvputs(job, " -->\n"); }
/* * John M. suggests: * You might want to add four more: * * _ohdraw_ (optional head-end arrow for edges) * _ohldraw_ (optional head-end label for edges) * _otdraw_ (optional tail-end arrow for edges) * _otldraw_ (optional tail-end label for edges) * * that would be generated when an additional option is supplied to * dot, etc. and * these would be the arrow/label positions to use if a user want to flip the * direction of an edge (as sometimes is there want). * * N.B. John M. asks: * By the way, I don't know if you ever plan to add other letters for * the xdot spec, but could you reserve "a" and also "A" (for attribute), * "n" and also "N" (for numeric), "w" (for sWitch), "s" (for string) * and "t" (for tooltip) and "x" (for position). We use those letters in * our drawing spec (and also "<" and ">"), so if you start generating * output with them, it could break what we have. */ static void xdot_begin_graph (graph_t *g, int s_arrows, int e_arrows, format_type id) { int i, us; char* s; xd = GNEW(xdot_state_t); if (id == FORMAT_XDOT14) { xd->version = 14; xd->version_s = "1.4"; } else if (id == FORMAT_XDOT12) { xd->version = 12; xd->version_s = "1.2"; } else if ((s = agget(g, "xdotversion")) && s[0] && ((us = versionStr2Version(s)) > 10)) { xd->version = us; xd->version_s = s; } else { xd->version = versionStr2Version(XDOTVERSION); xd->version_s = XDOTVERSION; } if (GD_n_cluster(g)) #ifndef WITH_CGRAPH xd->g_draw = safe_dcl(g, g, "_draw_", "", agraphattr); #else xd->g_draw = safe_dcl(g, AGRAPH, "_draw_", ""); #endif else
QString QGVSubGraph::getAttribute(const QString &name) const { char* value = agget(_sgraph->graph(), name.toLocal8Bit().data()); if(value) return value; return QString(); }
QString QGVEdge::getAttribute(const QString &name) const { char* value = agget(_edge->edge(), name.toLocal8Bit().data()); if(value) return value; return QString(); }
static inline QString _agget(void *object, QString attr, QString alt=QString()){ setlocale(LC_NUMERIC,"en_US.UTF-8"); QString str = agget(object, const_cast<char *>(qPrintable(attr))); if(str==QString()) return alt; else return str; }
/** Determine the current active state. * Note that there might be multiple active states if there are sub-fsms. It will * only consider the active state of the bottom-fsm. * @return the current active state */ std::string SkillGuiGraphDrawingArea::get_active_state(graph_t *graph) { if (! graph) { return ""; } // Loop through the nodes in the graph/subgraph and find the active node for (node_t *n = agfstnode(graph); n; n = agnxtnode(graph, n)) { const char *actattr = agget(n, (char *)"active"); if (actattr && (strcmp(actattr, "true") == 0) ) { node_t *mn = agmetanode(graph); graph_t *mg = mn->graph; // Check to see if the node has an edge going into a subgraph for (edge_t *me = agfstout(mg, mn); me; me = agnxtout(mg, me)) { graph_t *subgraph = agusergraph(me->head); for (edge_t *e = agfstout(graph, n); e; e = agnxtout(graph, e)) { for (node_t *subnode = agfstnode(subgraph); subnode; subnode = agnxtnode(subgraph, subnode)) { if (agnameof(subnode) == agnameof(e->head)) { // The node goes into a subgraph, recursively find and return the active subnode name return get_active_state(subgraph); } } } } // The node has no subgraph, return the name of the active node return agnameof(n); } } return ""; }
/* getdoubles2ptf: * converts a graph attribute in inches to a pointf in points. * If only one number is given, it is used for both x and y. * Returns true if the attribute ends in '!'. */ static boolean getdoubles2ptf(graph_t * g, char *name, pointf * result) { char *p; int i; double xf, yf; char c = '\0'; boolean rv = FALSE; if ((p = agget(g, name))) { i = sscanf(p, "%lf,%lf%c", &xf, &yf, &c); if ((i > 1) && (xf > 0) && (yf > 0)) { result->x = POINTS(xf); result->y = POINTS(yf); if (c == '!') rv = TRUE; } else { c = '\0'; i = sscanf(p, "%lf%c", &xf, &c); if ((i > 0) && (xf > 0)) { result->y = result->x = POINTS(xf); if (c == '!') rv = TRUE; } } } return rv; }
/* initGraphAttrs: * Set attributes based on original root graph. * This is obtained by taking a node of g, finding its node * in the original graph, and finding that node's graph. */ static void initGraphAttrs(Agraph_t * g, circ_state * state) { static Agraph_t *rootg; static attrsym_t *N_artpos; static attrsym_t *N_root; static attrsym_t *G_mindist; static char *rootname; Agraph_t *rg; node_t *n = agfstnode(g); rg = agraphof(ORIGN(n)); if (rg != rootg) { /* new root graph */ state->blockCount = 0; rootg = rg; G_mindist = agattr(rootg,AGRAPH, "mindist", NULL); N_artpos = agattr(rootg,AGNODE, "articulation_pos", NULL); N_root = agattr(rootg,AGNODE, "root", NULL); } rootname = agget(rootg, "root"); initBlocklist(&state->bl); state->orderCount = 1; state->min_dist = late_double(rootg, G_mindist, MINDIST, 0.0); state->N_artpos = N_artpos; state->N_root = N_root; state->rootname = rootname; }
aresta_t add_aresta(grafo g, vertice_t v, Agnode_t *v_cgraph, Agedge_t *a){ aresta_t nova_aresta; Agnode_t * vertice_dest; char *peso; // aloca aresta nova_aresta = (aresta_t) malloc(sizeof(struct aresta_t)); // insere aresta na fila nova_aresta->next = v->aresta; v->aresta = nova_aresta; // seta peso peso = agget(a, (char *)"peso"); if ( peso && *peso ) { nova_aresta->peso = atof(peso); g->peso = 1; } else nova_aresta->peso = PESO_DEFAULT; // seta ponteiro da aresta para vertice if (!strcmp(agnameof(v_cgraph), agnameof(aghead(a))) ) vertice_dest = agtail(a); else vertice_dest = aghead(a); nova_aresta->vertice = get_vertice(vertice_dest); return nova_aresta; }
/* setRatio: * Checks "ratio" attribute, if any, and sets enum type. */ static void setRatio(graph_t * g) { char *p, c; double ratio; if ((p = agget(g, "ratio")) && ((c = p[0]))) { switch (c) { case 'a': if (streq(p, "auto")) GD_drawing(g)->ratio_kind = R_AUTO; break; case 'c': if (streq(p, "compress")) GD_drawing(g)->ratio_kind = R_COMPRESS; break; case 'e': if (streq(p, "expand")) GD_drawing(g)->ratio_kind = R_EXPAND; break; case 'f': if (streq(p, "fill")) GD_drawing(g)->ratio_kind = R_FILL; break; default: ratio = atof(p); if (ratio > 0.0) { GD_drawing(g)->ratio_kind = R_VALUE; GD_drawing(g)->ratio = ratio; } break; } } }
static void gd_begin_graph_to_file(graph_t* g, box bb, point pb) { char *truecolor_p; gd_begin_graph(g, bb, pb); if (Verbose) fprintf(stderr,"%s: allocating a %dK GD image\n", CmdName, ROUND( Viewport.x * Viewport.y / 1024. )); truecolor_p = agget(g,"truecolor"); /* automatically decide color mode if "truecolor" not specified */ if (truecolor_p == NULL || *truecolor_p == '\0') { truecolor_p="false"; /* indexed color maps unless ... */ if (agfindattr(g->proto->n, "shapefile")) { /* ... custom shapefiles are used */ truecolor_p = "true"; } } if (mapbool(truecolor_p)) im = gdImageCreateTrueColor(Viewport.x, Viewport.y); else im = gdImageCreate(Viewport.x, Viewport.y); init_gd(); #ifdef MYTRACE fprintf(stderr,"gd_begin_graph_to_file\n"); #endif }
/* Execute union commands for "same rank" subgraphs and clusters. */ static void collapse_sets(graph_t *rg, graph_t *g) { int c; graph_t *subg; #ifdef OBSOLETE node_t *n; #endif for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { c = rank_set_class(subg); if (c) { if ((c == CLUSTER) && CL_type == LOCAL) collapse_cluster(rg, subg); else collapse_rankset(rg, subg, c); } else collapse_sets(rg, subg); #ifdef OBSOLETE Collapsing leaves is currently obsolete /* mark nodes with ordered edges so their leaves are not collapsed */ if (agget(subg, "ordering")) for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) ND_order(n) = 1; #endif } }
int main(int argc, char* argv[]) { if(argc != 3) usage(); float scale = atof(argv[1]); FILE* fin = fopen(argv[2],"r"); Agraph_t* g = agread(fin, (Agdisc_t*)NULL); Agnode_t* n; for(n = agfstnode(g); n; n = agnxtnode(g,n)) { char* pos = agget(n,"pos"); double x,y; sscanf(pos,"%lf,%lf",&x,&y); x *= scale; y *= scale; char* s = pos_to_str(x,y); agset(n,"pos",s); free(s); } agwrite(g,stdout); agclose(g); return 0; }
static void get_graph_node_attribute(Agraph_t* g, char *tag, char *format, size_t len, void *x_default_val, int *nn, void *x, int *flag){ /* read a node attribute. Example {real x0[2]; real *x = NULL; x0[0] = x0[1] = 0.; get_graph_node_attribute(g, "pos", "%lf,%lf", sizeof(real)*2, x0, &n, &x, &flag) or, do not supply x0 if you want error flagged when pos tag is not available: get_graph_node_attribute(g, "pos", "%lf,%lf", sizeof(real)*2, NULL, &n, x, &flag); assert(!flag); FREE(x); } */ Agnode_t* n; int nnodes; *flag = 0; if (!g) { *flag = -1; return; } nnodes = agnnodes (g); *nn = nnodes; for (n = agfstnode (g); n; n = agnxtnode (g, n)) { if (agget(n, tag)){ if (strcmp(format,"%s") == 0){ strcpy(x, agget(n, tag)); } else { sscanf(agget(n, tag), format, x); } } else if (x_default_val){ memcpy(x, x_default_val, len); } else { *flag = -1; return; } x += len; } }
static void scanXdotwithattr(void *p, char *attr) { xdot *xDot; if ((xDot = parseXDotF(agget(p, attr), OpFns, sizeof(sdot_op)))) { scanXdot(xDot, p); freeXDot(xDot); } }
SEXP Rgraphviz_doLayout(SEXP graph, SEXP layoutType, SEXP size) { /* Will perform a Graphviz layout on a graph */ Agraph_t *g; SEXP slotTmp, nLayout, cPoints, bb; /* Extract the Agraph_t pointer from the S4 object */ PROTECT(slotTmp = GET_SLOT(graph, install("agraph"))); CHECK_Rgraphviz_graph(slotTmp); g = R_ExternalPtrAddr(slotTmp); if (size != R_NilValue) { agsafeset(g, "size", CHAR(STRING_ELT(size, 0)), NULL); } /* Call the appropriate Graphviz layout routine */ gvLayout(gvc, g, CHAR(STRING_ELT(layoutType, 0))); /* if (!isInteger(layoutType)) error("layoutType must be an integer value"); else { gvLayout(gvc, g, layouts[INTEGER(layoutType)[0]]); } */ /* Here we want to extract information for the resultant S4 object */ PROTECT(nLayout = getNodeLayouts(g)); PROTECT(bb = getBoundBox(g)); PROTECT(cPoints = getEdgeLocs(g)); SET_SLOT(graph, Rf_install("agraph"), slotTmp); SET_SLOT(graph,Rf_install("AgNode"), nLayout); SET_SLOT(graph,Rf_install("laidout"), Rgraphviz_ScalarLogicalFromRbool(TRUE)); SET_SLOT(graph,Rf_install("AgEdge"), cPoints); SET_SLOT(graph,Rf_install("boundBox"), bb); SET_SLOT(graph,Rf_install("fg"), Rgraphviz_ScalarStringOrNull(agget(g, "fgcolor"))); SET_SLOT(graph,Rf_install("bg"), Rgraphviz_ScalarStringOrNull(agget(g, "bgcolor"))); UNPROTECT(4); /* free gvc after rendering */ gvFreeLayout(gvc, g); return(graph); }
void getdouble(graph_t* g, char* name, double* result) { char *p; double f; if ((p = agget(g,name))) { if (sscanf(p,"%lf",&f) >= 1) *result = f; } }
static void drawtopfishnodelabels(topview * t) { int v, finenodes, focusnodes; char buf[512]; char *str; Hierarchy *hp = t->fisheyeParams.h; finenodes = focusnodes = 0; str = agget(view->g[view->activeGraph], "topologicalfisheyelabelfinenodes"); if (strcmp(str, "1") == 0) { finenodes = 1; } str = agget(view->g[view->activeGraph], "topologicalfisheyelabelfocus"); if (strcmp(str, "1") == 0) { focusnodes = 1; } if ((finenodes) || (focusnodes)) { for (v = 0; v < hp->nvtxs[0]; v++) { ex_vtx_data *gg = hp->geom_graphs[0]; if (gg[v].active_level == 0) { if (view->Topview->Nodes[v].Label) strcpy(buf, view->Topview->Nodes[v].Label); else sprintf(buf, "%d", v); if ((v == t->fisheyeParams.fs->foci_nodes[0]) && (focusnodes)) { glColor4f((float) 0, (float) 0, (float) 1, (float) 1); glprintfglut(GLUT_BITMAP_HELVETICA_18, gg[v].physical_x_coord, gg[v].physical_y_coord, 0, buf); } else if (finenodes) { glColor4f(0, 0, 0, 1); glprintfglut(GLUT_BITMAP_HELVETICA_10, gg[v].physical_x_coord, gg[v].physical_y_coord, 0, buf); } } } } }
static long int get_peso(Agedge_t *Ae) { char p_str[5]; strcpy(p_str, "peso"); char *peso_c = agget(Ae, p_str); if (peso_c && *peso_c) return atol(peso_c); return 0; }
static void my_ins(Agobj_t * obj, void *context) { Agnode_t *n; if (AGTYPE(obj) == AGNODE) { n = (Agnode_t *) obj; fprintf(stderr, "%s initialized with label %s\n", agnameof(n), agget(n, "label")); } }
/* twopi_layout: */ void twopi_layout(Agraph_t * g) { Agnode_t *ctr = 0; char *s; twopi_init_graph(g); s = agget(g, "root"); if (s && (*s != '\0')) { ctr = agfindnode(g, s); if (!ctr) { agerr(AGWARN, "specified root node \"%s\" was not found.", s); agerr(AGPREV, "Using default calculation for root node\n"); } } if (agnnodes(g)) { Agraph_t **ccs; Agraph_t *sg; Agnode_t *c = NULL; int ncc; int i; ccs = ccomps(g, &ncc, 0); if (ncc == 1) { circleLayout(g, ctr); adjustNodes(g); spline_edges(g); } else { pack_info pinfo; pack_mode pmode = getPackMode(g, l_node); for (i = 0; i < ncc; i++) { sg = ccs[i]; if (ctr && agcontains(sg, ctr)) c = ctr; else c = 0; nodeInduce(sg); circleLayout(sg, c); adjustNodes(sg); } spline_edges(g); pinfo.margin = getPack(g, CL_OFFSET, CL_OFFSET); pinfo.doSplines = 1; pinfo.mode = pmode; pinfo.fixed = 0; packSubgraphs(ncc, ccs, g, &pinfo); } for (i = 0; i < ncc; i++) { agdelete(g, ccs[i]); } free(ccs); } dotneato_postprocess(g); }
void dot_rank(graph_t * g, aspect_t* asp) { if (agget (g, "newrank")) { GD_flags(g) |= NEW_RANK; dot2_rank (g, asp); } else dot1_rank (g, asp); if (Verbose) fprintf (stderr, "Maxrank = %d, minrank = %d\n", GD_maxrank(g), GD_minrank(g)); }