]> granicus.if.org Git - graphviz/commitdiff
changed due to edgepaint
authorYifan Hu <yifanhu@yahoo.com>
Fri, 28 Feb 2014 17:14:01 +0000 (12:14 -0500)
committerYifan Hu <yifanhu@yahoo.com>
Fri, 28 Feb 2014 17:14:01 +0000 (12:14 -0500)
graphviz.spec.in
lib/sfdpgen/QuadTree.c
lib/sfdpgen/QuadTree.h
lib/sparse/DotIO.c
lib/sparse/DotIO.h
lib/sparse/general.c
lib/sparse/general.h

index 43c74ffd2031a29ef65403e08810550d9b37d2eb..1a210126a804a8c23261932367bcb039a69988a7 100644 (file)
@@ -215,6 +215,7 @@ of graphs (as in nodes and edges, not as in bar-charts).
 %{_bindir}/gxl2dot
 %{_bindir}/gxl2gv
 %{_bindir}/mingle
+%{_bindir}/edgepaint
 %{_bindir}/mm2gv
 %{_bindir}/neato
 %{_bindir}/nop
@@ -248,6 +249,7 @@ of graphs (as in nodes and edges, not as in bar-charts).
 %{_mandir}/man1/gvpr.1*
 %{_mandir}/man1/gxl2gv.1*
 %{_mandir}/man1/mingle.1*
+%{_mandir}/man1/edgepaint.1*
 %{_mandir}/man1/mm2gv.1*
 %{_mandir}/man1/neato.1*
 %{_mandir}/man1/nop.1*
index bd6b289d4a445de5e138f8bc800bafbd6adeb7f9..aeb14254d81b9a3984ad347cdbacc36a16856a00 100644 (file)
@@ -373,6 +373,7 @@ QuadTree QuadTree_new_from_point_list(int dim, int n, int max_level, real *coord
     center[i] = (xmin[i] + xmax[i])*0.5;
     width = MAX(width, xmax[i] - xmin[i]);
   }
+  if (width == 0) width = 0.00001;/* if we only have one point, width = 0! */
   width *= 0.52;
   qt = QuadTree_new(dim, center, width, max_level);
 
@@ -446,7 +447,7 @@ static int QuadTree_get_quadrant(int dim, real *center, real *coord){
   return d;
 }
 
-static QuadTree QuadTree_new_in_quadrant(int dim, real *center, real width, int max_level, int i){
+QuadTree QuadTree_new_in_quadrant(int dim, real *center, real width, int max_level, int i){
   /* a new quadtree in quadrant i of the original cell. The original cell is centered at 'center".
      The new cell have width "width".
    */
index bbd90485934f658a1458ed28fc703dc0e66c10e1..358cb78850cf1173b216ae9af3baa4250c1d49dd 100644 (file)
@@ -59,5 +59,6 @@ void QuadTree_get_repulsive_force(QuadTree qt, real *force, real *x, real bh, re
 /* find the nearest point and put in ymin, index in imin and distance in min */
 void QuadTree_get_nearest(QuadTree qt, real *x, real *ymin, int *imin, real *min, int *flag);
 
+QuadTree QuadTree_new_in_quadrant(int dim, real *center, real width, int max_level, int i);
 
 #endif
index 12e658aecfa6c8261f205762d96ba56d05d192ca..b2d564275c25792fe6c0a47a224db9ef7ceb393c 100644 (file)
 #include "color_palette.h"
 #include "colorutil.h"
 
+#define ag_xget(x,a) agxget(x,a)
+#define ag_xset(x,a,c) agxset(x,a,c)
+#define agedgeattr(g,a,c) (agattr(g,AGEDGE,a,c))
+#define agfindedgeattr(g,a) (agattr(g,AGEDGE,a,NULL))
+
 typedef struct {
     Agrec_t h;
     unsigned int id;
@@ -70,6 +75,52 @@ attach_embedding (Agraph_t* g, int dim, double sc, real *x)
 }
 #endif
 
+
+static void color_string(int slen, char *buf, int dim, real *color){
+  if (dim > 3 || dim < 1){
+    fprintf(stderr,"can only 1, 2 or 3 dimensional color space. with color value between 0 to 1\n");
+    assert(0);
+  }
+  assert(slen >= 3);
+  if (dim == 3){
+    sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255), 
+           MIN((unsigned int) (color[1]*255), 255), MIN((unsigned int)(color[2]*255), 255));
+  } else if (dim == 1){
+    sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255), 
+           MIN((unsigned int) (color[0]*255), 255), MIN((unsigned int)(color[0]*255), 255));
+  } else if (dim == 2){
+    sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255), 
+           0, MIN((unsigned int)(color[1]*255), 255));
+  }
+}
+
+void attach_edge_colors(Agraph_t* g, int dim, real *colors){
+  /* colors is array of dim*nedges, with color for edge i at colors[dim*i, dim(i+1))
+   */
+  Agsym_t* sym = agfindedgeattr(g, "color"); 
+  Agedge_t* e;
+  Agnode_t* n;
+  enum {slen = 1024};
+  char buf[slen];
+  int row, col;
+  int ie = 0;
+
+  if (!sym)
+    sym = agedgeattr (g, "color", "");
+
+  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
+    row = ND_id(n);
+    for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
+      col = ND_id(aghead(e));
+      if (row == col) continue;
+      color_string(slen, buf, dim, colors + ie*dim);
+      ag_xset(e, sym, buf);
+      ie++;
+    }
+  }
+
+}
+
 /* SparseMatrix_read_dot:
  * Wrapper for reading dot graph from file
  */
@@ -106,26 +157,39 @@ SparseMatrix_import_dot (Agraph_t* g, int dim, real **label_sizes, real **x, int
   real padding = 10;
   int nedge_nodes = 0;
 
+
+
   if (!g) return NULL;
   nnodes = agnnodes (g);
   nedges = agnedges (g);
-  if (format != FORMAT_CSR) {
+  if (format != FORMAT_CSR && format != FORMAT_COORD) {
     fprintf (stderr, "Format %d not supported\n", format);
     exit (1);
   }
 
+
   /* Assign node ids */
   i = 0;
   for (n = agfstnode (g); n; n = agnxtnode (g, n))
     ND_id(n) = i++;
 
-  I = N_NEW(nedges, int);
-  J = N_NEW(nedges, int);
-  val = N_NEW(nedges, real);
 
-  sym = agattr(g, AGEDGE, "weight", NULL); 
+
+  if (format == FORMAT_COORD){
+    A = SparseMatrix_new(i, i, nedges, MATRIX_TYPE_REAL, format);
+    A->nz = nedges;
+    I = A->ia;
+    J = A->ja;
+    val = (real*) A->a;
+  } else {
+    I = N_NEW(nedges, int);
+    J = N_NEW(nedges, int);
+    val = N_NEW(nedges, real);
+  }
+
+  sym = agfindedgeattr(g, "weight");
   if (D) {
-    symD = agattr(g, AGEDGE, "len", NULL); 
+    symD = agfindedgeattr(g, "len");
     valD = N_NEW(nedges, real);
   }
   i = 0;
@@ -165,26 +229,30 @@ SparseMatrix_import_dot (Agraph_t* g, int dim, real **label_sizes, real **x, int
     nedge_nodes = 0;
   }
 
-  *label_sizes = MALLOC(sizeof(real)*2*nnodes);
+
+  if (label_sizes) *label_sizes = MALLOC(sizeof(real)*2*nnodes);
   for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
     real sz;
     i = ND_id(n);
     if (edge_label_nodes && strncmp(agnameof(n), "|edgelabel|",11)==0) {
       (*edge_label_nodes)[nedge_nodes++] = i;
     }
-    if (agget(n, "width") && agget(n, "height")){
-      sscanf(agget(n, "width"), "%lf", &sz);
-      /*      (*label_sizes)[i*2] = POINTS(sz)*.6;*/
-      (*label_sizes)[i*2] = POINTS(sz)*.5 + padding*0.5;
-      sscanf(agget(n, "height"), "%lf", &sz);
-      /*(*label_sizes)[i*2+1] = POINTS(sz)*.6;*/
-      (*label_sizes)[i*2+1] = POINTS(sz)*.5  + padding*0.5;
-    } else {
-      (*label_sizes)[i*2] = 4*POINTS(0.75)*.5;
-      (*label_sizes)[i*2+1] = 4*POINTS(0.5)*.5;
+    if (label_sizes){
+      if (agget(n, "width") && agget(n, "height")){
+       sscanf(agget(n, "width"), "%lf", &sz);
+       /*      (*label_sizes)[i*2] = POINTS(sz)*.6;*/
+       (*label_sizes)[i*2] = POINTS(sz)*.5 + padding*0.5;
+       sscanf(agget(n, "height"), "%lf", &sz);
+       /*(*label_sizes)[i*2+1] = POINTS(sz)*.6;*/
+       (*label_sizes)[i*2+1] = POINTS(sz)*.5  + padding*0.5;
+      } else {
+       (*label_sizes)[i*2] = 4*POINTS(0.75)*.5;
+       (*label_sizes)[i*2+1] = 4*POINTS(0.5)*.5;
+      }
     }
  }
 
+
   if (x && (psym = agattr(g, AGNODE, "pos", NULL))) {
     int has_positions = TRUE;
     char* pval;
@@ -244,19 +312,68 @@ SparseMatrix_import_dot (Agraph_t* g, int dim, real **label_sizes, real **x, int
   else if (x)
     agerr (AGERR, "Error: graph %s has missing \"pos\" information", agnameof(g));
 
-  A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
+
+  if (format == FORMAT_CSR) A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
   if (edge_label_nodes) *n_edge_label_nodes = nedge_nodes;
 
   if (D) *D = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, valD, type, sz);
 
-  FREE(I);
-  FREE(J);
-  FREE(val);
+  if (format != FORMAT_COORD){
+    FREE(I);
+    FREE(J);
+    FREE(val);
+  }
   if (valD) FREE(valD);
 
   return A;
 }
 
+/* get spline info */
+int Import_dot_splines(Agraph_t* g, int *ne, char ***xsplines){
+  /* get the list of splines for the edges in the order they appear, and store as a list of strings in xspline.
+     If *xsplines = NULL, it will be allocated. On exit (*xsplines)[i] is the control point string for the i-th edge. This string
+     is of the form "x1,y1 x2,y2...", the two end points of the edge is not included per Dot format 
+     Return 1 if success. 0 if not.
+  */
+  Agnode_t* n;
+  Agedge_t* e;
+  Agsym_t *sym;
+  int nedges;
+  int i;
+
+  if (!g){
+    return 0;
+  }
+
+  *ne = nedges = agnedges (g);
+
+  /* Assign node ids */
+  i = 0;
+  for (n = agfstnode (g); n; n = agnxtnode (g, n))
+    ND_id(n) = i++;
+
+  sym = agattr(g, AGEDGE, "pos", NULL); 
+  if (!sym) return 0;
+
+  if (!(*xsplines)) *xsplines = malloc(sizeof(char*)*nedges);
+
+  i = 0;
+  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
+    for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
+      /* edge weight */
+      if (sym) {
+       char *pos = ag_xget (e, sym);
+       (*xsplines)[i] = malloc(sizeof(char)*(strlen(pos)+1));
+       strcpy((*xsplines)[i], pos);
+      } else {
+       (*xsplines)[i] = NULL;
+      }
+      i++;
+    }
+  }
+  return 1;
+}
+
 static real dist(int dim, real *x, real *y){
   int k;
   real d = 0;
@@ -646,6 +763,17 @@ Agraph_t* assign_random_edge_color(Agraph_t* g){
   return g;
  }
 
+
+static int hex2int(char h){
+  if (h >= '0' && h <= '9') return h - '0';
+  if (h >= 'a' && h <= 'f') return 10 + h - 'a';
+  if (h >= 'A' && h <= 'F') return 10 + h - 'A';
+  return 0;
+}  
+static float hexcol2rgb(char *h){
+  return (hex2int(h[0])*16 + hex2int(h[1]))/255.;
+}
+
 void Dot_SetClusterColor(Agraph_t* g, float *rgb_r,  float *rgb_g,  float *rgb_b, int *clusters){
 
   Agnode_t* n;
@@ -911,6 +1039,13 @@ SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim
      (*rgb_b)[(*clusters)[i]] = color.u.RGBA[2];
    }
 
+   if (!noclusterinfo && agget(n, "cluster") && agget(n, "clustercolor") && strlen(agget(n, "clustercolor") ) >= 7 && pal){
+     char cc[10];
+     strcpy(cc, agget(n, "clustercolor"));
+     (*rgb_r)[(*clusters)[i]] = hexcol2rgb(cc+1);
+     (*rgb_g)[(*clusters)[i]] = hexcol2rgb(cc+3);
+     (*rgb_b)[(*clusters)[i]] = hexcol2rgb(cc+5);
+   }
 
   }
 
index 00258b03bb041d13b081b55bb8d6f04d167eedea..8057421c1ed254356fe36543163a524319807e96 100644 (file)
@@ -24,6 +24,10 @@ extern Agraph_t* SparseMatrix_read_dot(FILE*);
 extern void setDotNodeID (Agnode_t* n, int v);
 extern int getDotNodeID (Agnode_t* n);
 
+extern void attach_edge_colors(Agraph_t* g, int dim, real *colors);
+
+extern void attach_embedding(Agraph_t *g, int dim, double sc, real *x);
+
 /* extern void attach_embedding(Agraph_t *g, int dim, double sc, real *x); */
 extern SparseMatrix SparseMatrix_import_dot(Agraph_t* g, int dim, real **label_sizes, real **x, int *n_edge_label_nodes,
                                            int **edge_label_nodes, int format, SparseMatrix *D);
@@ -39,4 +43,5 @@ SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim
 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);
 
+int Import_dot_splines(Agraph_t* g, int *ne, char ***xsplines);
 #endif
index bf2c6333ad670b5623a49266f701e79606e21e71..7bdc79e4fa447ab6b32ffe266db3d174cd0d07f9 100644 (file)
@@ -207,7 +207,7 @@ int comp_ascend_int(const void *s1, const void *s2){
 
 
 void vector_ordering(int n, real *v, int **p, int ascending){
-  /* give the position of the lagest, second largest etc in vector v if ascending = TRUE
+  /* give the position of the lagest, second largest etc in vector v if ascending = FALSE
 
      or
 
@@ -271,7 +271,6 @@ int excute_system_command(char *s1, char *s2){
   return system(c);
 }
 
-
 real distance_cropped(real *x, int dim, int i, int j){
   int k;
   real dist = 0.;
@@ -298,6 +297,7 @@ real point_distance(real *p1, real *p2, int dim){
 
 char *strip_dir(char *s){
   int i, first = TRUE;
+  if (!s) return s;
   for (i = strlen(s); i >= 0; i--) {
     if (first && s[i] == '.') {/* get rid of .mtx */
       s[i] = '\0';
@@ -342,3 +342,24 @@ void scale_to_box(real xmin, real ymin, real xmax, real ymax, int n, int dim, re
   
   
 }
+
+int digitsQ(char *s){
+  while (*s && *s - '0' >= 0 && *s - '0' <= 9) {
+    s++;
+  }
+  if (*s) return 0;
+  return 1;
+}
+int validQ_int_string(char *to_convert, int *v){
+  /* check to see if this is a string is integer */
+  char *p = to_convert;
+  int errno = 0;
+  long val = strtoul(to_convert, &p, 10);
+  if (errno != 0 ||// conversion failed (EINVAL, ERANGE)
+      to_convert == p || // conversion failed (no characters consumed)
+      *p != 0
+      ) return 0;
+  if (val > INT_MAX || val < INT_MIN) return 0;
+  *v = (int) val;
+  return 1;
+}
index 9411d86fd891d5b83220983114a221b49e099e3c..f8996e526ecd770b356cfea229f1cd6c01983ffb 100644 (file)
@@ -116,6 +116,8 @@ real vector_percentile(int n, real *x, real y);/* find the value such that y% of
 void vector_print(char *s, int n, real *x);
 
 #define MACHINEACC 1.0e-16
+#define SQRT_MACHINEACC 1.0e-8
+
 
 int excute_system_command3(char *s1, char *s2, char *s3);
 int excute_system_command(char *s1, char *s2);
@@ -134,6 +136,12 @@ char *strip_dir(char *s);
 
 void scale_to_box(real xmin, real ymin, real xmax, real ymax, int n, int dim, real *x);
 
+/* check to see if this is a string is integer (that can be casted into an integer variable hence very long list of digits are not valid, like 123456789012345. Return 1 if true, 0 if false. */
+int validQ_int_string(char *to_convert, int *v);
+
+/* check to see if this is a string of digits consists of 0-9 */
+int digitsQ(char *to_convert);
+
 #endif