]> granicus.if.org Git - graphviz/commitdiff
Modify node adjustment API:
authorerg <devnull@localhost>
Thu, 28 May 2009 21:03:43 +0000 (21:03 +0000)
committererg <devnull@localhost>
Thu, 28 May 2009 21:03:43 +0000 (21:03 +0000)
  - parsing of "overlap" attribute to allow setting of parameters
  - support of full prism, or just initial scaling part of prism; also no scaling

lib/fdpgen/xlayout.c
lib/neatogen/adjust.c
lib/neatogen/adjust.h
lib/neatogen/neatoinit.c
lib/neatogen/neatoprocs.h
lib/neatogen/overlap.c

index 20f4c48c4d3f0ec064317176ca950d1a3770eee3..1fa04cc6dfdd7b0c35e4ceba619e99efd2f0cb88 100644 (file)
@@ -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);
index c89658513c3e678bee53b9f860cf70cf91952741..c7610ac8d151d8570aafe24aa91722beeeab85a6 100644 (file)
@@ -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:
index 6ad7d9026ce4fd6459f2f764281f173b57b9b508..d4ff1b6d7329be38bd8fc2685498d682b6d5d968 100644 (file)
@@ -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);
 
index 1a6ab25562c2d69ddca271db51ddbc0f09c00dfd..2148cc7c7a69a7884355bccb2d222ebc54f85b1b 100644 (file)
@@ -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);
        }
index 4c9e4c600b7881155d6b91b65af00bab7da8460e..e2b636f689b7eeacd493984a1a913b5f35d86166 100644 (file)
@@ -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 *);
index 918077d62096c2061d21d70a553aa7d72a3b8ce5..93e72e7ce64017152b1de372c7ccfe289aba90ad 100644 (file)
@@ -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);
   }