static void cloneSubg (Agraph_t* parent, Agraph_t* sg, Dt_t* emap) { Agraph_t* subg; Agnode_t* t; Agedge_t* e; Agnode_t* newt; Agedge_t* newe; Agraph_t* newg; if (is_a_cluster(sg)) { newg = agsubg (parent, agnameof(sg), 1); parent = newg; for (t = agfstnode(sg); t; t = agnxtnode(sg, t)) { newt = agnode(newg, agnameof(t), 0); agsubnode(newg, newt, 1); /* if e is in sg, both end points are, so we can use out edges */ for (e = agfstout(sg, t); e; e = agnxtout(sg, e)) { newe = mapEdge (emap, e); agsubedge(newg, newe, 1); } } } for (subg = agfstsubg(sg); subg; subg = agnxtsubg(subg)) { cloneSubg(parent, subg, emap); } }
/* 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 } }
Agraph_t *nextsubg(Agraph_t *g, Agraph_t *sg) { if (!g || !sg) return NULL; return agnxtsubg(sg); }
/* cloneGraph: * Clone node, edge and subgraph structure from src to tgt. */ static void cloneGraph(Agraph_t * tgt, Agraph_t * src) { Agedge_t *e; Agnode_t *t; Agraph_t *sg; for (t = agfstnode(src); t; t = agnxtnode(t)) { if (!copy(tgt, OBJ(t))) { error(ERROR_FATAL, "error cloning node %s from graph %s", agnameof(t), agnameof(src)); } } for (t = agfstnode(src); t; t = agnxtnode(t)) { for (e = agfstout(t); e; e = agnxtout(e)) { if (!copy(tgt, OBJ(e))) { error(ERROR_FATAL, "error cloning edge (%s,%s)[%s] from graph %s", agnameof(agtail(e)), agnameof(aghead(e)), agnameof(e), agnameof(src)); } } } for (sg = agfstsubg(src); sg; sg = agnxtsubg(sg)) { if (!cloneSubg(tgt, sg)) { error(ERROR_FATAL, "error cloning subgraph %s from graph %s", agnameof(sg), agnameof(src)); } } }
/* createGroups: * run after temp nodes are created */ void createGroups(Agraph_t* sg) { mcGroup* gr; Agraph_t* subg; Agnode_t* v; mcNode* leader; mcNode* mcn; for (subg = agfstsubg(sg); subg; subg = agnxtsubg(subg)) { if(is_a_cluster(subg)) { int isLeader=1; gr=initMcGroup(mcGrStrict); for (v = agfstnode(subg); v; v = agnxtnode(subg, v)) { mcn = MND_mcn(v); dtappend(gr->nodes,mcn); mcn->group=gr; mcn->groupOrder=0;/*this will be removed eventually */ mcn->isLeader=isLeader; if(isLeader==1) { leader = mcn; isLeader = 0; } mcn->leader = leader; } } else createGroups (subg); } }
static int write_subgs(Agraph_t * g, GVJ_t * job, int top, state_t* sp) { Agraph_t* sg; int not_first = 0; sg = agfstsubg(g); if (!sg) return 0; gvputs(job, ",\n"); indent(job, sp->Level++); if (top) gvputs(job, "\"objects\": [\n"); else { gvputs(job, "\"subgraphs\": [\n"); indent(job, sp->Level); } for (; sg; sg = agnxtsubg(sg)) { if (not_first) gvputs(job, ",\n"); else not_first = 1; if (top) write_subg (sg, job, sp); else gvprintf(job, "%d", GD_gid(sg)); } if (!top) { sp->Level--; gvputs(job, "\n"); indent(job, sp->Level); gvputs(job, "]"); } return 1; }
void GraphvizPlotter::parseSubgraphs(Agraph_t *g, GraphComponent *g_component, processedProperties *props) { // nacteni zpracovanych komponent pro jejich mozne budouci preskoceni v aktualni iteraci string_map node_attrs_bak = props->node_attrs; string_map edge_attrs_bak = props->edge_attrs; string_map graph_attrs_bak = props->graph_attrs; // prochazeni vsech podgrafu daneho grafu/podgrafu for (Agraph_t *subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { // vytvoreni podgrafu v datovem modelu Subgraph *subgraph = g_component->addSubgraph(agnameof(subg)); // zpracovani atributu grafu/podgrafu a ulozeni do datoveho modelu k danemu podgrafu parseGraphAttrs(subg, subgraph, props); // zpracovani podgrafu a ulozeni do datoveho modelu k danemu pdgrafu parseSubgraphs(subg, subgraph, props); // stejne zpracovani v pripade parseNodes(subg, subgraph, props); parseEdges(subg, subgraph, props); // pro dalsi podgraf nactu zpet zpracovane komponenty props->graph_attrs.clear(); props->node_attrs.clear(); props->edge_attrs.clear(); props->graph_attrs = graph_attrs_bak; props->node_attrs = node_attrs_bak; props->edge_attrs = edge_attrs_bak; } }
static void rec_cluster_init(Agraph_t *ug) { Agraph_t *subg; if (is_a_cluster(ug)) cluster_init(ug); for (subg = agfstsubg(ug); subg; subg = agnxtsubg(ug,subg)) rec_cluster_init(subg); }
/* this is a first cut at a top-level planner. it's lame. */ static void rec_cluster_run(Agraph_t *ug) { Agraph_t *subg; if (is_a_cluster(ug)) mincross_clust(ug); for (subg = agfstsubg(ug); subg; subg = agnxtsubg(ug,subg)) rec_cluster_run(subg); if (is_a_cluster(ug)) mincross_clust(ug); }
static void find_clusters(graph_t * g) { graph_t *subg; for (subg = agfstsubg(dot_root(g)); subg; subg = agnxtsubg(subg)) { if (GD_set_type(subg) == CLUSTER) collapse_cluster(g, subg); } }
static void rec_model_subclusts(Agraph_t *model, Agraph_t *user) { Agraph_t *subg; if (is_a_cluster(user)) (void) model_clust(model,user); /* note there can be non-cluster subgraphs that contain lower clusters */ for (subg = agfstsubg(ug); subg; subg = agnxtsubg(ug,subg)) rec_model_subclusts(model,subg); }
static void write_subg(Agraph_t * g, GVJ_t * job, state_t* sp) { Agraph_t* sg; write_graph (g, job, FALSE, sp); for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { gvputs(job, ",\n"); write_subg(sg, job, sp); } }
/* cloneSubg: * Clone subgraph sg in tgt. */ static Agraph_t *cloneSubg(Agraph_t * tgt, Agraph_t * g, Dt_t* emap) { Agraph_t *ng; Agraph_t *sg; Agnode_t *t; Agnode_t *newt; Agedge_t *e; Agedge_t *newe; char* name; ng = (Agraph_t *) (copy(tgt, OBJ(g))); if (!ng) return 0; for (t = agfstnode(g); t; t = agnxtnode(g, t)) { newt = agnode(tgt, agnameof(t), 0); if (!newt) { exerror("node %s not found in cloned graph %s", agnameof(t), agnameof(tgt)); return 0; } else agsubnode(ng, newt, 1); } for (t = agfstnode(g); t; t = agnxtnode(g, t)) { for (e = agfstout(g, t); e; e = agnxtout(g, e)) { newe = mapEdge (emap, e); if (!newe) { name = agnameof(AGMKOUT(e)); if (name) exerror("edge (%s,%s)[%s] not found in cloned graph %s", agnameof(agtail(e)), agnameof(aghead(e)), name, agnameof(tgt)); else exerror("edge (%s,%s) not found in cloned graph %s", agnameof(agtail(e)), agnameof(aghead(e)), agnameof(tgt)); return 0; } else agsubedge(ng, newe, 1); } } for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { if (!cloneSubg(ng, sg, emap)) { exerror("error cloning subgraph %s from graph %s", agnameof(sg), agnameof(g)); return 0; } } return ng; }
static int label_subgs(Agraph_t* g, int lbl, Dt_t* map) { Agraph_t* sg; if (g != agroot(g)) { GD_gid(g) = lbl++; if (IS_CLUSTER(g)) insert (map, agnameof(g), GD_gid(g)); } for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { lbl = label_subgs(sg, lbl, map); } return lbl; }
void graphGroups(Agraph_t* sg) { Agraph_t* subg; Agnode_t* v; for (subg = agfstsubg(sg); subg; subg = agnxtsubg(subg)) { if(is_a_cluster(subg)) for (v = agfstnode(subg); v; v = agnxtnode(subg, v)) MND_highCluster(v)=subg; else graphGroups (subg); } }
static void dot_init_subg(graph_t * g, graph_t* droot) { graph_t* subg; if ((g != agroot(g))) agbindrec(g, "Agraphinfo_t", sizeof(Agraphinfo_t), TRUE); if (g == droot) GD_dotroot(agroot(g)) = droot; for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { dot_init_subg(subg, droot); } }
bool rm(Agraph_t *g) { Agedge_t *e; if (!g) return false; Agraph_t* sg; for (sg = agfstsubg (g); sg; sg = agnxtsubg (sg)) rm(sg); if (g == agroot(g)) agclose(g); else agdelete(agroot(g), g); return true; }
/* recursively apply objfn within the hierarchy of a graph. * if obj is a node or edge, it and its images in every subg are visited. * if obj is a graph, then it and its subgs are visited. */ static void rec_apply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg, agobjsearchfn_t objsearch, int preorder) { Agraph_t *sub; Agobj_t *subobj; if (preorder) fn(g, obj, arg); for (sub = agfstsubg(g); sub; sub = agnxtsubg(sub)) { if ((subobj = objsearch(sub, obj))) rec_apply(sub, subobj, fn, arg, objsearch, preorder); } if (NOT(preorder)) fn(g, obj, arg); }
/* cloneGraph: * Clone node, edge and subgraph structure from src to tgt. */ static void cloneGraph(Agraph_t * tgt, Agraph_t * src) { Agedge_t *e; Agedge_t *ne; Agnode_t *t; Agraph_t *sg; char* name; Dt_t* emap = dtopen (&edgepair, Dtoset); edgepair_t* data = (edgepair_t*)malloc(sizeof(edgepair_t)*agnedges(src)); edgepair_t* ep = data; for (t = agfstnode(src); t; t = agnxtnode(src, t)) { if (!copy(tgt, OBJ(t))) { exerror("error cloning node %s from graph %s", agnameof(t), agnameof(src)); } } for (t = agfstnode(src); t; t = agnxtnode(src, t)) { for (e = agfstout(src, t); e; e = agnxtout(src, e)) { if (!(ne = (Agedge_t*)copy(tgt, OBJ(e)))) { name = agnameof(AGMKOUT(e)); if (name) exerror("error cloning edge (%s,%s)[%s] from graph %s", agnameof(agtail(e)), agnameof(aghead(e)), name, agnameof(src)); else exerror("error cloning edge (%s,%s) from graph %s", agnameof(agtail(e)), agnameof(aghead(e)), agnameof(src)); return; } ep->key = e; ep->val = ne; dtinsert (emap, ep++); } } for (sg = agfstsubg(src); sg; sg = agnxtsubg(sg)) { if (!cloneSubg(tgt, sg, emap)) { exerror("error cloning subgraph %s from graph %s", agnameof(sg), agnameof(src)); } } dtclose (emap); free (data); }
/* mkMCGraph: * Clone original graph. We only need the nodes, edges and clusters. * Copy */ Agraph_t* mkMCGraph (Agraph_t* g) { Agnode_t* t; Agnode_t* newt; Agnode_t* newh; Agedge_t* e; Agedge_t* newe; Agraph_t* sg; edgepair_t* data; edgepair_t* ep; Agraph_t* newg = agopen (agnameof(g), g->desc, 0); Dt_t* emap = dtopen (&edgepair, Dtoset);; data = N_NEW(agnedges(g), edgepair_t); ep = data; for (t = agfstnode(g); t; t = agnxtnode(g, t)) { newt = mkMCNode (newg, STDNODE, agnameof(t)); assert(newt); MND_orig(newt) = t; MND_rank(newt) = ND_rank(t); } for (t = agfstnode(g); t; t = agnxtnode(g, t)) { newt = agnode (newg, agnameof(t), 0); for (e = agfstout(g, t); e; e = agnxtout(g, e)) { newh = agnode (newg, agnameof(aghead(e)), 0); assert(newh); newe = mkMCEdge (newg, newt, newh, agnameof (e), NORMAL, e); assert(newe); ep->key = e; ep->val = newe; dtinsert (emap, ep++); } } for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { cloneSubg(newg, sg, emap); } dtclose (emap); free (data); return newg; }
void drawGraph(Agraph_t * g) { Agnode_t *v; Agedge_t *e; Agraph_t *s; int param = 0; for (s = agfstsubg(g); s; s = agnxtsubg(s)) { OD_SelFlag(s) = 0; if (OD_Selected(s) == 1) param = 1; else param = 0; drawXdotwithattrs(s, param); } for (v = agfstnode(g); v; v = agnxtnode(g, v)) { if (OD_Selected(v) == 1) param = 1; else param = 0; OD_SelFlag(v) = 0; drawXdotwithattr(v, "_draw_", param); //draw primitives drawXdotwithattr(v, "_ldraw_", param);//label drawing for (e = agfstout(g, v); e; e = agnxtout(g, e)) { OD_SelFlag(e) = 0; if (OD_Selected(e) == 1) param = 1; else param = 0; drawXdotwithattrs(e, param); } } if ((view->Selection.Active > 0) && (!view->SignalBlock)) { view->Selection.Active = 0; drawGraph(g); view->SignalBlock = 1; glexpose(); view->SignalBlock = 0; } }
static void set_attrwf(Agraph_t * g, int toplevel, int value) { Agraph_t *subg; Agnode_t *n; Agedge_t *e; AGATTRWF(g) = value; for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { set_attrwf(subg, FALSE, value); } if (toplevel) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { AGATTRWF(n) = value; for (e = agfstout(g, n); e; e = agnxtout(g, e)) AGATTRWF(e) = value; } } }
void deleteGraph(gctx_t * gctx, Agraph_t *g) { Agraph_t *sg; char *hndl; for (sg = agfstsubg (g); sg; sg = agnxtsubg (sg)) { deleteGraph(gctx, sg); } deleteGraphNodes(gctx, g); hndl = obj2cmd(g); if (g == agroot(g)) { agclose(g); } else { agdelsubg(agroot(g), g); } Tcl_DeleteCommand(gctx->ictx->interp, hndl); }
/* cloneSubg: * Clone subgraph sg in tgt. */ static Agraph_t *cloneSubg(Agraph_t * tgt, Agraph_t * g) { Agraph_t *ng; Agraph_t *sg; Agnode_t *t; Agnode_t *newt; Agnode_t *newh; Agedge_t *e; Agedge_t *newe; ng = (Agraph_t *) (copy(tgt, OBJ(g))); if (!ng) return 0; for (t = agfstnode(g); t; t = agnxtnode(t)) { newt = agnode(tgt, agnameof(t), 0); if (!newt) error(ERROR_PANIC, "node %s not found in cloned graph %s", agnameof(t), agnameof(tgt)); agsubnode(ng, newt, 1); } for (t = agfstnode(g); t; t = agnxtnode(t)) { newt = agnode(tgt, agnameof(t), 0); for (e = agfstout(t); e; e = agnxtout(e)) { newh = agnode(tgt, agnameof(aghead(e)), 0); newe = agedge(newt, newh, agnameof(e), 0); if (!newe) error(ERROR_PANIC, "edge (%s,%s)[%s] not found in cloned graph %s", agnameof(agtail(e)), agnameof(aghead(e)), agnameof(e), agnameof(tgt)); agsubedge(ng, newe, 1); } } for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { if (!cloneSubg(ng, sg)) { error(ERROR_FATAL, "error cloning subgraph %s from graph %s", agnameof(sg), agnameof(g)); } } return ng; }
static void dot_cleanup_graph(graph_t * g) { int i; graph_t *subg; for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { dot_cleanup_graph(subg); } if (GD_clust(g)) free (GD_clust(g)); if (GD_rankleader(g)) free (GD_rankleader(g)); free_list(GD_comp(g)); if (GD_rank(g)) { for (i = GD_minrank(g); i <= GD_maxrank(g); i++) free(GD_rank(g)[i].av); if (GD_minrank(g) == -1) free(GD_rank(g)-1); else free(GD_rank(g)); } if (g != agroot(g)) agdelrec(g,"Agraphinfo_t"); }
/* 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 #ifndef WITH_CGRAPH graph_t *mg; node_t *mn; edge_t *me; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = aghead(me); subg = agusergraph(mn); #else /* WITH_CGRAPH */ for (subg = agfstsubg(g); subg; subg = agnxtsubg(subg)) { #endif /* WITH_CGRAPH */ 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 } } static void find_clusters(graph_t * g) { graph_t *subg; #ifndef WITH_CGRAPH graph_t *mg; node_t *mn; edge_t *me; mg = g->meta_node->graph; for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) { mn = me->head; subg = agusergraph(mn); #else /* WITH_CGRAPH */ for (subg = agfstsubg(agroot(g)); subg; subg = agnxtsubg(subg)) { #endif /* WITH_CGRAPH */ if (GD_set_type(subg) == CLUSTER) collapse_cluster(g, subg); } } static void set_minmax(graph_t * g) { int c; GD_minrank(g) += ND_rank(GD_leader(g)); GD_maxrank(g) += ND_rank(GD_leader(g)); for (c = 1; c <= GD_n_cluster(g); c++) set_minmax(GD_clust(g)[c]); }
/* * Close a graph or subgraph, freeing its storage. */ int agclose(Agraph_t * g) { Agraph_t *subg, *next_subg, *par; Agnode_t *n, *next_n; agflatten(g, FALSE); par = agparent(g); if ((par == NILgraph) && (AGDISC(g, mem)->close)) { /* free entire heap */ agmethod_delete(g, g); /* invoke user callbacks */ agfreeid(g, AGRAPH, AGID(g)); AGDISC(g, mem)->close(AGCLOS(g, mem)); /* whoosh */ return SUCCESS; } for (subg = agfstsubg(g); subg; subg = next_subg) { next_subg = agnxtsubg(subg); agclose(subg); } for (n = agfstnode(g); n; n = next_n) { next_n = agnxtnode(n); agdelnode(n); } aginternalmapclose(g); agmethod_delete(g, g); assert(dtsize(g->n_id) == 0); agdtclose(g, g->n_id); assert(dtsize(g->n_seq) == 0); agdtclose(g, g->n_seq); assert(dtsize(g->e_id) == 0); agdtclose(g, g->e_id); assert(dtsize(g->e_seq) == 0); agdtclose(g, g->e_seq); assert(dtsize(g->g_dict) == 0); agdtclose(g, g->g_dict); if (g->desc.has_attrs) agraphattr_delete(g); agrecclose((Agobj_t *) g); agfreeid(g, AGRAPH, AGID(g)); if (par) { agdelsubg(par, g); agfree(par, g); } else { Agmemdisc_t *memdisc; void *memclos, *clos; while (g->clos->cb) agpopdisc(g, g->clos->cb->f); AGDISC(g, id)->close(AGCLOS(g, id)); agstrclose(g); memdisc = AGDISC(g, mem); memclos = AGCLOS(g, mem); clos = g->clos; (memdisc->free) (memclos, g); (memdisc->free) (memclos, clos); } return SUCCESS; }