Esempio n. 1
0
edge_t	* debug_getedge(graph_t *g, char *s0, char *s1)
{
	node_t	*n0,*n1;
	n0 = agfindnode(g,s0);
	n1 = agfindnode(g,s1);
	if (n0 && n1) return agfindedge(g,n0,n1);
	else return NULL;
}
Esempio n. 2
0
/* mapN:
 * Convert cluster nodes back to ordinary nodes
 * If n is already ordinary, return it.
 * Otherwise, we know node's name is "__i:xxx"
 * where i is some number and xxx is the nodes's original name.
 * Create new node of name xxx if it doesn't exist and add n to clg
 * for later deletion.
 */
static node_t *mapN(node_t * n, graph_t * clg)
{
    extern Agdict_t *agdictof(void *);
    node_t *nn;
    char *name;
    graph_t *g = n->graph;
    Agdict_t *d;
    Agsym_t **list;
    Agsym_t *sym;

    if (!(IS_CLUST_NODE(n)))
	return n;
    aginsert(clg, n);

    name = strchr(n->name, ':');
    assert(name);
    name++;
    if ((nn = agfindnode(g, name)))
	return nn;
    nn = agnode(g, name);

    /* Set all attributes to default */
    d = agdictof(n);
    list = d->list;
    while ((sym = *list++)) {
	/* Can use pointer comparison because of ref strings. */
	if (agxget(nn, sym->index) != sym->value)
	    agxset(nn, sym->index, sym->value);
    }

    return nn;
}
Esempio n. 3
0
/* mapN:
 * Convert cluster nodes back to ordinary nodes
 * If n is already ordinary, return it.
 * Otherwise, we know node's name is "__i:xxx"
 * where i is some number and xxx is the nodes's original name.
 * Create new node of name xxx if it doesn't exist and add n to clg
 * for later deletion.
 */
static node_t *mapN(node_t * n, graph_t * clg)
{
    node_t *nn;
    char *name;
    graph_t *g = agraphof(n);
    Agsym_t *sym;

    if (!(IS_CLUST_NODE(n)))
	return n;
    agsubnode(clg, n, 1);
    name = strchr(agnameof(n), ':');
    assert(name);
    name++;
    if ((nn = agfindnode(g, name)))
	return nn;
    nn = agnode(g, name, 1);
    agbindrec(nn, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE);

    /* Set all attributes to default */
    for (sym = agnxtattr(g, AGNODE, NULL); sym;  (sym = agnxtattr(g, AGNODE, sym))) {
	if (agxget(nn, sym) != sym->defval)
	    agxset(nn, sym, sym->defval);
    }
    return nn;
}
Esempio n. 4
0
/* 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);

}
Esempio n. 5
0
/* find_blocks:
 */
static void find_blocks(Agraph_t * g, circ_state * state)
{
    Agnode_t *n;
    Agnode_t *root = NULL;
    block_t *rootBlock = NULL;
    blocklist_t ublks;
#ifdef USER_BLOCKS
    graph_t *clust_subg;
    graph_t *mg;
    edge_t *me;
    node_t *mm;
    int isRoot;
#endif

    initBlocklist(&ublks);

    /*      check to see if there is a node which is set to be the root
     */
    if (state->rootname) {
	root = agfindnode(g, state->rootname);
    }
    if (!root && state->N_root) {
	for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	    if (late_bool(ORIGN(n), state->N_root, 0)) {
		root = n;
		break;
	    }
	}
    }
#ifdef USER_BLOCKS
    /* process clusters first */
    /* by construction, all subgraphs are blocks and are non-empty */
    mm = g->meta_node;
    mg = mm->graph;
    for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) {
	block_t *block;

	clust_subg = agusergraph(me->head);

	isRoot = 0;
	block = mkBlock(clust_subg);
	/* block = makeBlock(g, state); */
	for (n = agfstnode(clust_subg); n; n = agnxtnode(clust_subg, n)) {
	    if (!BCDONE(n)) {	/* test not necessary if blocks disjoint */
		SET_BCDONE(n);
		BLOCK(n) = block;
		if (n == root)
		    isRoot = 1;
	    }
	}
	if (isRoot) {
	    /* Assume blocks are disjoint, so don't check if rootBlock is
	     * already assigned.
	     */
	    rootBlock = block;
	    insertBlock(&state->bl, block);
	} else {
	    appendBlock(&state->bl, block);
	}
    }
    ublks.first = state->bl.first;
    ublks.last = state->bl.last;
#endif

    if (!root)
	root = agfstnode(g);
    dfs(g, root, state, !rootBlock);

#ifdef USER_BLOCKS
    /* If g has user-supplied blocks, it may be disconnected.
     * We then fall into the following ugly loop.
     * We are guaranteed !VISITED(n) and PARENT(n) has been
     * set to a visited node.
     */
    if (ublks.first) {
	while (n = findUnvisited(&ublks)) {
	    dfs(g, n, state, 0);
	}
    }
#endif
}
Esempio n. 6
0
/* twopi_layout:
 */
void twopi_layout(Agraph_t * g)
{
    Agnode_t *ctr = 0;
    char *s;
    int setRoot = 0;
    pointf sc;
    int doScale = 0;
    int r;

    if (agnnodes(g) == 0) return;

    twopi_init_graph(g);
    s = agget(g, "root");
    if ((s = agget(g, "root"))) {
	if (*s) {
	    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");
		setRoot = 1;
	    }
	}
	else {
	    setRoot = 1;
	}
    }

    if ((s = agget(g, "scale")) && *s) {
	if ((r = sscanf (s, "%lf,%lf",&sc.x,&sc.y))) {
	    if (r == 1) sc.y = sc.x;
	    doScale = 1;
	    if (Verbose)
		fprintf (stderr, "scale = (%f,%f)\n", sc.x, sc.y);
	}
    }

    if (agnnodes(g)) {
	Agraph_t **ccs;
	Agraph_t *sg;
	Agnode_t *c = NULL;
	Agnode_t *n;
	int ncc;
	int i;

	ccs = ccomps(g, &ncc, 0);
	if (ncc == 1) {
	    c = circleLayout(g, ctr);
	    if (setRoot && !ctr)
		ctr = c;
	    n = agfstnode(g);
	    free(ND_alg(n));
	    ND_alg(n) = NULL;
	    if (doScale)
		scaleGraph (g, c, sc);
	    adjustNodes(g);
	    spline_edges(g);
	} else {
	    pack_info pinfo;
	    getPackInfo (g, l_node, CL_OFFSET, &pinfo);
	    pinfo.doSplines = 0;

	    for (i = 0; i < ncc; i++) {
		sg = ccs[i];
		if (ctr && agcontains(sg, ctr))
		    c = ctr;
		else
		    c = 0;
		nodeInduce(sg);
		c = circleLayout(sg, c);
	        if (setRoot && !ctr)
		    ctr = c;
		if (doScale)
		    scaleGraph (sg, c, sc);
		adjustNodes(sg);
	    }
	    n = agfstnode(g);
	    free(ND_alg(n));
	    ND_alg(n) = NULL;
	    packSubgraphs(ncc, ccs, g, &pinfo);
	    spline_edges(g);
	}
	for (i = 0; i < ncc; i++) {
	    agdelete(g, ccs[i]);
	}
	free(ccs);
    }
    if (setRoot)
	agset (g, "root", agnameof (ctr)); 
    dotneato_postprocess(g);

}
Esempio n. 7
0
/* makeGraphs:
 * Generate dags modeling the row and column constraints.
 * If the table has cc columns, we create the graph
 *  0 -> 1 -> 2 -> ... -> cc
 * and if a cell starts in column c with span cspan, with
 * width w, we add the edge c -> c+cspan [minlen = w].
 *
 * We might simplify the graph by removing multiedges,
 * using the max minlen, but will affect the balancing?
 */
void makeGraphs(htmltbl_t * tbl, graph_t * rowg, graph_t * colg)
{
    htmlcell_t *cp;
    htmlcell_t **cells;
    node_t *t;
    node_t *lastn;
    node_t *h;
    edge_t *e;
    int i;
    int* minc;
    int* minr;

    lastn = NULL;
    for (i = 0; i <= tbl->cc; i++) {
	t = agnode(colg, nToName(i));
	alloc_elist(tbl->rc, ND_in(t));
	alloc_elist(tbl->rc, ND_out(t));
	if (lastn) {
	    ND_next(lastn) = t;
	    lastn = t;
	} else {
	    lastn = GD_nlist(colg) = t;
	}
    }
    lastn = NULL;
    for (i = 0; i <= tbl->rc; i++) {
	t = agnode(rowg, nToName(i));
	alloc_elist(tbl->cc, ND_in(t));
	alloc_elist(tbl->cc, ND_out(t));
	if (lastn) {
	    ND_next(lastn) = t;
	    lastn = t;
	} else {
	    lastn = GD_nlist(rowg) = t;
	}
    }
    minr = N_NEW(tbl->rc, int);
    minc = N_NEW(tbl->cc, int);
    for (cells = tbl->u.n.cells; *cells; cells++) {
        int x, y, c, r;
	cp = *cells;
        x = (cp->data.box.UR.x + (cp->cspan-1))/cp->cspan;
        for (c = 0; c < cp->cspan; c++)
          minc[cp->col + c] = MAX(minc[cp->col + c],x);
        y = (cp->data.box.UR.y + (cp->rspan-1))/cp->rspan;
        for (r = 0; r < cp->rspan; r++)
          minr[cp->row + r] = MAX(minr[cp->row + r],y);
    }
    for (cells = tbl->u.n.cells; *cells; cells++) {
        int x, y, c, r;
	cp = *cells;
	t = agfindnode(colg, nToName(cp->col));
	h = agfindnode(colg, nToName(cp->col + cp->cspan));
	e = agedge(colg, t, h);
        x = 0;
        for (c = 0; c < cp->cspan; c++)
            x += minc[cp->col + c];
	ED_minlen(e) = x;
	/* ED_minlen(e) = cp->data.box.UR.x; */
#ifdef DEBUG
	fprintf(stderr, "col edge %s -> %s %d\n", t->name, h->name,
		ED_minlen(e));
#endif
	elist_append(e, ND_out(t));
	elist_append(e, ND_in(h));

	t = agfindnode(rowg, nToName(cp->row));
	h = agfindnode(rowg, nToName(cp->row + cp->rspan));
	e = agedge(rowg, t, h);
        y = 0;
        for (r = 0; r < cp->rspan; r++)
            y += minr[cp->row + r];
	ED_minlen(e) = y;
	/* ED_minlen(e) = cp->data.box.UR.y; */
#ifdef DEBUG
	fprintf(stderr, "row edge %s -> %s %d\n", t->name, h->name,
		ED_minlen(e));
#endif
	elist_append(e, ND_out(t));
	elist_append(e, ND_in(h));
    }

    /* Make sure that 0 <= 1 <= 2 ...k. This implies graph connected. */
    checkChain(colg);
    checkChain(rowg);

    free (minc);
    free (minr);
}
Esempio n. 8
0
Agnode_t *findnode(Agraph_t *g, char *name)
{
    if (!g || !name)
	return NULL;
    return agfindnode(g, name);
}
Esempio n. 9
0
void gates_save_layout (GQueue *gates, const char *mode, const char *format, const char *filename)
{
    Agraph_t *graph;
    GVC_t* context;

    if (!gates || g_queue_is_empty (gates))
        return;

    // create context (automatically calls aginit())
    context = gvContext();

    // open a graph
    graph = agopen((char*)"map", AGRAPHSTRICT); // strict, directed graph

    // add all gates to the graph
    //
    for (GList *iter=g_queue_peek_tail_link (gates);iter;iter=g_list_previous (iter)) {
        gate_t *gate = (gate_t*)iter->data;
        char name[5];
        sprintf (name, "%d", gate->uid);
        printf ("creating node with name %s\n", name);
        agnode (graph, name);
    }

    // create edges
    int count=0;
    for (GList *iter=g_queue_peek_tail_link (gates);iter;iter=g_list_previous (iter)) {
        gate_t *gate = (gate_t*)iter->data;
        // find corresponding node
        char name[5];
        sprintf (name, "%d", gate->uid);
        Agnode_t *n1 = agfindnode (graph, name);
        if (!n1) {
            dbg (DBG_ERROR, "failed to retrieve node from name %s", name);
            continue;
        }
        printf ("adding %d edges to node %d\n", gate->ng, gate->uid);
        for (int j=0;j<gate->ng;j++) {
            sprintf (name, "%d", gate->ng_names[j]);
            Agnode_t *n2 = agfindnode (graph, name);
            if (!n2) {
                dbg (DBG_ERROR, "failed to retrieve node from name %s", name);
                continue;
            }
            agedge (graph, n1, n2);
            count++;
        }
    }

    printf ("created %d edges.\n", count);

    // layout the graph
    // choices are: manual, fdp, dot, neato, twopi, circo
    dbg (DBG_CLASS, "rendering graph with graphviz. mode = %s", mode);

    if (strcmp (mode, "fdp")) {
        gvLayout (context, graph, (char*)"fdp");
    } 
    if (strcmp (mode, "dot")) {
        gvLayout (context, graph, (char*)"dot");
    }
    if (strcmp (mode, "neato")) {
        gvLayout (context, graph, (char*)"neato");
    }
    if (strcmp (mode, "twopi")) {
        gvLayout (context, graph, (char*)"twopi");
    }
    if (strcmp (mode, "circo")) {
        gvLayout (context, graph, (char*)"circo");
    }

    // render graph to file
    dbg (DBG_CLASS, "saving graph to file %s", filename);
    gvRenderFilename(context, graph, (char*)format, (char*)filename);
    dbg (DBG_CLASS, "done.");

    // free graph
    gvFreeLayout(context, graph);
    agclose (graph);
    gvFreeContext(context);
}
Esempio n. 10
0
main(int argc, char *argv[])
{
    Agraph_t **gs;
    Agraph_t **ccs;
    Agraph_t *g;
    Agraph_t *gp;
    char *fname;
    FILE *fp;
    int cnt;
    int i;

    init(argc, argv);
    if (!Files) {
	fprintf(stderr, "No input files given\n");
	exit(1);
    }

    PSinputscale = POINTS_PER_INCH;
    if (doComps) {
	if (verbose)
	    fprintf(stderr, "do Comps\n");
	while (fname = *Files++) {
	    fp = fopen(fname, "r");
	    if (!fp) {
		fprintf(stderr, "Could not open %s\n", fname);
		continue;
	    }
	    g = agread(fp);
	    fclose(fp);
	    if (!g) {
		fprintf(stderr, "Could not read graph\n");
		continue;
	    }
	    printf("%s %d nodes %d edges %sconnected\n",
		   g->name, agnnodes(g), agnedges(g),
		   (isConnected(g) ? "" : "not "));
	    gs = ccomps(g, &cnt, "abc");
	    for (i = 0; i < cnt; i++) {
		gp = gs[i];
		printf(" %s %d nodes %d edges\n", gp->name, agnnodes(gp),
		       agnedges(gp));
	    }
	}
    } else {
	gs = N_GNEW(nFiles, Agraph_t *);
	cnt = 0;
	while (fname = Files[cnt]) {
	    fp = fopen(fname, "r");
	    if (!fp) {
		fprintf(stderr, "Could not open %s\n", fname);
		exit(1);
	    }
	    g = agread(fp);
	    fclose(fp);
	    if (!g) {
		fprintf(stderr, "Could not read graph\n");
		exit(1);
	    }
	    if (!single) {
		graph_init(g);
		ptest_initGraph(g);
	    }
	    initPos(g);
	    /* if (Verbose) dumpG (g); */
	    gs[cnt++] = g;
	}
	if (single) {
	    Agraph_t *root;
	    Agnode_t *n;
	    Agnode_t *np;
	    Agnode_t *tp;
	    Agnode_t *hp;
	    Agedge_t *e;
	    Agedge_t *ep;
	    root = agopen("root", 0);
	    agedgeattr(root, "pos", "");
	    for (i = 0; i < cnt; i++) {
		g = gs[i];
		for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
		    if (agfindnode(root, n->name)) {
			fprintf(stderr,
				"Error: node %s in graph %d (%s) previously added\n",
				n->name, i, Files[i]);
			exit(1);
		    }
		    np = agnode(root, n->name);
		    ND_pos(np)[0] = ND_pos(n)[0];
		    ND_pos(np)[1] = ND_pos(n)[1];
		    ND_coord_i(np).x = ND_coord_i(n).x;
		    ND_coord_i(np).y = ND_coord_i(n).y;
		}
		for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
		    tp = agfindnode(root, n->name);
		    for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
			hp = agfindnode(root, e->head->name);
			ep = agedge(root, tp, hp);
			ED_spl(ep) = ED_spl(e);
		    }
		}
	    }
	    graph_init(root);
	    ptest_initGraph(root);
	    ccs = ccomps(root, &cnt, 0);
	    packGraphs(cnt, ccs, root, margin, doEdges);
	    if (!doEdges)
		copyPos(root);
	    else
		State = GVSPLINES;
	    attach_attrs(root);
	    for (i = 0; i < cnt; i++) {
		agdelete(root, ccs[i]);
	    }
	    agwrite(root, stdout);
	} else {
	    packGraphs(cnt, gs, 0, margin, doEdges);
	    if (doEdges)
		State = GVSPLINES;
	    for (i = 0; i < cnt; i++) {
		if (!doEdges)
		    copyPos(gs[i]);
		attach_attrs(gs[i]);
		agwrite(gs[i], stdout);
	    }
	}
    }
}