From: erg Date: Thu, 28 May 2009 21:03:43 +0000 (+0000) Subject: Modify node adjustment API: X-Git-Tag: LAST_LIBGRAPH~32^2~1982 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=55ff80950bdbb41f030fa7b07b1d006945182057;p=graphviz Modify node adjustment API: - parsing of "overlap" attribute to allow setting of parameters - support of full prism, or just initial scaling part of prism; also no scaling --- diff --git a/lib/fdpgen/xlayout.c b/lib/fdpgen/xlayout.c index 20f4c48c4..1fa04cc6d 100644 --- a/lib/fdpgen/xlayout.c +++ b/lib/fdpgen/xlayout.c @@ -532,7 +532,8 @@ void fdp_xLayout(graph_t * g, xparams * xpms) if (!ovlp || (*ovlp == '\0')) { ovlp = DFLT_overlap; } - if ((cp = strchr(ovlp, ':'))) { + /* look for optional ":" or "number:" */ + if ((cp = strchr(ovlp, ':')) && ((cp == ovlp) || isdigit(*ovlp))) { cp++; rest = cp; tries = atoi (ovlp); diff --git a/lib/neatogen/adjust.c b/lib/neatogen/adjust.c index c89658513..c7610ac8d 100644 --- a/lib/neatogen/adjust.c +++ b/lib/neatogen/adjust.c @@ -739,7 +739,7 @@ SparseMatrix makeMatrix(Agraph_t * g, int dim) #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP)) static int -fdpAdjust (graph_t* g) +fdpAdjust (graph_t* g, adjust_data* am) { SparseMatrix A0 = makeMatrix(g, Ndim); SparseMatrix A = A0; @@ -749,7 +749,6 @@ fdpAdjust (graph_t* g) int flag, i; expand_t sep = sepFactor(g); pointf pad; - double initial_scaling; if (sep.doAdd) { pad.x = PS2INCH(sep.x); @@ -774,8 +773,7 @@ fdpAdjust (graph_t* g) A = SparseMatrix_remove_diagonal(A); } - initial_scaling = late_double(g, agfindgraphattr(g, "overlap_scaling"), -4.0, -1.e10); - remove_overlap(Ndim, A, A->m, pos, sizes, 1000, initial_scaling, &flag); + remove_overlap(Ndim, A, A->m, pos, sizes, am->value, am->scaling, &flag); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { real *npos = pos + (Ndim * ND_id(n)); @@ -897,73 +895,112 @@ void normalize(graph_t * g) } } -static adjust_data adjustMode[] = { - {AM_NONE, "", ""}, - {AM_VOR, "", "Voronoi"}, - {AM_SCALE, "oscale", "old scaling"}, - {AM_NSCALE, "scale", "scaling"}, - {AM_SCALEXY, "scalexy", "x and y scaling"}, - /* {AM_PUSH, "push", "push scan adjust"}, */ - /* {AM_PUSHPULL, "pushpull", "push-pull scan adjust"}, */ - {AM_ORTHO, "ortho", "orthogonal constraints"}, - {AM_ORTHO_YX, "ortho_yx", "orthogonal constraints"}, - {AM_ORTHOXY, "orthoxy", "xy orthogonal constraints"}, - {AM_ORTHOYX, "orthoyx", "yx orthogonal constraints"}, - {AM_PORTHO, "portho", "pseudo-orthogonal constraints"}, - {AM_PORTHO_YX, "portho_yx", "pseudo-orthogonal constraints"}, - {AM_PORTHOXY, "porthoxy", "xy pseudo-orthogonal constraints"}, - {AM_PORTHOYX, "porthoyx", "yx pseudo-orthogonal constraints"}, - {AM_COMPRESS, "compress", "compress"}, - {AM_VPSC, "vpsc", "vpsc"}, - {AM_IPSEP, "ipsep", "ipsep"}, - {AM_PRISM, "prism", "prism"}, - {AM_NONE, 0, 0} +typedef struct { + adjust_mode mode; + char *attrib; + int len; + char *print; +} lookup_t; + +#define STRLEN(s) ((sizeof(s)-1)/sizeof(char)) +#define ITEM(i,s,v) {i, s, STRLEN(s), v} + +static lookup_t adjustMode[] = { + ITEM(AM_NONE, "", "none"), + ITEM(AM_VOR, "", "Voronoi"), + ITEM(AM_SCALE, "oscale", "old scaling"), + ITEM(AM_NSCALE, "scale", "scaling"), + ITEM(AM_SCALEXY, "scalexy", "x and y scaling"), + ITEM(AM_ORTHO, "ortho", "orthogonal constraints"), + ITEM(AM_ORTHO_YX, "ortho_yx", "orthogonal constraints"), + ITEM(AM_ORTHOXY, "orthoxy", "xy orthogonal constraints"), + ITEM(AM_ORTHOYX, "orthoyx", "yx orthogonal constraints"), + ITEM(AM_PORTHO, "portho", "pseudo-orthogonal constraints"), + ITEM(AM_PORTHO_YX, "portho_yx", "pseudo-orthogonal constraints"), + ITEM(AM_PORTHOXY, "porthoxy", "xy pseudo-orthogonal constraints"), + ITEM(AM_PORTHOYX, "porthoyx", "yx pseudo-orthogonal constraints"), + ITEM(AM_COMPRESS, "compress", "compress"), + ITEM(AM_VPSC, "vpsc", "vpsc"), + ITEM(AM_IPSEP, "ipsep", "ipsep"), +#if (HAVE_GTS || HAVE_TRIANGLE) + ITEM(AM_PRISM, "prism", "prism"), +#endif + {AM_NONE, 0, 0, 0} }; + +/* setPrismValues: + * Initialize and set prism values + */ +static void +setPrismValues (Agraph_t* g, char* s, adjust_data* dp) +{ + int v; + + if ((sscanf (s, "%d", &v) > 0) && (v >= 0)) + dp->value = v; + else + dp->value = 1000; + dp->scaling = late_double(g, agfindgraphattr(g, "overlap_scaling"), -4.0, -1.e10); +} + /* getAdjustMode: * Convert string value to internal value of adjustment mode. * Assume s != NULL. */ -static adjust_data *getAdjustMode(char *s) +static adjust_data *getAdjustMode(Agraph_t* g, char *s, adjust_data* dp) { - adjust_data *ap = adjustMode + 2; - if (*s == '\0') return adjustMode; - while (ap->attrib) { - if (!strcasecmp(s, ap->attrib)) - return ap; - ap++; + lookup_t *ap = adjustMode + 2; + if (*s == '\0') { + dp->mode = adjustMode[0].mode; + dp->print = adjustMode[0].print; } - if (mapbool(s)) - return adjustMode; - else - return adjustMode + 1; + else { + while (ap->attrib) { + if (!strncasecmp(s, ap->attrib, ap->len)) { + dp->mode = ap->mode; + dp->print = ap->print; + if (ap->mode == AM_PRISM) + setPrismValues (g, s + ap->len, dp); + break; + } + ap++; + } + if (ap->attrib == NULL ) { + if (mapbool(s)) { + dp->mode = adjustMode[0].mode; + dp->print = adjustMode[0].print; + } + else { + dp->mode = adjustMode[1].mode; + dp->print = adjustMode[1].print; + } + } + } + return dp; } -adjust_data *graphAdjustMode(graph_t *G) +adjust_data *graphAdjustMode(graph_t *G, adjust_data* dp, char* dflt) { char* am = agget(G, "overlap"); - return (getAdjustMode (am ? am : "")); + return (getAdjustMode (G, am ? am : (dflt ? dflt : ""), dp)); } -/* removeOverlapAs: - * Use flag value to determine if and how to remove +/* removeOverlapWith: + * Use adjust_data to determine if and how to remove * node overlaps. + * Return non-zero if nodes are moved. */ int -removeOverlapAs(graph_t * G, char* flag) +removeOverlapWith (graph_t * G, adjust_data* am) { - /* int userWindow = 0; */ - int ret = 0; - /* extern void scanAdjust(graph_t*, int); */ - - adjust_data *am; + int ret; if (agnnodes(G) < 2) return 0; - if (flag == NULL) - return 0; - am = getAdjustMode(flag); + normalize(G); + if (am->mode == AM_NONE) return 0; @@ -1000,7 +1037,7 @@ removeOverlapAs(graph_t * G, char* flag) break; #if ((defined(HAVE_GTS) || defined(HAVE_TRIANGLE)) && defined(SFDP)) case AM_PRISM: - ret = fdpAdjust(G); + ret = fdpAdjust(G, am); break; #endif #ifdef IPSEPCOLA @@ -1043,12 +1080,22 @@ removeOverlapAs(graph_t * G, char* flag) return ret; } -/* removeOverlap: +/* removeOverlapAs: + * Use flag value to determine if and how to remove + * node overlaps. */ int -removeOverlap(graph_t * G) +removeOverlapAs(graph_t * G, char* flag) { - return (removeOverlapAs(G, agget(G, "overlap"))); + adjust_data am; + + if (agnnodes(G) < 2) + return 0; + if (flag == NULL) + return 0; + + getAdjustMode(G, flag, &am); + return removeOverlapWith (G, &am); } /* adjustNodes: @@ -1057,10 +1104,7 @@ removeOverlap(graph_t * G) */ int adjustNodes(graph_t * G) { - if (agnnodes(G) < 2) - return 0; - normalize(G); - return removeOverlap (G); + return (removeOverlapAs(G, agget(G, "overlap"))); } /* parseFactor: diff --git a/lib/neatogen/adjust.h b/lib/neatogen/adjust.h index 6ad7d9026..d4ff1b6d7 100644 --- a/lib/neatogen/adjust.h +++ b/lib/neatogen/adjust.h @@ -38,8 +38,9 @@ typedef enum { typedef struct { adjust_mode mode; - char *attrib; char *print; + int value; + double scaling; } adjust_data; typedef struct { @@ -51,11 +52,11 @@ typedef struct { extern expand_t esepFactor(graph_t * G); extern int adjustNodes(graph_t * G); extern void normalize(graph_t * g); - extern int removeOverlap(graph_t * G); extern int removeOverlapAs(graph_t*, char*); + extern int removeOverlapWith(graph_t*, adjust_data*); extern int cAdjust(graph_t *, int); extern int scAdjust(graph_t *, int); - extern adjust_data *graphAdjustMode(graph_t *G); + extern adjust_data *graphAdjustMode(graph_t *G, adjust_data*, char* dflt); extern double *getSizes(Agraph_t * g, pointf pad); extern SparseMatrix makeMatrix(Agraph_t * g, int dim); diff --git a/lib/neatogen/neatoinit.c b/lib/neatogen/neatoinit.c index 1a6ab2556..2148cc7c7 100644 --- a/lib/neatogen/neatoinit.c +++ b/lib/neatogen/neatoinit.c @@ -1189,7 +1189,7 @@ void dumpData(graph_t * g, vtx_data * gp, int nv, int ne) * mode will be MODE_MAJOR, MODE_HIER or MODE_IPSEP */ static void -majorization(graph_t *mg, graph_t * g, int nv, int mode, int model, int dim, int steps) +majorization(graph_t *mg, graph_t * g, int nv, int mode, int model, int dim, int steps, adjust_data* am) { double **coords; int ne; @@ -1239,7 +1239,6 @@ majorization(graph_t *mg, graph_t * g, int nv, int mode, int model, int dim, int #ifdef IPSEPCOLA else { char* str; - adjust_data* am; ipsep_options opt; pointf* nsize; cluster_data *cs = (cluster_data*)cluster_map(mg,g); @@ -1261,7 +1260,6 @@ majorization(graph_t *mg, graph_t * g, int nv, int mode, int model, int dim, int fprintf(stderr,"Generating DiG-CoLa Edge Constraints...\n"); } else opt.diredges = 0; - am = graphAdjustMode (g); if (am->mode == AM_IPSEP) { opt.noverlap = 1; if(Verbose) @@ -1395,7 +1393,9 @@ static void kkNeato(Agraph_t * g, int nG, int model) /* neatoLayout: * Use stress optimization to layout a single component */ -void neatoLayout(Agraph_t * mg, Agraph_t * g, int layoutMode, int layoutModel) +static void +neatoLayout(Agraph_t * mg, Agraph_t * g, int layoutMode, int layoutModel, + adjust_data* am) { int nG; char *str; @@ -1410,12 +1410,8 @@ void neatoLayout(Agraph_t * mg, Agraph_t * g, int layoutMode, int layoutModel) nG = scan_graph_mode(g, layoutMode); if ((nG < 2) || (MaxIter <=0)) return; -#ifdef WITH_CGRAPH -// if (Verbose) { -// fprintf(stderr, "%i\n", count_nodes(g)); -#endif /* WITH_CGRAPH */ if (layoutMode) - majorization(mg, g, nG, layoutMode, layoutModel, Ndim, MaxIter); + majorization(mg, g, nG, layoutMode, layoutModel, Ndim, MaxIter, am); else kkNeato(g, nG, layoutModel); } @@ -1449,6 +1445,7 @@ void neato_layout(Agraph_t * g) int model; pack_mode mode; pack_info pinfo; + adjust_data am; if (Nop) { int save = PSinputscale; @@ -1465,6 +1462,7 @@ void neato_layout(Agraph_t * g) } else { neato_init_graph(g); layoutMode = neatoMode(g); + graphAdjustMode (g, &am, 0); model = neatoModel(g); mode = getPackModeInfo (g, l_undef, &pinfo); Pack = getPack(g, -1, CL_OFFSET); @@ -1490,8 +1488,8 @@ void neato_layout(Agraph_t * g) for (i = 0; i < n_cc; i++) { gc = cc[i]; nodeInduce(gc); - neatoLayout(g, gc, layoutMode, model); - adjustNodes(gc); + neatoLayout(g, gc, layoutMode, model, &am); + removeOverlapWith(gc, &am); } if (n_cc > 1) { boolean *bp; @@ -1540,8 +1538,8 @@ void neato_layout(Agraph_t * g) } #endif } else { - neatoLayout(g, g, layoutMode, model); - adjustNodes(g); + neatoLayout(g, g, layoutMode, model, &am); + removeOverlapWith(g, &am); addZ (g); spline_edges(g); } diff --git a/lib/neatogen/neatoprocs.h b/lib/neatogen/neatoprocs.h index 4c9e4c600..e2b636f68 100644 --- a/lib/neatogen/neatoprocs.h +++ b/lib/neatogen/neatoprocs.h @@ -59,7 +59,6 @@ extern "C" { extern void neato_enqueue(node_t *); extern void neato_init_node(node_t * n); extern void neato_layout(Agraph_t * g); - extern void neatoLayout(Agraph_t *mg, Agraph_t * g, int layoutMode, int layoutModel); extern int Plegal_arrangement(Ppoly_t ** polys, int n_polys); extern void randompos(Agnode_t *, int); extern void s1(graph_t *, node_t *); diff --git a/lib/neatogen/overlap.c b/lib/neatogen/overlap.c index 918077d62..93e72e7ce 100644 --- a/lib/neatogen/overlap.c +++ b/lib/neatogen/overlap.c @@ -438,14 +438,15 @@ void remove_overlap(int dim, SparseMatrix A, int m, real *x, real *label_sizes, if (!label_sizes) return; - avg_label_size = 0; - for (i = 0; i < m; i++) avg_label_size += label_sizes[i*dim]+label_sizes[i*dim+1]; - /* for (i = 0; i < m; i++) avg_label_size += 2*MAX(label_sizes[i*dim],label_sizes[i*dim+1]);*/ - avg_label_size /= m; if (initial_scaling < 0) { + avg_label_size = 0; + for (i = 0; i < m; i++) avg_label_size += label_sizes[i*dim]+label_sizes[i*dim+1]; + /* for (i = 0; i < m; i++) avg_label_size += 2*MAX(label_sizes[i*dim],label_sizes[i*dim+1]);*/ + avg_label_size /= m; scale_to_edge_length(dim, A, x, -initial_scaling*avg_label_size); - } else { + } + else if (initial_scaling > 0) { scale_to_edge_length(dim, A, x, initial_scaling); }