Graphviz 13.0.0~dev.20250607.1528
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/itos.h>
24#include <util/startswith.h>
25#include <util/unreachable.h>
26
27typedef struct {
28 Agrec_t h;
29 unsigned int id;
31
32#define ND_id(n) (((Agnodeinfo_t*)((n)->base.data))->id)
33
34static void color_string(agxbuf *buf, int dim, double *color){
35 if (dim > 3 || dim < 1){
36 fprintf(stderr,"can only 1, 2 or 3 dimensional color space. with color value between 0 to 1\n");
37 assert(0);
38 }
39 if (dim == 3){
40 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] *255), 255),
41 MIN((unsigned int) (color[1]*255), 255), MIN((unsigned int)(color[2]*255), 255));
42 } else if (dim == 1){
43 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] * 255), 255),
44 MIN((unsigned int) (color[0]*255), 255), MIN((unsigned int)(color[0]*255), 255));
45 } else if (dim == 2){
46 agxbprint(buf, "#%02x%02x%02x", MIN((unsigned int)(color[0] * 255), 255),
47 0, MIN((unsigned int)(color[1]*255), 255));
48 }
49}
50
51void attach_edge_colors(Agraph_t* g, int dim, double *colors){
52 /* colors is array of dim*nedges, with color for edge i at colors[dim*i, dim(i+1))
53 */
54 Agsym_t* sym = agattr_text(g, AGEDGE, "color", 0);
55 Agedge_t* e;
56 Agnode_t* n;
57 agxbuf buf = {0};
58 unsigned row, col;
59 int ie = 0;
60
61 if (!sym)
62 sym = agattr_text (g, AGEDGE, "color", "");
63
64 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
65 row = ND_id(n);
66 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
67 col = ND_id(aghead(e));
68 if (row == col) continue;
69 color_string(&buf, dim, colors + ie*dim);
70 agxset(e, sym, agxbuse(&buf));
71 ie++;
72 }
73 }
74 agxbfree(&buf);
75}
76
77/* SparseMatrix_import_dot:
78 * Assumes g is connected and simple, i.e., we can have a->b and b->a
79 * but not a->b and a->b
80 */
82 double **x, int format) {
83 SparseMatrix A = 0;
84 Agnode_t* n;
85 Agedge_t* e;
86 Agsym_t *sym;
87 Agsym_t *psym;
88 int nnodes;
89 int nedges;
90 int i, row;
91 int* I;
92 int* J;
93 double *val;
94 double v;
96
97 if (!g) return NULL;
98 nnodes = agnnodes (g);
99 nedges = agnedges (g);
100 if (format != FORMAT_CSR && format != FORMAT_COORD) {
101 fprintf (stderr, "Format %d not supported\n", format);
102 graphviz_exit(1);
103 }
104
105 /* Assign node ids */
106 i = 0;
107 for (n = agfstnode (g); n; n = agnxtnode (g, n))
108 ND_id(n) = i++;
109
110 if (format == FORMAT_COORD){
112 A->nz = nedges;
113 I = A->ia;
114 J = A->ja;
115 val = A->a;
116 } else {
117 I = gv_calloc(nedges, sizeof(int));
118 J = gv_calloc(nedges, sizeof(int));
119 val = gv_calloc(nedges, sizeof(double));
120 }
121
122 sym = agattr_text(g, AGEDGE, "weight", NULL);
123 i = 0;
124 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
125 row = ND_id(n);
126 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
127 I[i] = row;
128 J[i] = ND_id(aghead(e));
129
130 /* edge weight */
131 if (sym) {
132 if (sscanf (agxget(e,sym), "%lf", &v) != 1) v = 1;
133 } else {
134 v = 1;
135 }
136 val[i] = v;
137
138 i++;
139 }
140 }
141
142 if (x && (psym = agattr_text(g, AGNODE, "pos", NULL))) {
143 bool has_positions = true;
144 char* pval;
145 if (!(*x)) {
146 *x = gv_calloc(dim * nnodes, sizeof(double));
147 }
148 for (n = agfstnode (g); n && has_positions; n = agnxtnode (g, n)) {
149 double xx,yy, zz,ww;
150 int nitems;
151 i = ND_id(n);
152 if ((pval = agxget(n, psym)) && *pval) {
153 if (dim == 2){
154 nitems = sscanf(pval, "%lf,%lf", &xx, &yy);
155 if (nitems != 2) {
156 has_positions = false;
157 agerrorf("Node \"%s\" pos has %d < 2 values", agnameof(n), nitems);
158 }
159 (*x)[i*dim] = xx;
160 (*x)[i*dim+1] = yy;
161 } else if (dim == 3){
162 nitems = sscanf(pval, "%lf,%lf,%lf", &xx, &yy, &zz);
163 if (nitems != 3) {
164 has_positions = false;
165 agerrorf("Node \"%s\" pos has %d < 3 values", agnameof(n), nitems);
166 }
167 (*x)[i*dim] = xx;
168 (*x)[i*dim+1] = yy;
169 (*x)[i*dim+2] = zz;
170 } else if (dim == 4){
171 nitems = sscanf(pval, "%lf,%lf,%lf,%lf", &xx, &yy, &zz,&ww);
172 if (nitems != 4) {
173 has_positions = false;
174 agerrorf("Node \"%s\" pos has %d < 4 values", agnameof(n), nitems);
175 }
176 (*x)[i*dim] = xx;
177 (*x)[i*dim+1] = yy;
178 (*x)[i*dim+2] = zz;
179 (*x)[i*dim+3] = ww;
180 } else if (dim == 1){
181 nitems = sscanf(pval, "%lf", &xx);
182 if (nitems != 1){
184 A = NULL;
185 goto done;
186 }
187 (*x)[i*dim] = xx;
188 } else {
189 assert(0);
190 }
191 } else {
192 has_positions = false;
193 agerrorf("Node \"%s\" lacks position info", agnameof(n));
194 }
195 }
196 if (!has_positions) {
197 free(*x);
198 *x = NULL;
199 }
200 }
201 else if (x)
202 agerrorf("Error: graph %s has missing \"pos\" information", agnameof(g));
203
204 size_t sz = sizeof(double);
205 if (format == FORMAT_CSR) A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
206
207done:
208 if (format != FORMAT_COORD){
209 free(I);
210 free(J);
211 free(val);
212 }
213
214 return A;
215}
216
217/* get spline info */
218int Import_dot_splines(Agraph_t* g, int *ne, char ***xsplines){
219 /* get the list of splines for the edges in the order they appear, and store as a list of strings in xspline.
220 If *xsplines = NULL, it will be allocated. On exit (*xsplines)[i] is the control point string for the i-th edge. This string
221 is of the form "x1,y1 x2,y2...", the two end points of the edge is not included per Dot format
222 Return 1 if success. 0 if not.
223 */
224 Agnode_t* n;
225 Agedge_t* e;
226 Agsym_t *sym;
227 int nedges;
228 unsigned i;
229
230 if (!g){
231 return 0;
232 }
233
234 *ne = nedges = agnedges (g);
235
236 /* Assign node ids */
237 i = 0;
238 for (n = agfstnode (g); n; n = agnxtnode (g, n))
239 ND_id(n) = i++;
240
241 sym = agattr_text(g, AGEDGE, "pos", 0);
242 if (!sym) return 0;
243
244 *xsplines = gv_calloc(nedges, sizeof(char*));
245
246 i = 0;
247 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
248 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
249 /* edge weight */
250 char *pos = agxget (e, sym);
251 (*xsplines)[i] = strdup(pos);
252 i++;
253 }
254 }
255 return 1;
256}
257
258static int hex2int(char h){
259 if (h >= '0' && h <= '9') return h - '0';
260 if (h >= 'a' && h <= 'f') return 10 + h - 'a';
261 if (h >= 'A' && h <= 'F') return 10 + h - 'A';
262 return 0;
263}
264
265static float hexcol2rgb(const char *h) {
266 return (hex2int(h[0])*16 + hex2int(h[1]))/255.;
267}
268
269void Dot_SetClusterColor(Agraph_t* g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters){
270
271 Agnode_t* n;
272 agxbuf scluster = {0};
273 unsigned i;
274 Agsym_t* clust_clr_sym = agattr_text(g, AGNODE, "clustercolor", NULL);
275
276 if (!clust_clr_sym) clust_clr_sym = agattr_text(g, AGNODE, "clustercolor", "-1");
277 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
278 i = ND_id(n);
279 if (rgb_r && rgb_g && rgb_b) {
280 rgb2hex(rgb_r[clusters[i]], rgb_g[clusters[i]], rgb_b[clusters[i]],
281 &scluster, NULL);
282 }
283 agxset(n, clust_clr_sym, agxbuse(&scluster));
284 }
285 agxbfree(&scluster);
286}
287
288SparseMatrix 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){
289 SparseMatrix A = 0;
290 Agnode_t* n;
291 Agedge_t* e;
292 Agsym_t* sym;
293 Agsym_t* clust_sym;
294 Agsym_t* clust_clr_sym;
295 int nnodes;
296 int nedges;
297 int i, row, ic,nc, j;
298 double v;
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_text(g, AGEDGE, "weight", NULL);
364 clust_sym = agattr_text(g, AGNODE, "cluster", NULL);
365 clust_clr_sym = agattr_text(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_text(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 agxset(n, clust_sym, ITOS((*clusters)[i]));
454 }
455 MIN_GRPS = 1;
456 MAX_GRPS = nc;
457 if (Verbose){
458 fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
459 }
460 }
461
462 *label_sizes = gv_calloc(dim * nnodes, sizeof(double));
463 if (pal || (!noclusterinfo && clust_clr_sym)){
464 *rgb_r = gv_calloc(1 + MAX_GRPS, sizeof(float));
465 *rgb_g = gv_calloc(1 + MAX_GRPS, sizeof(float));
466 *rgb_b = gv_calloc(1 + MAX_GRPS, sizeof(float));
467 } else {
468 *rgb_r = NULL;
469 *rgb_g = NULL;
470 *rgb_b = NULL;
471 }
472 *fsz = gv_calloc(nnodes, sizeof(float));
473 *labels = gv_calloc(nnodes, sizeof(char*));
474
475 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
477 double sz;
478 i = ND_id(n);
479 if (agget(n, "width") && agget(n, "height")){
480 sscanf(agget(n, "width"), "%lf", &sz);
481 (*label_sizes)[i*2] = POINTS(sz*0.5);
482 sscanf(agget(n, "height"), "%lf", &sz);
483 (*label_sizes)[i*2+1] = POINTS(sz*0.5);
484 } else {
485 (*label_sizes)[i*2] = POINTS(0.75/2);
486 (*label_sizes)[i*2+1] = POINTS(0.5*2);
487 }
488
489 if (agget(n, "fontsize")){
490 sscanf(agget(n, "fontsize"), "%f", &ff);
491 (*fsz)[i] = ff;
492 } else {
493 (*fsz)[i] = 14;
494 }
495
496 if (agget(n, "label") && strcmp(agget(n, "label"), "") != 0 && strcmp(agget(n, "label"), "\\N") != 0){
497 char *lbs = agget(n, "label");
498 (*labels)[i] = strdup(lbs);
499 } else {
500 (*labels)[i] = strdup(agnameof(n));
501 }
502
503
504
505 j = (*clusters)[i];
506 if (MAX_GRPS-MIN_GRPS < max_color) {
507 j = (j-MIN_GRPS)*((int)((max_color-1)/MAX((MAX_GRPS-MIN_GRPS),1)));
508 } else {
509 j = (j-MIN_GRPS)%max_color;
510 }
511
512 if (pal){
513 (*rgb_r)[(*clusters)[i]] = pal[3*j+0];
514 (*rgb_g)[(*clusters)[i]] = pal[3*j+1];
515 (*rgb_b)[(*clusters)[i]] = pal[3*j+2];
516 }
517
518 if (!noclusterinfo && clust_clr_sym && (colorxlate(agxget(n,clust_clr_sym),&color,RGBA_DOUBLE) == COLOR_OK)) {
519 (*rgb_r)[(*clusters)[i]] = color.u.RGBA[0];
520 (*rgb_g)[(*clusters)[i]] = color.u.RGBA[1];
521 (*rgb_b)[(*clusters)[i]] = color.u.RGBA[2];
522 }
523
524 const char *cc = agget(n, "clustercolor");
525 if (!noclusterinfo && agget(n, "cluster") && cc && strlen(cc) >= 7 && pal) {
526 (*rgb_r)[(*clusters)[i]] = hexcol2rgb(cc+1);
527 (*rgb_g)[(*clusters)[i]] = hexcol2rgb(cc+3);
528 (*rgb_b)[(*clusters)[i]] = hexcol2rgb(cc+5);
529 }
530
531 }
532
533
534 if (x){
535 bool has_position = false;
536 *x = gv_calloc(dim * nnodes, sizeof(double));
537 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
538 double xx,yy;
539 i = ND_id(n);
540 if (agget(n, "pos")){
541 has_position = true;
542 sscanf(agget(n, "pos"), "%lf,%lf", &xx, &yy);
543 (*x)[i*dim] = xx;
544 (*x)[i*dim+1] = yy;
545 } else {
546 fprintf(stderr,"WARNING: pos field missing for node %d, set to origin\n",i);
547 (*x)[i*dim] = 0;
548 (*x)[i*dim+1] = 0;
549 }
550 }
551 if (!has_position){
552 free(*x);
553 *x = NULL;
554 }
555 }
556
557
558 free(I);
559 free(J);
560 free(val);
561
562 return A;
563}
564
565void attached_clustering(Agraph_t* g, int maxcluster, int clustering_scheme){
566 SparseMatrix A = 0;
567 Agnode_t* n;
568 Agedge_t* e;
569 Agsym_t *sym, *clust_sym;
570 int nnodes;
571 int nedges;
572 int i, row,nc;
573 double v;
575 size_t sz = sizeof(double);
576
577 if (!g) return;
578 nnodes = agnnodes (g);
579 nedges = agnedges (g);
580
581 /* Assign node ids */
582 i = 0;
583 for (n = agfstnode (g); n; n = agnxtnode (g, n))
584 ND_id(n) = i++;
585
586 /* form matrix */
587 int* I = gv_calloc(nedges, sizeof(int));
588 int* J = gv_calloc(nedges, sizeof(int));
589 double* val = gv_calloc(nedges, sizeof(double));
590
591 sym = agattr_text(g, AGEDGE, "weight", NULL);
592 clust_sym = agattr_text(g, AGNODE, "cluster", NULL);
593
594 i = 0;
595 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
596 row = ND_id(n);
597 for (e = agfstout (g, n); e; e = agnxtout (g, e)) {
598 I[i] = row;
599 J[i] = ND_id(aghead(e));
600 if (sym) {
601 if (sscanf (agxget(e,sym), "%lf", &v) != 1)
602 v = 1;
603 }
604 else
605 v = 1;
606 val[i] = v;
607 i++;
608 }
609 }
610 A = SparseMatrix_from_coordinate_arrays(nedges, nnodes, nnodes, I, J, val, type, sz);
611
612 int *clusters = gv_calloc(nnodes, sizeof(int));
613
614 {
615 double modularity;
616 if (!clust_sym) clust_sym = agattr_text(g,AGNODE,"cluster","-1");
617
618 if (clustering_scheme == CLUSTERING_MQ){
619 mq_clustering(A, maxcluster,
620 &nc, &clusters, &modularity);
621 } else if (clustering_scheme == CLUSTERING_MODULARITY){
622 modularity_clustering(A, false, maxcluster,
623 &nc, &clusters, &modularity);
624 } else {
625 UNREACHABLE();
626 }
627 for (i = 0; i < nnodes; i++) (clusters)[i]++;/* make into 1 based */
628 for (n = agfstnode (g); n; n = agnxtnode (g, n)) {
629 i = ND_id(n);
630 agxset(n, clust_sym, ITOS(clusters[i]));
631 }
632 if (Verbose){
633 fprintf(stderr," no complement clustering info in dot file, using modularity clustering. Modularity = %f, ncluster=%d\n",modularity, nc);
634 }
635 }
636
637 free(I);
638 free(J);
639 free(val);
640 free(clusters);
641
643
644}
645
646
647
649{
650 aginit(g, AGNODE, "info", sizeof(Agnodeinfo_t), true);
651}
652
653void setDotNodeID (Agnode_t* n, int v)
654{
655 ND_id(n) = v;
656}
657
659{
660 return ND_id(n);
661}
662
#define ND_id(n)
Definition DotIO.c:32
void Dot_SetClusterColor(Agraph_t *g, float *rgb_r, float *rgb_g, float *rgb_b, int *clusters)
Definition DotIO.c:269
SparseMatrix SparseMatrix_import_dot(Agraph_t *g, int dim, double **x, int format)
Definition DotIO.c:81
int getDotNodeID(Agnode_t *n)
Definition DotIO.c:658
void initDotIO(Agraph_t *g)
Definition DotIO.c:648
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:288
static float hexcol2rgb(const char *h)
Definition DotIO.c:265
void attach_edge_colors(Agraph_t *g, int dim, double *colors)
Definition DotIO.c:51
static void color_string(agxbuf *buf, int dim, double *color)
Definition DotIO.c:34
void setDotNodeID(Agnode_t *n, int v)
Definition DotIO.c:653
static int hex2int(char h)
Definition DotIO.c:258
void attached_clustering(Agraph_t *g, int maxcluster, int clustering_scheme)
Definition DotIO.c:565
int Import_dot_splines(Agraph_t *g, int *ne, char ***xsplines)
Definition DotIO.c:218
@ 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)
@ FORMAT_COORD
@ FORMAT_CSR
@ MATRIX_TYPE_REAL
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:65
@ 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:206
#define A(n, t)
Definition expr.h:76
#define I
Definition expr.h:71
#define POINTS(a_inches)
Definition geom.h:62
static bool Verbose
Definition gml2gv.c:23
void free(void *)
node NULL
Definition grammar.y:180
int agnedges(Agraph_t *g)
Definition graph.c:163
int agnnodes(Agraph_t *g)
Definition graph.c:157
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:348
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:536
char * agget(void *obj, char *name)
Definition attr.c:462
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:472
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:26
#define aghead(e)
Definition cgraph.h:989
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:41
void agerrorf(const char *fmt,...)
Definition agerror.c:165
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:48
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:41
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:143
@ 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:73
Agraph_t * agnxtsubg(Agraph_t *subg)
Definition subg.c:78
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
#define ITOS(i)
Definition itos.h:43
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:29
graph or subgraph
Definition cgraph.h:424
implementation of Agrec_t
Definition cgraph.h:172
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:651
#define UNREACHABLE()
Definition unreachable.h:30
#define MAX(a, b)
Definition write.c:31