]> granicus.if.org Git - graphviz/commitdiff
Add -D option to tell gvmap to use the graph's cluster subgraphs for its clusters.
authorEmden R. Gansner <erg@research.att.com>
Wed, 10 Jul 2013 18:59:19 +0000 (14:59 -0400)
committerEmden R. Gansner <erg@research.att.com>
Wed, 10 Jul 2013 18:59:19 +0000 (14:59 -0400)
cmd/gvmap/DotIO.c
cmd/gvmap/DotIO.h
cmd/gvmap/gvmap.1
cmd/gvmap/gvmap.c

index d3a4208cc398b60a670a6166cdb1d571f18b785e..1ae5f99c5a06a2f9e519f105c7525af5a56062ed 100644 (file)
@@ -552,7 +552,7 @@ void Dot_SetClusterColor(Agraph_t* g, float *rgb_r,  float *rgb_g,  float *rgb_b
   }
 }
 
-SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, real **label_sizes, real **areas, real **x, int **clusters, float **rgb_r,  float **rgb_g,  float **rgb_b,  float **fsz, char ***labels, int default_color_scheme, int clustering_scheme){
+SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, real **label_sizes, real **areas, real **x, int **clusters, float **rgb_r,  float **rgb_g,  float **rgb_b,  float **fsz, char ***labels, int default_color_scheme, int clustering_scheme, int useClusters){
   SparseMatrix A = 0;
   Agnode_t* n;
   Agedge_t* e;
@@ -647,26 +647,57 @@ SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim
   A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type);
 
   /* get clustering info */
+  *clusters = MALLOC(sizeof(int)*nnodes);
   nc = 1;
   MIN_GRPS = 0;
-  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
-    i = ND_id(n);
-    if (clust_sym && (sscanf(agxget(n,clust_sym), "%d", &ic)>0)) {
-      nc = MAX(nc, ic);
-      if (first){
-       MIN_GRPS = ic;
-       first = FALSE;
+  /* if useClusters, the nodes in each top-level cluster subgraph are assigned to
+   * clusters 2, 3, .... Any nodes not in a cluster subgraph are tossed into cluster 1.
+   */
+  if (useClusters) {
+    Agraph_t* sg;
+    int gid = 1;  
+    memset (*clusters, 0, sizeof(int)*nnodes);
+    for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) {
+      if (strncmp(agnameof(sg), "cluster", 7)) continue;
+      gid++;
+      for (n = agfstnode(sg); n; n = agnxtnode (sg, n)) {
+        i = ND_id(n);
+        if ((*clusters)[i])
+          fprintf (stderr, "Warning: node %s appears in multiple clusters.\n", agnameof(n));
+        else
+          (*clusters)[i] = gid;
+      }
+    }
+    for (n = agfstnode(g); n; n = agnxtnode (g, n)) {
+      i = ND_id(n);
+      if ((*clusters)[i] == 0)
+        (*clusters)[i] = 1;
+    }
+    MIN_GRPS = 1;
+    nc = gid;
+  }
+  else if (clust_sym) {
+    for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
+      i = ND_id(n);
+      if ((sscanf(agxget(n,clust_sym), "%d", &ic)>0)) {
+        (*clusters)[i] = ic;
+        nc = MAX(nc, ic);
+        if (first){
+         MIN_GRPS = ic;
+         first = FALSE;
+        } else {
+         MIN_GRPS = MIN(MIN_GRPS, ic);
+        }
       } else {
-       MIN_GRPS = MIN(MIN_GRPS, ic);
+        noclusterinfo = TRUE;
+        break;
       }
-    } else {
-      noclusterinfo = TRUE;
     }
   }
+  else 
+    noclusterinfo = TRUE;
   MAX_GRPS = nc;
 
-  *clusters = MALLOC(sizeof(int)*nnodes);
-
   if (noclusterinfo) {
     int use_value = TRUE, flag = 0;
     real modularity;
@@ -734,11 +765,6 @@ SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim
         areap[i] = 1.0;
     }
 
-    if (!noclusterinfo && (sscanf(agxget(n, clust_sym), "%d", &ic)>0)) {
-      (*clusters)[i] = ic;
-    }
-
-
    if (agget(n, "fontsize")){
       sscanf(agget(n, "fontsize"), "%f", &ff);
       (*fsz)[i] = ff;
index b2084444898c22c43ee958e7dde3f5ee844af096..0f69bda3eb2e2cf14b0aa5d089f69c34f741e57b 100644 (file)
@@ -29,7 +29,7 @@ Agraph_t* assign_random_edge_color(Agraph_t* g);
 void dump_coordinates(char *name, int n, int dim, real *x);
 char * hue2rgb(real hue, char *color);
 
-SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, real **label_sizes, real ** areas, real **x, int **clusters, float **rgb_r,  float **rgb_g,  float **rgb_b,  float **fsz, char ***labels, int default_color_scheme, int clustering_scheme);
+SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, real **label_sizes, real ** areas, real **x, int **clusters, float **rgb_r,  float **rgb_g,  float **rgb_b,  float **fsz, char ***labels, int default_color_scheme, int clustering_scheme, int useClusters);
 
 void Dot_SetClusterColor(Agraph_t* g, float *rgb_r,  float *rgb_g,  float *rgb_b, int *clustering);
 void attached_clustering(Agraph_t* g, int maxcluster, int clustering_scheme);
index e2d537940d8a7e3ff226dc29de77e2de16b59aa6..652f19f21bb6c340fa5a38852e2e4fbf52e840d5 100644 (file)
@@ -30,10 +30,16 @@ By default,
 .B gvmap
 will generate the clusters from the data. If desired, the input graph can specify
 cluster information by giving every node a \fIcluster\fP attribute whose value is
-a small positive integer. Nodes sharing the same \fIcluster\fP attribute value will 
+a small positive integer. (It is works best if \fIcluster\fP values are all integers
+in the interval [1,K] for some K. Nodes sharing the same \fIcluster\fP attribute value will 
 be put into the same cluster. \fBN.B.\fP For the \fIcluster\fP attribute to be used,
 all nodes must have a valid value.
 .P
+If the \fI-D\fP flag is used, 
+.B  gvmap
+will use the top-level cluster subgraphs to determine the clustering. Any nodes not in
+such a cluster will be put into a single catch-all cluster.
+.P
 If the input specifies the desired clustering as described above, it can also
 specify a desired coloring by having some node in each cluster provide a
 \fIclustercolor\fP attribute. \fBN.B.\fP Unless one specifies \fI-c0\fP, only the \fIclustercolor\fP
@@ -76,6 +82,9 @@ The integer d specifies the maximum number of clusters (countries) allowed. By d
 .BI \-d " d"
 The integer d specifies the random seed used during color assignment optimization that maximize color difference between neighboring countries.
 .TP
+.BI \-D
+If specified, the graph's cluster subgraphs are used to specify the clustering.
+.TP
 .BI \-e
 If specified, edges will be included in the final output.
 .TP
index 3a3dd75d0607adb4228600b3a0fd5a468198a92e..7d130fafe69c68465feba287c7258737b876a5eb 100644 (file)
@@ -107,6 +107,7 @@ typedef struct {
     int show_points; 
     real bbox_margin[2]; 
     int whatout;
+    int useClusters;
     int plotedges;
     int color_scheme;
     real line_width;
@@ -192,6 +193,7 @@ static char* usestr =
     -c_opacity=xx - 2-character hex string for opacity of polygons\n\
     -C k - generate at most k clusters. (0)\n\
     -d s - seed used to calculate Fielder vector for optimal coloring\n\
+    -D   - use top-level cluster subgraphs to specify clustering\n\
     -e   - show edges\n\
     -g c - bounding box color. If not specified, a bounding box is not drawn.\n\
     -h k - number of artificial points added to maintain bridge between endpoints (0)\n\
@@ -277,6 +279,7 @@ init(int argc, char **argv, params_t* pm)
   pm->dim = 2;
   pm->shore_depth_tol = 0;
   pm->highlight_cluster = 0;
+  pm->useClusters = 0;
   pm->plotedges = 0;
   pm->whatout = 0;
   pm->show_points = 0;
@@ -301,7 +304,7 @@ init(int argc, char **argv, params_t* pm)
   /*  bbox_margin[0] =  bbox_margin[1] = -0.2;*/
   pm->bbox_margin[0] =  pm->bbox_margin[1] = 0;
 
-  while ((c = getopt(argc, argv, ":evOko:m:s:r:p:c:C:l:b:g:t:a:h:z:d:")) != -1) {
+  while ((c = getopt(argc, argv, ":evODko:m:s:r:p:c:C:l:b:g:t:a:h:z:d:")) != -1) {
     switch (c) {
     case 'm':
       if ((sscanf(optarg,"%lf",&s) > 0) && (s != 0)){
@@ -357,6 +360,9 @@ init(int argc, char **argv, params_t* pm)
     case 'v':
       Verbose = 1;
       break;
+    case 'D':
+      pm->useClusters = 1;
+      break;
     case 'e':
       pm->plotedges = 1;
       break;
@@ -685,7 +691,7 @@ static void mapFromGraph (Agraph_t* g, params_t* pm)
 
   initDotIO(g);
   graph = Import_coord_clusters_from_dot(g, pm->maxcluster, pm->dim, &n, &width, NULL, &x, &grouping, 
-                                          &rgb_r,  &rgb_g,  &rgb_b,  &fsz, &labels, pm->color_scheme, CLUSTERING_MODULARITY);
+                                          &rgb_r,  &rgb_g,  &rgb_b,  &fsz, &labels, pm->color_scheme, CLUSTERING_MODULARITY, pm->useClusters);
   makeMap (graph, n, x, width, grouping, labels, fsz, rgb_r, rgb_g, rgb_b, pm, g);
 }