Graphviz  2.41.20171026.1811
DotIO.c
Go to the documentation of this file.
1 /* $Id$Revision: */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 #define STANDALONE
15 #include "general.h"
16 #include "DotIO.h"
17 #include "clustering.h"
18 #include "mq.h"
19 /* #include "spring_electrical.h" */
20 #include "color_palette.h"
21 #include "colorutil.h"
22 
23 typedef struct {
25  unsigned int id;
26 } Agnodeinfo_t;
27 
28 #define ND_id(n) (((Agnodeinfo_t*)((n)->base.data))->id)
29 
30 #if 0
31 static void
32 posStr (int len_buf, char* buf, int dim, real* x, double sc)
33 {
34  char s[1000];
35  int i;
36  int len = 0;
37 
38  buf[0] = '\0';
39  for (i = 0; i < dim; i++){
40  if (i < dim - 1){
41  sprintf(s,"%f,",sc*x[i]);
42  } else {
43  sprintf(s,"%f",sc*x[i]);
44  }
45  len += strlen(s);
46  assert(len < len_buf);
47  buf = strcat(buf, s);
48  }
49 }
50 
51 static void
52 attach_embedding (Agraph_t* g, int dim, double sc, real *x)
53 {
54  Agsym_t* sym = agattr(g, AGNODE, "pos", NULL);
55  Agnode_t* n;
56 #define SLEN 1024
57  char buf[SLEN];
58  int i = 0;
59 
60  if (!sym)
61  sym = agattr (g, AGNODE, "pos", "");
62 
63  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
64  assert (i == ND_id(n));
65  posStr (SLEN, buf, dim, x + i*dim, sc);
66  agxset (n, sym, buf);
67  i++;
68  }
69 
70 }
71 #endif
72 
73 static void color_string(int slen, char *buf, int dim, real *color){
74  if (dim > 3 || dim < 1){
75  fprintf(stderr,"can only 1, 2 or 3 dimensional color space. with color value between 0 to 1\n");
76  assert(0);
77  }
78  assert(slen >= 3);
79  if (dim == 3){
80  sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255),
81  MIN((unsigned int) (color[1]*255), 255), MIN((unsigned int)(color[2]*255), 255));
82  } else if (dim == 1){
83  sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255),
84  MIN((unsigned int) (color[0]*255), 255), MIN((unsigned int)(color[0]*255), 255));
85  } else if (dim == 2){
86  sprintf(buf,"#%02x%02x%02x", MIN((unsigned int)(color[0]*255),255),
87  0, MIN((unsigned int)(color[1]*255), 255));
88  }
89 }
90 
91 void attach_edge_colors(Agraph_t* g, int dim, real *colors){
92  /* colors is array of dim*nedges, with color for edge i at colors[dim*i, dim(i+1))
93  */
94  Agsym_t* sym = agattr(g, AGEDGE, "color", 0);
95  Agedge_t* e;
96  Agnode_t* n;
97  enum {slen = 1024};
98  char buf[slen];
99  int row, col;
100  int ie = 0;
101 
102  if (!sym)
103  sym = agattr (g, AGEDGE, "color", "");
104 
105  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
106  row = ND_id(n);
107  for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
108  col = ND_id(aghead(e));
109  if (row == col) continue;
110  color_string(slen, buf, dim, colors + ie*dim);
111  agxset(e, sym, buf);
112  ie++;
113  }
114  }
115 
116 }
117 
118 /* SparseMatrix_read_dot:
119  * Wrapper for reading dot graph from file
120  */
121 Agraph_t*
123 {
124  Agraph_t* g;
125  g = agread (f, 0);
126  aginit(g, AGNODE, "nodeinfo", sizeof(Agnodeinfo_t), TRUE);
127  return g;
128 }
129 
130 /* SparseMatrix_import_dot:
131  * Assumes g is connected and simple, i.e., we can have a->b and b->a
132  * but not a->b and a->b
133  */
135 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)
136 {
137  SparseMatrix A = 0;
138  Agnode_t* n;
139  Agedge_t* e;
140  Agsym_t *sym, *symD = NULL;
141  Agsym_t *psym;
142  int nnodes;
143  int nedges;
144  int i, row;
145  int* I;
146  int* J;
147  real *val, *valD = NULL;
148  real v;
149  int type = MATRIX_TYPE_REAL;
150  size_t sz = sizeof(real);
151  real padding = 10;
152  int nedge_nodes = 0;
153 
154 
155 
156  if (!g) return NULL;
157  nnodes = agnnodes (g);
158  nedges = agnedges (g);
159  if (format != FORMAT_CSR && format != FORMAT_COORD) {
160  fprintf (stderr, "Format %d not supported\n", format);
161  exit (1);
162  }
163 
164  /* Assign node ids */
165  i = 0;
166  for (n = agfstnode (g); n; n = agnxtnode (g, n))
167  ND_id(n) = i++;
168 
169  if (format == FORMAT_COORD){
170  A = SparseMatrix_new(i, i, nedges, MATRIX_TYPE_REAL, format);
171  A->nz = nedges;
172  I = A->ia;
173  J = A->ja;
174  val = (real*) A->a;
175  } else {
176  I = N_NEW(nedges, int);
177  J = N_NEW(nedges, int);
178  val = N_NEW(nedges, real);
179  }
180 
181 
182  if (format == FORMAT_COORD){
183  A = SparseMatrix_new(i, i, nedges, MATRIX_TYPE_REAL, format);
184  A->nz = nedges;
185  I = A->ia;
186  J = A->ja;
187  val = (real*) A->a;
188  } else {
189  I = N_NEW(nedges, int);
190  J = N_NEW(nedges, int);
191  val = N_NEW(nedges, real);
192  }
193 
194  sym = agattr(g, AGEDGE, "weight", NULL);
195  if (D) {
196  symD = agattr(g, AGEDGE, "len", NULL);
197  valD = N_NEW(nedges, real);
198  }
199  i = 0;
200  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
201  if (edge_label_nodes && strncmp(agnameof(n), "|edgelabel|",11)==0) nedge_nodes++;
202  row = ND_id(n);
203  for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
204  I[i] = row;
205  J[i] = ND_id(aghead(e));
206 
207  /* edge weight */
208  if (sym) {
209  if (sscanf (agxget(e,sym), "%lf", &v) != 1) v = 1;
210  } else {
211  v = 1;
212  }
213  val[i] = v;
214 
215  /* edge length */
216  if (symD) {
217  if (sscanf (agxget (e, symD), "%lf", &v) != 1) {
218  v = 72;
219  } else {
220  v *= 72;/* len is specified in inch. Convert to points */
221  }
222  valD[i] = v;
223  } else if (valD) {
224  valD[i] = 72;
225  }
226 
227  i++;
228  }
229  }
230 
231  if (edge_label_nodes) {
232  *edge_label_nodes = MALLOC(sizeof(int)*nedge_nodes);
233  nedge_nodes = 0;
234  }
235 
236 
237  if (label_sizes) *label_sizes = MALLOC(sizeof(real)*2*nnodes);
238  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
239  real sz;
240  i = ND_id(n);
241  if (edge_label_nodes && strncmp(agnameof(n), "|edgelabel|",11)==0) {
242  (*edge_label_nodes)[nedge_nodes++] = i;
243  }
244  if (label_sizes){
245  if (agget(n, "width") && agget(n, "height")){
246  sscanf(agget(n, "width"), "%lf", &sz);
247  /* (*label_sizes)[i*2] = POINTS(sz)*.6;*/
248  (*label_sizes)[i*2] = POINTS(sz)*.5 + padding*0.5;
249  sscanf(agget(n, "height"), "%lf", &sz);
250  /*(*label_sizes)[i*2+1] = POINTS(sz)*.6;*/
251  (*label_sizes)[i*2+1] = POINTS(sz)*.5 + padding*0.5;
252  } else {
253  (*label_sizes)[i*2] = 4*POINTS(0.75)*.5;
254  (*label_sizes)[i*2+1] = 4*POINTS(0.5)*.5;
255  }
256  }
257  }
258 
259  if (x && (psym = agattr(g, AGNODE, "pos", NULL))) {
260  int has_positions = TRUE;
261  char* pval;
262  if (!(*x)) {
263  *x = MALLOC(sizeof(real)*dim*nnodes);
264  assert(*x);
265  }
266  for (n = agfstnode (g); n && has_positions; n = agnxtnode (g, n)) {
267  real xx,yy, zz,ww;
268  int nitems;
269  i = ND_id(n);
270  if ((pval = agxget(n, psym)) && *pval) {
271  if (dim == 2){
272  nitems = sscanf(pval, "%lf,%lf", &xx, &yy);
273  if (nitems != 2) {
274  has_positions = FALSE;
275  agerr(AGERR, "Node \"%s\" pos has %d < 2 values", agnameof(n), nitems);
276  }
277  (*x)[i*dim] = xx;
278  (*x)[i*dim+1] = yy;
279  } else if (dim == 3){
280  nitems = sscanf(pval, "%lf,%lf,%lf", &xx, &yy, &zz);
281  if (nitems != 3) {
282  has_positions = FALSE;
283  agerr(AGERR, "Node \"%s\" pos has %d < 3 values", agnameof(n), nitems);
284  }
285  (*x)[i*dim] = xx;
286  (*x)[i*dim+1] = yy;
287  (*x)[i*dim+2] = zz;
288  } else if (dim == 4){
289  nitems = sscanf(pval, "%lf,%lf,%lf,%lf", &xx, &yy, &zz,&ww);
290  if (nitems != 4) {
291  has_positions = FALSE;
292  agerr(AGERR, "Node \"%s\" pos has %d < 4 values", agnameof(n), nitems);
293  }
294  (*x)[i*dim] = xx;
295  (*x)[i*dim+1] = yy;
296  (*x)[i*dim+2] = zz;
297  (*x)[i*dim+3] = ww;
298  } else if (dim == 1){
299  nitems = sscanf(pval, "%lf", &xx);
300  if (nitems != 1) return NULL;
301  (*x)[i*dim] = xx;
302  } else {
303  assert(0);
304  }
305  } else {
306  has_positions = FALSE;
307  agerr(AGERR, "Node \"%s\" lacks position info", agnameof(n));
308  }
309  }
310  if (!has_positions) {
311  FREE(*x);
312  *x = NULL;
313  }
314  }
315  else if (x)
316  agerr (AGERR, "Error: graph %s has missing \"pos\" information", agnameof(g));
317 
318  if (format == FORMAT_CSR) A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
319  if (edge_label_nodes) *n_edge_label_nodes = nedge_nodes;
320 
321  if (D) *D = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, valD, type, sz);
322 
323  if (format != FORMAT_COORD){
324  FREE(I);
325  FREE(J);
326  FREE(val);
327  }
328  if (valD) FREE(valD);
329 
330  return A;
331 }
332 
333 
334 static real dist(int dim, real *x, real *y){
335  int k;
336  real d = 0;
337  for (k = 0; k < dim; k++) d += (x[k] - y[k])*(x[k]-y[k]);
338  return sqrt(d);
339 }
340 
341 /* get spline info */
342 int Import_dot_splines(Agraph_t* g, int *ne, char ***xsplines){
343  /* get the list of splines for the edges in the order they appear, and store as a list of strings in xspline.
344  If *xsplines = NULL, it will be allocated. On exit (*xsplines)[i] is the control point string for the i-th edge. This string
345  is of the form "x1,y1 x2,y2...", the two end points of the edge is not included per Dot format
346  Return 1 if success. 0 if not.
347  */
348  Agnode_t* n;
349  Agedge_t* e;
350  Agsym_t *sym;
351  int nedges;
352  int i;
353 
354  if (!g){
355  return 0;
356  }
357 
358  *ne = nedges = agnedges (g);
359 
360  /* Assign node ids */
361  i = 0;
362  for (n = agfstnode (g); n; n = agnxtnode (g, n))
363  ND_id(n) = i++;
364 
365  sym = agattr(g, AGEDGE, "pos", 0);
366  if (!sym) return 0;
367 
368  if (!(*xsplines)) *xsplines = malloc(sizeof(char*)*nedges);
369 
370  i = 0;
371  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
372  for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
373  /* edge weight */
374  if (sym) {
375  char *pos = agxget (e, sym);
376  (*xsplines)[i] = malloc(sizeof(char)*(strlen(pos)+1));
377  strcpy((*xsplines)[i], pos);
378  } else {
379  (*xsplines)[i] = NULL;
380  }
381  i++;
382  }
383  }
384  return 1;
385 }
386 
387 void edgelist_export(FILE* f, SparseMatrix A, int dim, real *x){
388  int n = A->m, *ia = A->ia, *ja = A->ja;
389  int i, j, len;
390  real max_edge_len, min_edge_len;
391 
392  for (i = 0; i < n; i++){
393  for (j = ia[i]; j < ia[i+1]; j++){
394  max_edge_len = MAX(max_edge_len, dist(dim, &x[dim*i], &x[dim*ja[j]]));
395  if (min_edge_len < 0){
396  min_edge_len = dist(dim, &x[dim*i], &x[dim*ja[j]]);
397  } else {
398  min_edge_len = MIN(min_edge_len, dist(dim, &x[dim*i], &x[dim*ja[j]]));
399  }
400  }
401  }
402  /* format:
403  n
404  nz
405  dim
406  x (length n*dim)
407  min_edge_length
408  max_edge_length
409  v1
410  neighbors of v1
411  v2
412  neighbors of v2
413  ...
414  */
415  fprintf(stderr,"writing a total of %d edges\n",A->nz);
416  fwrite(&(A->n), sizeof(int), 1, f);
417  fwrite(&(A->nz), sizeof(int), 1, f);
418  fwrite(&dim, sizeof(int), 1, f);
419  fwrite(x, sizeof(real), dim*n, f);
420  fwrite(&min_edge_len, sizeof(real), 1, f);
421  fwrite(&max_edge_len, sizeof(real), 1, f);
422  for (i = 0; i < n; i++){
423  if (i%1000 == 0) fprintf(stderr,"%6.2f%% done\r", i/(real) n*100);
424  fwrite(&i, sizeof(int), 1, f);
425  len = ia[i+1] - ia[i];
426  fwrite(&len, sizeof(int), 1, f);
427  fwrite(&(ja[ia[i]]), sizeof(int), len, f);
428  }
429 }
430 
431 
432 void dump_coordinates(char *name, int n, int dim, real *x){
433  char fn[1000];
434  FILE *fp;
435  int i, k;
436 
437  if (!name){
438  name = "";
439  } else {
440  name = strip_dir(name);
441  }
442 
443  strcpy(fn, name);
444  strcat(fn,".x");
445  fp = fopen(fn,"w");
446  fprintf(fp, "%d %d\n",n, dim);
447  for (i = 0; i < n; i++){
448  for (k = 0; k < dim; k++){
449  fprintf(fp,"%f ",x[i*dim+k]);
450  }
451  fprintf(fp,"\n");
452  }
453  fclose(fp);
454 
455 }
456 
457 static Agnode_t*
458 mkNode (Agraph_t* g, char* name)
459 {
460  Agnode_t* n = agnode(g, name, 1);
461  agbindrec(n, "info", sizeof(Agnodeinfo_t), TRUE);
462  return n;
463 }
464 
465 Agraph_t*
466 makeDotGraph (SparseMatrix A, char *name, int dim, real *x, int with_color, int with_label, int use_matrix_value)
467 {
468  Agraph_t* g;
469  Agnode_t* n;
470  Agnode_t* h;
471  Agedge_t* e;
472  int i, j;
473  char buf[1024], buf2[1024];
474  Agsym_t *sym, *sym2 = NULL, *sym3 = NULL;
475  int* ia=A->ia;
476  int* ja=A->ja;
477  real* val = (real*)(A->a);
478  Agnode_t** arr = N_NEW (A->m, Agnode_t*);
479  real *color = NULL;
480  char cstring[8];
481  char *label_string;
482 
483  if (!name){
484  name = "stdin";
485  } else {
486  name = strip_dir(name);
487  }
488  label_string = MALLOC(sizeof(char)*1000);
489 
491  g = agopen ("G", Agundirected, 0);
492  } else {
493  g = agopen ("G", Agdirected, 0);
494  }
495  sprintf (buf, "%f", 1.0);
496 
497  label_string = strcpy(label_string, name);
498  label_string = strcat(label_string, ". ");
499  sprintf (buf, "%d", A->m);
500  label_string = strcat(label_string, buf);
501  label_string = strcat(label_string, " nodes, ");
502  sprintf (buf, "%d", A->nz);
503  label_string = strcat(label_string, buf);
504  /* label_string = strcat(label_string, " edges. Created by Yifan Hu");*/
505  label_string = strcat(label_string, " edges.");
506 
507 
508  if (with_label) sym = agattr(g, AGRAPH, "label", label_string);
509  sym = agattr(g, AGRAPH, "fontcolor", "#808090");
510  if (with_color) sym = agattr(g, AGRAPH, "bgcolor", "black");
511  sym = agattr(g, AGRAPH, "outputorder", "edgesfirst");
512 
513  if (A->m > 100) {
514  /* -Estyle=setlinewidth(0.0)' -Eheadclip=false -Etailclip=false -Nstyle=invis*/
515  agattr(g, AGNODE, "style", "invis");
516  } else {
517  /* width=0, height = 0, label="", style=filled*/
518  agattr(g, AGNODE, "shape", "point");
519  if (A->m < 50){
520  agattr(g, AGNODE, "width", "0.03");
521  } else {
522  agattr(g, AGNODE, "width", "0");
523  }
524  agattr(g, AGNODE, "label", "");
525  agattr(g, AGNODE, "style", "filled");
526  if (with_color) {
527  agattr(g, AGNODE, "color", "#FF0000");
528  } else {
529  agattr(g, AGNODE, "color", "#000000");
530  }
531  }
532 
533  agattr(g, AGEDGE, "headclip", "false");
534  agattr(g, AGEDGE, "tailclip", "false");
535  if (A->m < 50){
536  agattr(g, AGEDGE, "style", "setlinewidth(2)");
537  } else if (A->m < 500){
538  agattr(g, AGEDGE, "style", "setlinewidth(0.5)");
539  } else if (A->m < 5000){
540  agattr(g, AGEDGE, "style", "setlinewidth(0.1)");
541  } else {
542  agattr(g, AGEDGE, "style", "setlinewidth(0.0)");
543  }
544 
545  if (with_color) {
546  sym2 = agattr(g, AGEDGE, "color", "");
547  sym3 = agattr(g, AGEDGE, "wt", "");
548  }
549  for (i = 0; i < A->m; i++) {
550  sprintf (buf, "%d", i);
551  n = mkNode (g, buf);
552  ND_id(n) = i;
553  arr[i] = n;
554  }
555 
556  if (with_color){
557  real maxdist = 0.;
558  real mindist = 0.;
559  int first = TRUE;
560  color = malloc(sizeof(real)*A->nz);
561  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
562  i = ND_id(n);
563  if (A->type != MATRIX_TYPE_REAL || !use_matrix_value){
564  for (j = ia[i]; j < ia[i+1]; j++) {
565  color[j] = distance(x, dim, i, ja[j]);
566  if (i != ja[j]){
567  if (first){
568  mindist = color[j];
569  first = FALSE;
570  } else {
571  mindist = MIN(mindist, color[j]);
572  }
573  }
574  maxdist = MAX(color[j], maxdist);
575  }
576  } else {
577  for (j = ia[i]; j < ia[i+1]; j++) {
578  color[j] = ABS(val[j]);
579  if (i != ja[j]){
580  if (first){
581  mindist = color[j];
582  first = FALSE;
583  } else {
584  mindist = MIN(mindist, color[j]);
585  }
586  }
587  maxdist = MAX(color[j], maxdist);
588  }
589  }
590  }
591  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
592  i = ND_id(n);
593  for (j = ia[i]; j < ia[i+1]; j++) {
594  if (i != ja[j]){
595  color[j] = ((color[j] - mindist)/MAX(maxdist-mindist, 0.000001));
596  } else {
597  color[j] = 0;
598  }
599  }
600  }
601  }
602 
603  i = 0;
604  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
605  i = ND_id(n);
606  for (j = ia[i]; j < ia[i+1]; j++) {
607  h = arr [ja[j]];
608  if (val){
609  switch (A->type){
610  case MATRIX_TYPE_REAL:
611  sprintf (buf, "%f", ((real*)A->a)[j]);
612  break;
613  case MATRIX_TYPE_INTEGER:
614  sprintf (buf, "%d", ((int*)A->a)[j]);
615  break;
616  case MATRIX_TYPE_COMPLEX:/* take real part as weight */
617  sprintf (buf, "%f", ((real*)A->a)[2*j]);
618  break;
619  }
620  if (with_color) {
621  if (i != ja[j]){
622  sprintf (buf2, "%s", hue2rgb(.65*color[j], cstring));
623  } else {
624  sprintf (buf2, "#000000");
625  }
626  }
627  } else {
628  sprintf (buf, "%f", 1.);
629  if (with_color) {
630  if (i != ja[j]){
631  sprintf (buf2, "%s", hue2rgb(.65*color[j], cstring));
632  } else {
633  sprintf (buf2, "#000000");
634  }
635  }
636  }
637  e = agedge (g, n, h, NULL, 1);
638  if (with_color) {
639  agxset (e, sym2, buf2);
640  sprintf (buf2, "%f", color[j]);
641  agxset (e, sym3, buf2);
642  }
643  }
644  }
645 
646  FREE(color);
647  FREE (arr);
648  FREE(label_string);
649  return g;
650 }
651 
652 
653 char *cat_string(char *s1, char *s2){
654  char *s;
655  s = malloc(sizeof(char)*(strlen(s1)+strlen(s2)+1+1));
656  strcpy(s,s1);
657  strcat(s,"|");
658  strcat(s,s2);
659  return s;
660 }
661 
662 char *cat_string3(char *s1, char *s2, char *s3, int id){
663  char *s;
664  char sid[1000];
665  sprintf(sid,"%d",id);
666  s = malloc(sizeof(char)*(strlen(s1)+strlen(s2)+strlen(s3)+strlen(sid)+1+3));
667  strcpy(s,s1);
668  strcat(s,"|");
669  strcat(s,s2);
670  strcat(s,"|");
671  strcat(s,s3);
672  strcat(s,"|");
673  strcat(s,sid);
674  return s;
675 }
676 
677 
679  if (!g) return NULL;
680 
681  Agnode_t *n, *newnode;
682  Agraph_t *dg;
683 
684  int nnodes;
685  int nedges;
686 
687 
688  Agedge_t *ep, *e;
689  int i = 0;
690  Agnode_t **ndmap = NULL;
691  char *s;
692  char *elabel;
693  int id = 0;
694 
695  Agsym_t* sym = agattr(g, AGEDGE, "label", NULL);
696 
697  dg = agopen("test", g->desc, 0);
698 
699  nnodes = agnnodes (g);
700  nedges = agnedges (g);
701 
702  ndmap = malloc(sizeof(Agnode_t *)*nnodes);
703 
704  agattr(dg, AGNODE, "label", "\\N");
705  agattr(dg, AGNODE, "shape", "ellipse");
706  agattr(dg, AGNODE, "width","0.00001");
707  agattr(dg, AGNODE, "height", "0.00001");
708  agattr(dg, AGNODE, "margin","0.");
709  agattr(dg, AGEDGE, "arrowsize", "0.5");
710 
711  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
712  newnode = mkNode(dg, agnameof(n));
713  agset(newnode,"shape","box");
714  ndmap[i] = newnode;
715  ND_id(n) = i++;
716  }
717 
718 
719  /*
720  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
721  for (ep = agfstedge(g, n); ep; ep = agnxtedge(g, ep, n)) {
722  if (agtail(ep) == n) continue;
723  agedge(dg, ndmap[ND_id(agtail(ep))], ndmap[ND_id(aghead(ep))]);
724  }
725  }
726  */
727 
728 
729 
730  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
731  for (ep = agfstedge(g, n); ep; ep = agnxtedge(g, ep, n)) {
732  if (agtail(ep) == n && (aghead(ep) != n)) continue;
733  if (sym && (elabel = agxget(ep,sym)) && strcmp(elabel,"") != 0) {
734  s = cat_string3("|edgelabel",agnameof(agtail(ep)), agnameof(aghead(ep)), id++);
735  newnode = mkNode(dg,s);
736  agset(newnode,"label",elabel);
737  agset(newnode,"shape","plaintext");
738  e = agedge(dg, ndmap[ND_id(agtail(ep))], newnode, NULL, 1);
739  agset(e, "arrowsize","0");
740  agedge(dg, newnode, ndmap[ND_id(aghead(ep))], NULL, 1);
741  free(s);
742  } else {
743  agedge(dg, ndmap[ND_id(agtail(ep))], ndmap[ND_id(aghead(ep))], NULL, 1);
744  }
745  }
746  }
747 
748  free(ndmap);
749  return dg;
750  }
751 
753  char cstring[8];
754  char buf2[1024];
755  Agsym_t *sym2;
756  Agnode_t* n;
757  Agedge_t *ep;
758 
759  sym2 = agattr(g, AGEDGE, "color", "");
760  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
761  for (ep = agfstedge(g, n); ep; ep = agnxtedge(g, ep, n)) {
762  sprintf (buf2, "%s", hue2rgb(0.65*drand(), cstring));
763  agxset (ep, sym2, buf2);
764  }
765  }
766 
767  return g;
768  }
769 
770 
771 static int hex2int(char h){
772  if (h >= '0' && h <= '9') return h - '0';
773  if (h >= 'a' && h <= 'f') return 10 + h - 'a';
774  if (h >= 'A' && h <= 'F') return 10 + h - 'A';
775  return 0;
776 }
777 static float hexcol2rgb(char *h){
778  return (hex2int(h[0])*16 + hex2int(h[1]))/255.;
779 }
780 
781 void Dot_SetClusterColor(Agraph_t* g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters){
782 
783  Agnode_t* n;
784  char scluster[20];
785  int i;
786  Agsym_t* clust_clr_sym = agattr(g, AGNODE, "clustercolor", NULL);
787 
788  if (!clust_clr_sym) clust_clr_sym = agattr(g, AGNODE, "clustercolor", "-1");
789  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
790  i = ND_id(n);
791  if (rgb_r && rgb_g && rgb_b) {
792  rgb2hex((rgb_r)[(clusters)[i]],(rgb_g)[(clusters)[i]],(rgb_b)[(clusters)[i]], scluster, NULL);
793  //sprintf(scluster,"#%2x%2x%2x", (int) (255*((rgb_r)[(clusters)[i]])), (int) (255*((rgb_g)[(clusters)[i]])), (int) (255*((rgb_b)[(clusters)[i]])));
794  }
795  agxset(n,clust_clr_sym,scluster);
796  }
797 }
798 
799 SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, real **label_sizes, 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){
800  SparseMatrix A = 0;
801  Agnode_t* n;
802  Agedge_t* e;
803  Agsym_t* sym;
804  Agsym_t* clust_sym;
805  Agsym_t* clust_clr_sym;
806  int nnodes;
807  int nedges;
808  int i, row, ic,nc, j;
809  int* I;
810  int* J;
811  real* val;
812  real v;
813  int type = MATRIX_TYPE_REAL;
814  size_t sz = sizeof(real);
815  char scluster[100];
816  float ff;
817 
818  int MAX_GRPS, MIN_GRPS, noclusterinfo = FALSE, first = TRUE;
819  float *pal;
820  int max_color = MAX_COLOR;
821 
822  switch (default_color_scheme){
824  pal = &(palette_blue_to_yellow[0][0]);
825  break;
827  pal = &(palette_white_to_red[0][0]);
828  break;
830  pal = &(palette_grey_to_red[0][0]);
831  break;
832  case COLOR_SCHEME_GREY:
833  pal = &(palette_grey[0][0]);
834  break;
835  case COLOR_SCHEME_PASTEL:
836  pal = &(palette_pastel[0][0]);
837  break;
839  fprintf(stderr," HERE!\n");
840  pal = &(palette_sequential_singlehue_red[0][0]);
841  break;
843  fprintf(stderr," HERE!\n");
845  break;
847  pal = &(palette_primary[0][0]);
848  break;
850  pal = &(palette_adam_blend[0][0]);
851  break;
852  case COLOR_SCHEME_ADAM:
853  pal = &(palette_adam[0][0]);
854  max_color = 11;
855  break;
856  case COLOR_SCHEME_NONE:
857  pal = NULL;
858  break;
859  default:
860  pal = &(palette_pastel[0][0]);
861  break;
862  }
863 
864  if (!g) return NULL;
865  nnodes = agnnodes (g);
866  nedges = agnedges (g);
867  *nn = nnodes;
868 
869  /* Assign node ids */
870  i = 0;
871  for (n = agfstnode (g); n; n = agnxtnode (g, n))
872  ND_id(n) = i++;
873 
874  /* form matrix */
875  I = N_NEW(nedges, int);
876  J = N_NEW(nedges, int);
877  val = N_NEW(nedges, real);
878 
879  sym = agattr(g, AGEDGE, "weight", NULL);
880  clust_sym = agattr(g, AGNODE, "cluster", NULL);
881  clust_clr_sym = agattr(g, AGNODE, "clustercolor", NULL);
882  //sym = agattr(g, AGEDGE, "wt", NULL);
883  i = 0;
884  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
885  row = ND_id(n);
886  for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
887  I[i] = row;
888  J[i] = ND_id(aghead(e));
889  if (sym) {
890  if (sscanf (agxget(e,sym), "%lf", &v) != 1)
891  v = 1;
892  }
893  else
894  v = 1;
895  val[i] = v;
896  i++;
897  }
898  }
899  A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
900 
901  /* get clustering info */
902  *clusters = MALLOC(sizeof(int)*nnodes);
903  nc = 1;
904  MIN_GRPS = 0;
905  /* if useClusters, the nodes in each top-level cluster subgraph are assigned to
906  * clusters 2, 3, .... Any nodes not in a cluster subgraph are tossed into cluster 1.
907  */
908  if (useClusters) {
909  Agraph_t* sg;
910  int gid = 1;
911  memset (*clusters, 0, sizeof(int)*nnodes);
912  for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) {
913  if (strncmp(agnameof(sg), "cluster", 7)) continue;
914  gid++;
915  for (n = agfstnode(sg); n; n = agnxtnode (sg, n)) {
916  i = ND_id(n);
917  if ((*clusters)[i])
918  fprintf (stderr, "Warning: node %s appears in multiple clusters.\n", agnameof(n));
919  else
920  (*clusters)[i] = gid;
921  }
922  }
923  for (n = agfstnode(g); n; n = agnxtnode (g, n)) {
924  i = ND_id(n);
925  if ((*clusters)[i] == 0)
926  (*clusters)[i] = 1;
927  }
928  MIN_GRPS = 1;
929  nc = gid;
930  }
931  else if (clust_sym) {
932  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
933  i = ND_id(n);
934  if ((sscanf(agxget(n,clust_sym), "%d", &ic)>0)) {
935  (*clusters)[i] = ic;
936  nc = MAX(nc, ic);
937  if (first){
938  MIN_GRPS = ic;
939  first = FALSE;
940  } else {
941  MIN_GRPS = MIN(MIN_GRPS, ic);
942  }
943  } else {
944  noclusterinfo = TRUE;
945  break;
946  }
947  }
948  }
949  else
950  noclusterinfo = TRUE;
951  MAX_GRPS = nc;
952 
953  if (noclusterinfo) {
954  int use_value = TRUE, flag = 0;
955  real modularity;
956  if (!clust_sym) clust_sym = agattr(g,AGNODE,"cluster","-1");
957 
958  if (clustering_scheme == CLUSTERING_MQ){
959  mq_clustering(A, FALSE, maxcluster, use_value,
960  &nc, clusters, &modularity, &flag);
961  } else if (clustering_scheme == CLUSTERING_MODULARITY){
962  modularity_clustering(A, FALSE, maxcluster, use_value,
963  &nc, clusters, &modularity, &flag);
964  } else {
965  assert(0);
966  }
967  for (i = 0; i < nnodes; i++) (*clusters)[i]++;/* make into 1 based */
968  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
969  i = ND_id(n);
970  sprintf(scluster,"%d",(*clusters)[i]);
971  agxset(n,clust_sym,scluster);
972  }
973  MIN_GRPS = 1;
974  MAX_GRPS = nc;
975  if (Verbose){
976  fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
977  }
978  }
979 
980  *label_sizes = MALLOC(sizeof(real)*dim*nnodes);
981  if (pal || (!noclusterinfo && clust_clr_sym)){
982  *rgb_r = MALLOC(sizeof(float)*(1+MAX_GRPS));
983  *rgb_g = MALLOC(sizeof(float)*(1+MAX_GRPS));
984  *rgb_b = MALLOC(sizeof(float)*(1+MAX_GRPS));
985  } else {
986  *rgb_r = NULL;
987  *rgb_g = NULL;
988  *rgb_b = NULL;
989  }
990  *fsz = MALLOC(sizeof(float)*nnodes);
991  *labels = MALLOC(sizeof(char*)*nnodes);
992 
993  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
994  gvcolor_t color;
995  real sz;
996  i = ND_id(n);
997  if (agget(n, "width") && agget(n, "height")){
998  sscanf(agget(n, "width"), "%lf", &sz);
999  (*label_sizes)[i*2] = POINTS(sz*0.5);
1000  sscanf(agget(n, "height"), "%lf", &sz);
1001  (*label_sizes)[i*2+1] = POINTS(sz*0.5);
1002  } else {
1003  (*label_sizes)[i*2] = POINTS(0.75/2);
1004  (*label_sizes)[i*2+1] = POINTS(0.5*2);
1005  }
1006 
1007  if (agget(n, "fontsize")){
1008  sscanf(agget(n, "fontsize"), "%f", &ff);
1009  (*fsz)[i] = ff;
1010  } else {
1011  (*fsz)[i] = 14;
1012  }
1013 
1014  if (agget(n, "label") && strcmp(agget(n, "label"), "") != 0 && strcmp(agget(n, "label"), "\\N") != 0){
1015  char *lbs;
1016  lbs = agget(n, "label");
1017  (*labels)[i] = MALLOC(sizeof(char)*(strlen(lbs)+1));
1018  strcpy((*labels)[i], lbs);
1019  } else {
1020  (*labels)[i] = MALLOC(sizeof(char)*(strlen(agnameof(n))+1));
1021  strcpy((*labels)[i], agnameof(n));
1022  }
1023 
1024 
1025 
1026  j = (*clusters)[i];
1027  if (MAX_GRPS-MIN_GRPS < max_color) {
1028  j = (j-MIN_GRPS)*((int)((max_color-1)/MAX((MAX_GRPS-MIN_GRPS),1)));
1029  } else {
1030  j = (j-MIN_GRPS)%max_color;
1031  }
1032 
1033  if (pal){
1034  // assert((*clusters)[i] >= 0 && (*clusters)[i] <= MAX_GRPS);
1035  (*rgb_r)[(*clusters)[i]] = pal[3*j+0];
1036  (*rgb_g)[(*clusters)[i]] = pal[3*j+1];
1037  (*rgb_b)[(*clusters)[i]] = pal[3*j+2];
1038  }
1039 
1040  if (!noclusterinfo && clust_clr_sym && (colorxlate(agxget(n,clust_clr_sym),&color,RGBA_DOUBLE) == COLOR_OK)) {
1041  (*rgb_r)[(*clusters)[i]] = color.u.RGBA[0];
1042  (*rgb_g)[(*clusters)[i]] = color.u.RGBA[1];
1043  (*rgb_b)[(*clusters)[i]] = color.u.RGBA[2];
1044  }
1045 
1046  if (!noclusterinfo && agget(n, "cluster") && agget(n, "clustercolor") && strlen(agget(n, "clustercolor") ) >= 7 && pal){
1047  char cc[10];
1048  strcpy(cc, agget(n, "clustercolor"));
1049  (*rgb_r)[(*clusters)[i]] = hexcol2rgb(cc+1);
1050  (*rgb_g)[(*clusters)[i]] = hexcol2rgb(cc+3);
1051  (*rgb_b)[(*clusters)[i]] = hexcol2rgb(cc+5);
1052  }
1053 
1054  }
1055 
1056 
1057  if (x){
1058  int has_position = FALSE;
1059  *x = MALLOC(sizeof(real)*dim*nnodes);
1060  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
1061  real xx,yy;
1062  i = ND_id(n);
1063  if (agget(n, "pos")){
1064  has_position = TRUE;
1065  sscanf(agget(n, "pos"), "%lf,%lf", &xx, &yy);
1066  (*x)[i*dim] = xx;
1067  (*x)[i*dim+1] = yy;
1068  } else {
1069  fprintf(stderr,"WARNING: pos field missing for node %d, set to origin\n",i);
1070  (*x)[i*dim] = 0;
1071  (*x)[i*dim+1] = 0;
1072  }
1073  }
1074  if (!has_position){
1075  FREE(*x);
1076  *x = NULL;
1077  }
1078  }
1079 
1080 
1081  FREE(I);
1082  FREE(J);
1083  FREE(val);
1084 
1085  return A;
1086 }
1087 
1088 void attached_clustering(Agraph_t* g, int maxcluster, int clustering_scheme){
1089  SparseMatrix A = 0;
1090  Agnode_t* n;
1091  Agedge_t* e;
1092  Agsym_t *sym, *clust_sym;
1093  int nnodes;
1094  int nedges;
1095  int i, row,nc;
1096  int* I;
1097  int* J;
1098  real* val;
1099  real v;
1100  int type = MATRIX_TYPE_REAL;
1101  size_t sz = sizeof(real);
1102  char scluster[100];
1103 
1104 
1105  int *clusters;
1106 
1107 
1108 
1109  if (!g) return;
1110  nnodes = agnnodes (g);
1111  nedges = agnedges (g);
1112 
1113  /* Assign node ids */
1114  i = 0;
1115  for (n = agfstnode (g); n; n = agnxtnode (g, n))
1116  ND_id(n) = i++;
1117 
1118  /* form matrix */
1119  I = N_NEW(nedges, int);
1120  J = N_NEW(nedges, int);
1121  val = N_NEW(nedges, real);
1122 
1123  sym = agattr(g, AGEDGE, "weight", NULL);
1124  clust_sym = agattr(g, AGNODE, "cluster", NULL);
1125 
1126  i = 0;
1127  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
1128  row = ND_id(n);
1129  for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
1130  I[i] = row;
1131  J[i] = ND_id(aghead(e));
1132  if (sym) {
1133  if (sscanf (agxget(e,sym), "%lf", &v) != 1)
1134  v = 1;
1135  }
1136  else
1137  v = 1;
1138  val[i] = v;
1139  i++;
1140  }
1141  }
1142  A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
1143 
1144  clusters = MALLOC(sizeof(int)*nnodes);
1145 
1146  {
1147  int use_value = TRUE, flag = 0;
1148  real modularity;
1149  if (!clust_sym) clust_sym = agattr(g,AGNODE,"cluster","-1");
1150 
1151  if (clustering_scheme == CLUSTERING_MQ){
1152  mq_clustering(A, FALSE, maxcluster, use_value,
1153  &nc, &clusters, &modularity, &flag);
1154  } else if (clustering_scheme == CLUSTERING_MODULARITY){
1155  modularity_clustering(A, FALSE, maxcluster, use_value,
1156  &nc, &clusters, &modularity, &flag);
1157  } else {
1158  assert(0);
1159  }
1160  for (i = 0; i < nnodes; i++) (clusters)[i]++;/* make into 1 based */
1161  for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
1162  i = ND_id(n);
1163  sprintf(scluster,"%d",(clusters)[i]);
1164  agxset(n,clust_sym,scluster);
1165  }
1166  if (Verbose){
1167  fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
1168  }
1169  }
1170 
1171  FREE(I);
1172  FREE(J);
1173  FREE(val);
1174  FREE(clusters);
1175 
1177 
1178 }
1179 
1180 
1181 
1183 {
1184  aginit(g, AGNODE, "info", sizeof(Agnodeinfo_t), TRUE);
1185 }
1186 
1187 void setDotNodeID (Agnode_t* n, int v)
1188 {
1189  ND_id(n) = v;
1190 }
1191 
1193 {
1194  return ND_id(n);
1195 }
1196 
void s1(graph_t *, node_t *)
Definition: stuff.c:686
#define MAX(a, b)
Definition: agerror.c:17
char * cat_string(char *s1, char *s2)
Definition: DotIO.c:653
CGRAPH_API Agnode_t * agnode(Agraph_t *g, char *name, int createflag)
Definition: node.c:142
Definition: cgraph.h:388
#define ABS(a)
Definition: arith.h:45
union color_s::@10 u
CGRAPH_API Agraph_t * agopen(char *name, Agdesc_t desc, Agdisc_t *disc)
Definition: graph.c:44
#define SparseMatrix_known_undirected(A)
Definition: SparseMatrix.h:175
Agsym_t * agattr(Agraph_t *g, int kind, char *name, char *value)
Definition: attr.c:324
#define N_NEW(n, t)
Definition: memory.h:36
float palette_grey[1001][3]
int getDotNodeID(Agnode_t *n)
Definition: DotIO.c:1192
real drand()
Definition: general.c:52
float palette_pastel[1001][3]
Agdesc_t desc
Definition: cgraph.h:241
#define MIN(a, b)
Definition: arith.h:35
void modularity_clustering(SparseMatrix A, int inplace, int ncluster_target, int use_value, int *nclusters, int **assignment, real *modularity, int *flag)
Definition: clustering.c:350
int agxset(void *obj, Agsym_t *sym, char *value)
Definition: attr.c:468
#define FREE
Definition: PriorityQueue.c:23
SparseMatrix SparseMatrix_new(int m, int n, int nz, int type, int format)
Definition: SparseMatrix.c:384
float palette_adam[11][3]
#define assert(x)
Definition: cghdr.h:47
void rgb2hex(float r, float g, float b, char *cstring, char *opacity)
Definition: colorutil.c:27
void attach_embedding(Agraph_t *g, int dim, double sc, real *x)
void edgelist_export(FILE *f, SparseMatrix A, int dim, real *x)
Definition: DotIO.c:387
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)
Definition: DotIO.c:135
CGRAPH_API Agraph_t * agread(void *chan, Agdisc_t *disc)
Definition: grammar.c:2349
CGRAPH_API Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition: edge.c:86
void mq_clustering(SparseMatrix A, int inplace, int maxcluster, int use_value, int *nclusters, int **assignment, real *mq, int *flag)
Definition: mq.c:588
Definition: color.h:34
#define SLEN(s)
Definition: neatoinit.c:943
int agerr(agerrlevel_t level, const char *fmt,...)
Definition: agerror.c:141
CGRAPH_API Agraph_t * agfstsubg(Agraph_t *g)
Definition: subg.c:72
real distance(real *x, int dim, int i, int j)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition: edge.c:25
float palette_white_to_red[1001][3]
char * hue2rgb(real hue, char *color)
Definition: colorutil.c:53
CGRAPH_API Agdesc_t Agundirected
Definition: cgraph.h:420
#define POINTS(a_inches)
Definition: geom.h:67
void initDotIO(Agraph_t *g)
Definition: DotIO.c:1182
char * agget(void *obj, char *name)
Definition: attr.c:428
float palette_sequential_singlehue_red[1001][3]
CGRAPH_API Agraph_t * agnxtsubg(Agraph_t *subg)
Definition: subg.c:77
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
Definition: edge.c:525
CGRAPH_API Agdesc_t Agdirected
Definition: cgraph.h:418
double RGBA[4]
Definition: color.h:36
void attach_edge_colors(Agraph_t *g, int dim, real *colors)
Definition: DotIO.c:91
unsigned int id
Definition: DotIO.c:25
int agset(void *obj, char *name, char *value)
Definition: attr.c:455
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition: node.c:45
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
Definition: edge.c:533
char * strip_dir(char *s)
Definition: general.c:299
float palette_adam_blend[1001][3]
CGRAPH_API char * agnameof(void *)
Definition: id.c:143
int Import_dot_splines(Agraph_t *g, int *ne, char ***xsplines)
Definition: DotIO.c:342
void attached_clustering(Agraph_t *g, int maxcluster, int clustering_scheme)
Definition: DotIO.c:1088
float palette_grey_to_red[1001][3]
float palette_blue_to_yellow[1001][3]
#define MALLOC
Definition: PriorityQueue.c:21
char * cat_string3(char *s1, char *s2, char *s3, int id)
Definition: DotIO.c:662
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
Definition: node.c:38
CGRAPH_API void aginit(Agraph_t *g, int kind, char *rec_name, int rec_size, int move_to_front)
Definition: rec.c:198
void SparseMatrix_delete(SparseMatrix A)
Definition: SparseMatrix.c:411
Definition: grammar.c:79
Definition: cgraph.h:83
Agraph_t * SparseMatrix_read_dot(FILE *f)
Definition: DotIO.c:122
#define AGNODE
Definition: cgraph.h:101
int colorxlate(char *str, gvcolor_t *color, color_type_t target_type)
Definition: colxlate.c:254
#define NULL
Definition: logic.h:39
CGRAPH_API Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition: edge.c:95
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
Definition: SparseMatrix.c:957
EXTERN unsigned char Verbose
Definition: globals.h:64
CGRAPH_API int agnnodes(Agraph_t *g)
Definition: graph.c:162
Agraph_t * makeDotGraph(SparseMatrix A, char *name, int dim, real *x, int with_color, int with_label, int use_matrix_value)
Definition: DotIO.c:466
#define ND_id(n)
Definition: DotIO.c:28
void Dot_SetClusterColor(Agraph_t *g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters)
Definition: DotIO.c:781
CGRAPH_API Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition: edge.c:281
Agraph_t * convert_edge_labels_to_nodes(Agraph_t *g)
Definition: DotIO.c:678
CGRAPH_API void * agbindrec(void *obj, char *name, unsigned int size, int move_to_front)
Definition: rec.c:86
#define COLOR_OK
Definition: color.h:49
float palette_sequential_singlehue_red_lighter[1001][3]
struct Agnodeinfo_t Agnodeinfo_t
void setDotNodeID(Agnode_t *n, int v)
Definition: DotIO.c:1187
CGRAPH_API int agnedges(Agraph_t *g)
Definition: graph.c:167
SparseMatrix Import_coord_clusters_from_dot(Agraph_t *g, int maxcluster, int dim, int *nn, real **label_sizes, 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)
Definition: DotIO.c:799
char * agxget(void *obj, Agsym_t *sym)
Definition: attr.c:444
double dist(Site *s, Site *t)
Definition: site.c:41
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition: edge.c:40
#define AGEDGE
Definition: cgraph.h:104
Agrec_t h
Definition: DotIO.c:24
#define FALSE
Definition: cgraph.h:35
void dump_coordinates(char *name, int n, int dim, real *x)
Definition: DotIO.c:432
Agraph_t * assign_random_edge_color(Agraph_t *g)
Definition: DotIO.c:752
float palette_primary[1001][3]
#define AGRAPH
Definition: cgraph.h:100
#define TRUE
Definition: cgraph.h:38
#define real
Definition: general.h:34