Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
DotIO.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#define STANDALONE
12#include <sparse/general.h>
13#include <sparse/DotIO.h>
14#include <sparse/clustering.h>
15#include <math.h>
16#include <sparse/mq.h>
18#include <sparse/colorutil.h>
19#include <stdbool.h>
20#include <string.h>
21#include <util/agxbuf.h>
22#include <util/alloc.h>
23#include <util/startswith.h>
24#include <util/unreachable.h>
25
26typedef struct {
27 Agrec_t h;
28 unsigned int id;
30
31#define ND_id(n) (((Agnodeinfo_t*)((n)->base.data))->id)
32
33static void color_string(agxbuf *buf, int dim, double *color){
34 if (dim > 3 || dim < 1){
35 fprintf(stderr,"can only 1, 2 or 3 dimensional color space. with color value between 0 to 1\n");
36 assert(0);
37 }
38 if (dim == 3){
39 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] *255), 255),
40 MIN((unsigned int) (color[1]*255), 255), MIN((unsigned int)(color[2]*255), 255));
41 } else if (dim == 1){
42 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] * 255), 255),
43 MIN((unsigned int) (color[0]*255), 255), MIN((unsigned int)(color[0]*255), 255));
44 } else if (dim == 2){
45 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] * 255), 255),
46 0, MIN((unsigned int)(color[1]*255), 255));
47 }
48}
49
50void attach_edge_colors(Agraph_t* g, int dim, double *colors){
51 /* colors is array of dim*nedges, with color for edge i at colors[dim*i, dim(i+1))
52 */
53 Agsym_t* sym = agattr(g, AGEDGE, "color", 0);
54 Agedge_t* e;
55 Agnode_t* n;
56 agxbuf buf = {0};
57 unsigned row, col;
58 int ie = 0;
59
60 if (!sym)
61 sym = agattr (g, AGEDGE, "color", "");
62
63 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
64 row = ND_id(n);
65 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
66 col = ND_id(aghead(e));
67 if (row == col) continue;
68 color_string(&buf, dim, colors + ie*dim);
69 agxset(e, sym, agxbuse(&buf));
70 ie++;
71 }
72 }
73 agxbfree(&buf);
74}
75
76/* SparseMatrix_import_dot:
77 * Assumes g is connected and simple, i.e., we can have a->b and b->a
78 * but not a->b and a->b
79 */
81 double **x, int format) {
82 SparseMatrix A = 0;
83 Agnode_t* n;
84 Agedge_t* e;
85 Agsym_t *sym;
86 Agsym_t *psym;
87 int nnodes;
88 int nedges;
89 int i, row;
90 int* I;
91 int* J;
92 double *val;
93 double v;
95
96 if (!g) return NULL;
97 nnodes = agnnodes (g);
98 nedges = agnedges (g);
99 if (format != FORMAT_CSR && format != FORMAT_COORD) {
100 fprintf (stderr, "Format %d not supported\n", format);
101 graphviz_exit(1);
102 }
103
104 /* Assign node ids */
105 i = 0;
106 for (n = agfstnode (g); n; n = agnxtnode (g, n))
107 ND_id(n) = i++;
108
109 if (format == FORMAT_COORD){
111 A->nz = nedges;
112 I = A->ia;
113 J = A->ja;
114 val = A->a;
115 } else {
116 I = gv_calloc(nedges, sizeof(int));
117 J = gv_calloc(nedges, sizeof(int));
118 val = gv_calloc(nedges, sizeof(double));
119 }
120
121 sym = agattr(g, AGEDGE, "weight", NULL);
122 i = 0;
123 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
124 row = ND_id(n);
125 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
126 I[i] = row;
127 J[i] = ND_id(aghead(e));
128
129 /* edge weight */
130 if (sym) {
131 if (sscanf (agxget(e,sym), "%lf", &v) != 1) v = 1;
132 } else {
133 v = 1;
134 }
135 val[i] = v;
136
137 i++;
138 }
139 }
140
141 if (x && (psym = agattr(g, AGNODE, "pos", NULL))) {
142 bool has_positions = true;
143 char* pval;
144 if (!(*x)) {
145 *x = gv_calloc(dim * nnodes, sizeof(double));
146 }
147 for (n = agfstnode (g); n && has_positions; n = agnxtnode (g, n)) {
148 double xx,yy, zz,ww;
149 int nitems;
150 i = ND_id(n);
151 if ((pval = agxget(n, psym)) && *pval) {
152 if (dim == 2){
153 nitems = sscanf(pval, "%lf,%lf", &xx, &yy);
154 if (nitems != 2) {
155 has_positions = false;
156 agerrorf("Node \"%s\" pos has %d < 2 values", agnameof(n), nitems);
157 }
158 (*x)[i*dim] = xx;
159 (*x)[i*dim+1] = yy;
160 } else if (dim == 3){
161 nitems = sscanf(pval, "%lf,%lf,%lf", &xx, &yy, &zz);
162 if (nitems != 3) {
163 has_positions = false;
164 agerrorf("Node \"%s\" pos has %d < 3 values", agnameof(n), nitems);
165 }
166 (*x)[i*dim] = xx;
167 (*x)[i*dim+1] = yy;
168 (*x)[i*dim+2] = zz;
169 } else if (dim == 4){
170 nitems = sscanf(pval, "%lf,%lf,%lf,%lf", &xx, &yy, &zz,&ww);
171 if (nitems != 4) {
172 has_positions = false;
173 agerrorf("Node \"%s\" pos has %d < 4 values", agnameof(n), nitems);
174 }
175 (*x)[i*dim] = xx;
176 (*x)[i*dim+1] = yy;
177 (*x)[i*dim+2] = zz;
178 (*x)[i*dim+3] = ww;
179 } else if (dim == 1){
180 nitems = sscanf(pval, "%lf", &xx);
181 if (nitems != 1){
183 A = NULL;
184 goto done;
185 }
186 (*x)[i*dim] = xx;
187 } else {
188 assert(0);
189 }
190 } else {
191 has_positions = false;
192 agerrorf("Node \"%s\" lacks position info", agnameof(n));
193 }
194 }
195 if (!has_positions) {
196 free(*x);
197 *x = NULL;
198 }
199 }
200 else if (x)
201 agerrorf("Error: graph %s has missing \"pos\" information", agnameof(g));
202
203 size_t sz = sizeof(double);
204 if (format == FORMAT_CSR) A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
205
206done:
207 if (format != FORMAT_COORD){
208 free(I);
209 free(J);
210 free(val);
211 }
212
213 return A;
214}
215
216/* get spline info */
217int Import_dot_splines(Agraph_t* g, int *ne, char ***xsplines){
218 /* get the list of splines for the edges in the order they appear, and store as a list of strings in xspline.
219 If *xsplines = NULL, it will be allocated. On exit (*xsplines)[i] is the control point string for the i-th edge. This string
220 is of the form "x1,y1 x2,y2...", the two end points of the edge is not included per Dot format
221 Return 1 if success. 0 if not.
222 */
223 Agnode_t* n;
224 Agedge_t* e;
225 Agsym_t *sym;
226 int nedges;
227 unsigned i;
228
229 if (!g){
230 return 0;
231 }
232
233 *ne = nedges = agnedges (g);
234
235 /* Assign node ids */
236 i = 0;
237 for (n = agfstnode (g); n; n = agnxtnode (g, n))
238 ND_id(n) = i++;
239
240 sym = agattr(g, AGEDGE, "pos", 0);
241 if (!sym) return 0;
242
243 *xsplines = gv_calloc(nedges, sizeof(char*));
244
245 i = 0;
246 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
247 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
248 /* edge weight */
249 char *pos = agxget (e, sym);
250 (*xsplines)[i] = strdup(pos);
251 i++;
252 }
253 }
254 return 1;
255}
256
257static int hex2int(char h){
258 if (h >= '0' && h <= '9') return h - '0';
259 if (h >= 'a' && h <= 'f') return 10 + h - 'a';
260 if (h >= 'A' && h <= 'F') return 10 + h - 'A';
261 return 0;
262}
263
264static float hexcol2rgb(const char *h) {
265 return (hex2int(h[0])*16 + hex2int(h[1]))/255.;
266}
267
268void Dot_SetClusterColor(Agraph_t* g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters){
269
270 Agnode_t* n;
271 agxbuf scluster = {0};
272 unsigned i;
273 Agsym_t* clust_clr_sym = agattr(g, AGNODE, "clustercolor", NULL);
274
275 if (!clust_clr_sym) clust_clr_sym = agattr(g, AGNODE, "clustercolor", "-1");
276 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
277 i = ND_id(n);
278 if (rgb_r && rgb_g && rgb_b) {
279 rgb2hex(rgb_r[clusters[i]], rgb_g[clusters[i]], rgb_b[clusters[i]],
280 &scluster, NULL);
281 }
282 agxset(n, clust_clr_sym, agxbuse(&scluster));
283 }
284 agxbfree(&scluster);
285}
286
287SparseMatrix Import_coord_clusters_from_dot(Agraph_t* g, int maxcluster, int dim, int *nn, double **label_sizes, double **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){
288 SparseMatrix A = 0;
289 Agnode_t* n;
290 Agedge_t* e;
291 Agsym_t* sym;
292 Agsym_t* clust_sym;
293 Agsym_t* clust_clr_sym;
294 int nnodes;
295 int nedges;
296 int i, row, ic,nc, j;
297 double v;
299 char scluster[100];
300 float ff;
301
302 int MAX_GRPS, MIN_GRPS;
303 bool noclusterinfo = false;
304 bool first = true;
305 const float *pal;
306 int max_color = MAX_COLOR;
307
308 switch (default_color_scheme){
310 pal = &(palette_blue_to_yellow[0][0]);
311 break;
313 pal = &(palette_white_to_red[0][0]);
314 break;
316 pal = &(palette_grey_to_red[0][0]);
317 break;
319 pal = &(palette_grey[0][0]);
320 break;
322 pal = &(palette_pastel[0][0]);
323 break;
326 break;
329 break;
331 pal = &(palette_primary[0][0]);
332 break;
334 pal = &(palette_adam_blend[0][0]);
335 break;
337 pal = &(palette_adam[0][0]);
338 max_color = 11;
339 break;
341 pal = NULL;
342 break;
343 default:
344 pal = &(palette_pastel[0][0]);
345 break;
346 }
347
348 if (!g) return NULL;
349 nnodes = agnnodes (g);
350 nedges = agnedges (g);
351 *nn = nnodes;
352
353 /* Assign node ids */
354 i = 0;
355 for (n = agfstnode (g); n; n = agnxtnode (g, n))
356 ND_id(n) = i++;
357
358 /* form matrix */
359 int* I = gv_calloc(nedges, sizeof(int));
360 int* J = gv_calloc(nedges, sizeof(int));
361 double* val = gv_calloc(nedges, sizeof(double));
362
363 sym = agattr(g, AGEDGE, "weight", NULL);
364 clust_sym = agattr(g, AGNODE, "cluster", NULL);
365 clust_clr_sym = agattr(g, AGNODE, "clustercolor", NULL);
366 i = 0;
367 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
368 row = ND_id(n);
369 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
370 I[i] = row;
371 J[i] = ND_id(aghead(e));
372 if (sym) {
373 if (sscanf (agxget(e,sym), "%lf", &v) != 1)
374 v = 1;
375 }
376 else
377 v = 1;
378 val[i] = v;
379 i++;
380 }
381 }
382 A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val,
383 type, sizeof(double));
384
385 /* get clustering info */
386 *clusters = gv_calloc(nnodes, sizeof(int));
387 nc = 1;
388 MIN_GRPS = 0;
389 /* if useClusters, the nodes in each top-level cluster subgraph are assigned to
390 * clusters 2, 3, .... Any nodes not in a cluster subgraph are tossed into cluster 1.
391 */
392 if (useClusters) {
393 Agraph_t* sg;
394 int gid = 1;
395 memset (*clusters, 0, sizeof(int)*nnodes);
396 for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) {
397 if (!startswith(agnameof(sg), "cluster")) continue;
398 gid++;
399 for (n = agfstnode(sg); n; n = agnxtnode (sg, n)) {
400 i = ND_id(n);
401 if ((*clusters)[i])
402 fprintf (stderr, "Warning: node %s appears in multiple clusters.\n", agnameof(n));
403 else
404 (*clusters)[i] = gid;
405 }
406 }
407 for (n = agfstnode(g); n; n = agnxtnode (g, n)) {
408 i = ND_id(n);
409 if ((*clusters)[i] == 0)
410 (*clusters)[i] = 1;
411 }
412 MIN_GRPS = 1;
413 nc = gid;
414 }
415 else if (clust_sym) {
416 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
417 i = ND_id(n);
418 if ((sscanf(agxget(n,clust_sym), "%d", &ic)>0)) {
419 (*clusters)[i] = ic;
420 nc = MAX(nc, ic);
421 if (first){
422 MIN_GRPS = ic;
423 first = false;
424 } else {
425 MIN_GRPS = MIN(MIN_GRPS, ic);
426 }
427 } else {
428 noclusterinfo = true;
429 break;
430 }
431 }
432 }
433 else
434 noclusterinfo = true;
435 MAX_GRPS = nc;
436
437 if (noclusterinfo) {
438 double modularity;
439 if (!clust_sym) clust_sym = agattr(g,AGNODE,"cluster","-1");
440
441 if (clustering_scheme == CLUSTERING_MQ){
442 mq_clustering(A, maxcluster,
443 &nc, clusters, &modularity);
444 } else if (clustering_scheme == CLUSTERING_MODULARITY){
445 modularity_clustering(A, false, maxcluster,
446 &nc, clusters, &modularity);
447 } else {
448 UNREACHABLE();
449 }
450 for (i = 0; i < nnodes; i++) (*clusters)[i]++;/* make into 1 based */
451 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
452 i = ND_id(n);
453 snprintf(scluster, sizeof(scluster), "%d", (*clusters)[i]);
454 agxset(n,clust_sym,scluster);
455 }
456 MIN_GRPS = 1;
457 MAX_GRPS = nc;
458 if (Verbose){
459 fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
460 }
461 }
462
463 *label_sizes = gv_calloc(dim * nnodes, sizeof(double));
464 if (pal || (!noclusterinfo && clust_clr_sym)){
465 *rgb_r = gv_calloc(1 + MAX_GRPS, sizeof(float));
466 *rgb_g = gv_calloc(1 + MAX_GRPS, sizeof(float));
467 *rgb_b = gv_calloc(1 + MAX_GRPS, sizeof(float));
468 } else {
469 *rgb_r = NULL;
470 *rgb_g = NULL;
471 *rgb_b = NULL;
472 }
473 *fsz = gv_calloc(nnodes, sizeof(float));
474 *labels = gv_calloc(nnodes, sizeof(char*));
475
476 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
478 double sz;
479 i = ND_id(n);
480 if (agget(n, "width") && agget(n, "height")){
481 sscanf(agget(n, "width"), "%lf", &sz);
482 (*label_sizes)[i*2] = POINTS(sz*0.5);
483 sscanf(agget(n, "height"), "%lf", &sz);
484 (*label_sizes)[i*2+1] = POINTS(sz*0.5);
485 } else {
486 (*label_sizes)[i*2] = POINTS(0.75/2);
487 (*label_sizes)[i*2+1] = POINTS(0.5*2);
488 }
489
490 if (agget(n, "fontsize")){
491 sscanf(agget(n, "fontsize"), "%f", &ff);
492 (*fsz)[i] = ff;
493 } else {
494 (*fsz)[i] = 14;
495 }
496
497 if (agget(n, "label") && strcmp(agget(n, "label"), "") != 0 && strcmp(agget(n, "label"), "\\N") != 0){
498 char *lbs = agget(n, "label");
499 (*labels)[i] = strdup(lbs);
500 } else {
501 (*labels)[i] = strdup(agnameof(n));
502 }
503
504
505
506 j = (*clusters)[i];
507 if (MAX_GRPS-MIN_GRPS < max_color) {
508 j = (j-MIN_GRPS)*((int)((max_color-1)/MAX((MAX_GRPS-MIN_GRPS),1)));
509 } else {
510 j = (j-MIN_GRPS)%max_color;
511 }
512
513 if (pal){
514 (*rgb_r)[(*clusters)[i]] = pal[3*j+0];
515 (*rgb_g)[(*clusters)[i]] = pal[3*j+1];
516 (*rgb_b)[(*clusters)[i]] = pal[3*j+2];
517 }
518
519 if (!noclusterinfo && clust_clr_sym && (colorxlate(agxget(n,clust_clr_sym),&color,RGBA_DOUBLE) == COLOR_OK)) {
520 (*rgb_r)[(*clusters)[i]] = color.u.RGBA[0];
521 (*rgb_g)[(*clusters)[i]] = color.u.RGBA[1];
522 (*rgb_b)[(*clusters)[i]] = color.u.RGBA[2];
523 }
524
525 const char *cc = agget(n, "clustercolor");
526 if (!noclusterinfo && agget(n, "cluster") && cc && strlen(cc) >= 7 && pal) {
527 (*rgb_r)[(*clusters)[i]] = hexcol2rgb(cc+1);
528 (*rgb_g)[(*clusters)[i]] = hexcol2rgb(cc+3);
529 (*rgb_b)[(*clusters)[i]] = hexcol2rgb(cc+5);
530 }
531
532 }
533
534
535 if (x){
536 bool has_position = false;
537 *x = gv_calloc(dim * nnodes, sizeof(double));
538 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
539 double xx,yy;
540 i = ND_id(n);
541 if (agget(n, "pos")){
542 has_position = true;
543 sscanf(agget(n, "pos"), "%lf,%lf", &xx, &yy);
544 (*x)[i*dim] = xx;
545 (*x)[i*dim+1] = yy;
546 } else {
547 fprintf(stderr,"WARNING: pos field missing for node %d, set to origin\n",i);
548 (*x)[i*dim] = 0;
549 (*x)[i*dim+1] = 0;
550 }
551 }
552 if (!has_position){
553 free(*x);
554 *x = NULL;
555 }
556 }
557
558
559 free(I);
560 free(J);
561 free(val);
562
563 return A;
564}
565
566void attached_clustering(Agraph_t* g, int maxcluster, int clustering_scheme){
567 SparseMatrix A = 0;
568 Agnode_t* n;
569 Agedge_t* e;
570 Agsym_t *sym, *clust_sym;
571 int nnodes;
572 int nedges;
573 int i, row,nc;
574 double v;
576 size_t sz = sizeof(double);
577
578 if (!g) return;
579 nnodes = agnnodes (g);
580 nedges = agnedges (g);
581
582 /* Assign node ids */
583 i = 0;
584 for (n = agfstnode (g); n; n = agnxtnode (g, n))
585 ND_id(n) = i++;
586
587 /* form matrix */
588 int* I = gv_calloc(nedges, sizeof(int));
589 int* J = gv_calloc(nedges, sizeof(int));
590 double* val = gv_calloc(nedges, sizeof(double));
591
592 sym = agattr(g, AGEDGE, "weight", NULL);
593 clust_sym = agattr(g, AGNODE, "cluster", NULL);
594
595 i = 0;
596 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
597 row = ND_id(n);
598 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
599 I[i] = row;
600 J[i] = ND_id(aghead(e));
601 if (sym) {
602 if (sscanf (agxget(e,sym), "%lf", &v) != 1)
603 v = 1;
604 }
605 else
606 v = 1;
607 val[i] = v;
608 i++;
609 }
610 }
611 A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
612
613 int *clusters = gv_calloc(nnodes, sizeof(int));
614
615 {
616 double modularity;
617 if (!clust_sym) clust_sym = agattr(g,AGNODE,"cluster","-1");
618
619 if (clustering_scheme == CLUSTERING_MQ){
620 mq_clustering(A, maxcluster,
621 &nc, &clusters, &modularity);
622 } else if (clustering_scheme == CLUSTERING_MODULARITY){
623 modularity_clustering(A, false, maxcluster,
624 &nc, &clusters, &modularity);
625 } else {
626 UNREACHABLE();
627 }
628 for (i = 0; i < nnodes; i++) (clusters)[i]++;/* make into 1 based */
629 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
630 i = ND_id(n);
631 agxbuf value_buffer = {0};
632 agxbprint(&value_buffer, "%d", clusters[i]);
633 agxset(n, clust_sym, agxbuse(&value_buffer));
634 agxbfree(&value_buffer);
635 }
636 if (Verbose){
637 fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
638 }
639 }
640
641 free(I);
642 free(J);
643 free(val);
644 free(clusters);
645
647
648}
649
650
651
653{
654 aginit(g, AGNODE, "info", sizeof(Agnodeinfo_t), true);
655}
656
657void setDotNodeID (Agnode_t* n, int v)
658{
659 ND_id(n) = v;
660}
661
663{
664 return ND_id(n);
665}
666
#define ND_id(n)
Definition DotIO.c:31
void Dot_SetClusterColor(Agraph_t *g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters)
Definition DotIO.c:268
SparseMatrix SparseMatrix_import_dot(Agraph_t *g, int dim, double **x, int format)
Definition DotIO.c:80
int getDotNodeID(Agnode_t *n)
Definition DotIO.c:662
void initDotIO(Agraph_t *g)
Definition DotIO.c:652
SparseMatrix Import_coord_clusters_from_dot(Agraph_t *g, int maxcluster, int dim, int *nn, double **label_sizes, double **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:287
static float hexcol2rgb(const char *h)
Definition DotIO.c:264
void attach_edge_colors(Agraph_t *g, int dim, double *colors)
Definition DotIO.c:50
static void color_string(agxbuf *buf, int dim, double *color)
Definition DotIO.c:33
void setDotNodeID(Agnode_t *n, int v)
Definition DotIO.c:657
static int hex2int(char h)
Definition DotIO.c:257
void attached_clustering(Agraph_t *g, int maxcluster, int clustering_scheme)
Definition DotIO.c:566
int Import_dot_splines(Agraph_t *g, int *ne, char ***xsplines)
Definition DotIO.c:217
@ COLOR_SCHEME_ADAM_BLEND
Definition DotIO.h:20
@ COLOR_SCHEME_PASTEL
Definition DotIO.h:20
@ COLOR_SCHEME_ADAM
Definition DotIO.h:20
@ COLOR_SCHEME_GREY_RED
Definition DotIO.h:20
@ COLOR_SCHEME_SEQUENTIAL_SINGLEHUE_RED
Definition DotIO.h:20
@ COLOR_SCHEME_NONE
Definition DotIO.h:20
@ COLOR_SCHEME_SEQUENTIAL_SINGLEHUE_RED_LIGHTER
Definition DotIO.h:20
@ COLOR_SCHEME_GREY
Definition DotIO.h:20
@ COLOR_SCHEME_WHITE_RED
Definition DotIO.h:20
@ COLOR_SCHEME_PRIMARY
Definition DotIO.h:20
@ COLOR_SCHEME_BLUE_YELLOW
Definition DotIO.h:20
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
void SparseMatrix_delete(SparseMatrix A)
SparseMatrix SparseMatrix_new(int m, int n, int nz, int type, int format)
@ MATRIX_TYPE_REAL
@ FORMAT_COORD
@ FORMAT_CSR
static void agxbfree(agxbuf *xb)
free any malloced resources
Definition agxbuf.h:78
static int agxbprint(agxbuf *xb, const char *fmt,...)
Printf-style output to an agxbuf.
Definition agxbuf.h:234
static WUR char * agxbuse(agxbuf *xb)
Definition agxbuf.h:307
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
#define MIN(a, b)
Definition arith.h:28
void modularity_clustering(SparseMatrix A, bool inplace, int ncluster_target, int *nclusters, int **assignment, double *modularity)
Definition clustering.c:341
@ CLUSTERING_MODULARITY
Definition clustering.h:39
@ CLUSTERING_MQ
Definition clustering.h:39
static bool useClusters
Definition ccomps.c:67
@ RGBA_DOUBLE
Definition color.h:27
#define COLOR_OK
Definition color.h:44
const float palette_sequential_singlehue_red[1001][3]
const float palette_grey[1001][3]
const float palette_sequential_singlehue_red_lighter[1001][3]
const float palette_blue_to_yellow[1001][3]
const float palette_grey_to_red[1001][3]
const float palette_adam[11][3]
const float palette_white_to_red[1001][3]
const float palette_adam_blend[1001][3]
const float palette_pastel[1001][3]
const float palette_primary[1001][3]
@ MAX_COLOR
void rgb2hex(float r, float g, float b, agxbuf *cstring, const char *opacity)
Definition colorutil.c:21
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:46
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
expr procedure type
Definition exparse.y:208
#define A(n, t)
Definition expr.h:76
#define I
Definition expr.h:71
#define POINTS(a_inches)
Definition geom.h:68
static bool Verbose
Definition gml2gv.c:23
void free(void *)
node NULL
Definition grammar.y:163
int agnedges(Agraph_t *g)
Definition graph.c:175
int agnnodes(Agraph_t *g)
Definition graph.c:169
Agsym_t * agattr(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up attributes of a graph
Definition attr.c:338
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:478
char * agget(void *obj, char *name)
Definition attr.c:439
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:455
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define aghead(e)
Definition cgraph.h:881
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
void agerrorf(const char *fmt,...)
Definition agerror.c:165
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
@ AGEDGE
Definition cgraph.h:207
@ AGNODE
Definition cgraph.h:207
void aginit(Agraph_t *g, int kind, const char *rec_name, int rec_size, int move_to_front)
attach new records to objects of specified kind
Definition rec.c:170
Agraph_t * agfstsubg(Agraph_t *g)
Definition subg.c:78
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition subg.c:83
static void color(Agraph_t *g)
Definition gvcolor.c:129
GVIO_API const char * format
Definition gvio.h:51
rows row
Definition htmlparse.y:326
void mq_clustering(SparseMatrix A, int maxcluster, int *nclusters, int **assignment, double *mq)
Definition mq.c:583
static const int dim
static int nedges
total no. of edges used in routing
Definition routespl.c:31
static bool startswith(const char *s, const char *prefix)
does the string s begin with the string prefix?
Definition startswith.h:11
unsigned int id
Definition DotIO.c:28
graph or subgraph
Definition cgraph.h:425
implementation of Agrec_t
Definition cgraph.h:172
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
#define UNREACHABLE()
Definition unreachable.h:30
#define MAX(a, b)
Definition write.c:31