home *** CD-ROM | disk | FTP | other *** search
- /**
- GRAB Graph Layout and Browser System
-
- Copyright (c) 1986, 1988 Regents of the University of California
- Copyright (c) 1989, Tera Computer Company
- **/
-
- /**
- routines2.c -- more fun menu routines, including most of the
- statistics dumping routines and the checkpoint routines
- **/
-
- #include "malloc.h"
- #include <math.h>
-
- #include "attribute.h"
- #include "digraph.h"
- #include "screen.h"
- #include "globals.h"
- #include "scrdep.h"
- #include "interf.h"
- #include "checkpoint.h"
- #include "cursor.h"
-
- extern NODE *next_dummy();
-
- void DoPrintDistributionStats();
-
- DumpBox(b)
- BOX *b;
- {
- printf("min_x=%d, max_x=%d, min_y=%d, max_y=%d",
- b->min_x, b->max_x, b->min_y, b->max_y);
- }
-
- /**
- For button area.
- Can't press buttons while moving or inserting.
- Can press button while changing labels (just leave the current mode)
- **/
-
- BOOL GetInCTextModeFlag()
- {
- return (inChangeTextMode);
- }
-
- BOOL GetInCEdgeLabelModeFlag()
- {
- return (inChangeEdgeLabelMode);
- }
-
- BOOL GetInFNodeModeFlag()
- {
- return (inFocusNodeMode);
- }
-
- BOOL GetInCModeFlag()
- {
- return (inChangeTextMode || inChangeEdgeLabelMode || inFocusNodeMode);
- }
-
- void ClearInModeFlag()
- {
- inChangeTextMode = FALSE;
- inChangeEdgeLabelMode = FALSE;
- inFocusNodeMode = FALSE;
- }
-
- void DoPrintLayoutStats()
- {
- printf("\n*XGRAB LAYOUT STATS*\n");
- PrintNodeStats();
- PrintEdgeStats();
- PrintLevelStats();
- PrintCrossingsStats();
- DoPrintDistributionStats();
- PrintAbsCoordStats();
- }
-
- PrintNodeStats()
- {
- NODE *node;
- int dummyNodeCount, realNodeCount;
-
- dummyNodeCount = realNodeCount = 0;
-
- each_node(digraph, node)
- loop
- if (Is_dummy(node))
- {
- dummyNodeCount++;
- }
- else
- {
- realNodeCount++;
- }
- endloop
-
- printf("total # of nodes: %d (real=%d;dummy=%d)\n",
- dummyNodeCount+realNodeCount, realNodeCount, dummyNodeCount);
- }
-
- Length(fromMember, toMember)
- MEMBER *fromMember, *toMember;
- {
- int xdist, ydist, dist;
-
- xdist = X_position(fromMember) - X_position(toMember);
- ydist = Y_position(fromMember) - Y_position(toMember);
- dist = (xdist * xdist) + (ydist * ydist);
-
- return((int) sqrt((double) dist));
- };
-
- PrintEdgeStats()
- {
- VNO toVno; /* each succedent node */
- NODE *node, *toNode;
- int totalEdgeCount, shortEdgeCount, longEdgeCount, segmentCount;
- int totalEdgeLength;
-
- totalEdgeCount = shortEdgeCount = longEdgeCount = segmentCount = 0;
- totalEdgeLength = 0;
-
- each_node(digraph, node)
- loop
- if (Is_dummy(node))
- {
- continue;
- }
-
- each_element(Succ_set(node), toVno)
- loop
- toNode = Node(digraph, toVno);
- totalEdgeCount++;
- totalEdgeLength += Length(Node_member(node), Node_member(toNode));
-
- if (!Is_dummy(toNode))
- {
- shortEdgeCount++;
- segmentCount++;
- }
- else
- {
- longEdgeCount++;
- segmentCount++;
- toNode = next_dummy(digraph, node);
-
- while (Is_dummy(toNode))
- {
- segmentCount++;
- totalEdgeLength += Length(Node_member(node),
- Node_member(toNode));
- toNode = next_dummy(digraph, toNode);
- }
-
- segmentCount++;
- totalEdgeLength += Length(Node_member(node),
- Node_member(toNode));
- }
- endloop
- endloop
-
- printf("total # of edges: %d (short: %d, long: %d)\n", totalEdgeCount,
- shortEdgeCount, longEdgeCount);
- printf("total segments: %d\n", segmentCount);
- printf("total edge length: %d\n", totalEdgeLength);
- }
-
- #define MAX_LEV_ARRAY 512
-
- PrintLevelStats()
- {
- int i, count = 0;
- LEVEL *level;
- MEMBER *member;
- double stdDev, mean, sum, diff;
- int maxLevelCoord, median, levArray[MAX_LEV_ARRAY];
-
- if (!digraph->levels)
- {
- printf("level stats unavailable - no level structure\n");
- return;
- }
-
- each_level(digraph, level)
- loop
- each_member(level, member)
- loop
- if (count < MAX_LEV_ARRAY)
- {
- levArray[count++] = Y_position(member);
- }
- else
- {
- fprintf(stderr, "PrintLevelStats: outa room in levArray\n");
- }
- break;
- endloop
- endloop
-
- /* calc maxLevelCoord */
- maxLevelCoord = levArray[0];
-
- /* calc median */
- median = levArray[(count-1)/2];
-
- /* calc mean */
- sum = 0.0;
-
- for (i = 0; i < count; i++)
- {
- sum += levArray[i];
- }
-
- mean = sum/(double)count;
-
- /* calc std dev */
- sum = 0.0;
-
- for (i = 0; i < count; i++)
- {
- diff = (double)levArray[i] - mean;
- sum += diff * diff;
- }
-
- sum = sum / (double) count;
- stdDev = sqrt(sum);
-
- printf("# levels = %d; ", count);
- printf("max = %d; median = %d; mean = %.2f; std dev = %.2f\n",
- maxLevelCoord, median, mean, stdDev);
- }
-
- PrintCrossingsStats()
- {
- if (!digraph->levels)
- {
- printf("crossings stats is unavailable - no level structure\n");
- }
- else
- {
- printf("# of edge crossings = %d\n", num_crossings(digraph));
- }
- }
-
- #define MAX_XBINS 4
- #define MAX_YBINS 4
-
- void DoPrintDistributionStats()
- {
-
- BOX absView;
- NODE *node;
- int bins[MAX_XBINS][MAX_YBINS];
- int num_xbins, num_ybins, xbin, ybin, count, i, j;
- float xDiv, yDiv, mean, diff, variance;
-
- printf("Node Spatial Distribution:\n");
- FindRange(digraph, &absView);
-
- for (num_xbins = 1, num_ybins = 1;
- num_xbins <= MAX_XBINS && num_ybins <= MAX_YBINS;
- num_xbins++, num_ybins++)
- {
- xDiv = (absView.max_x - absView.min_x) / (float) num_xbins;
- yDiv = (absView.max_y - absView.min_y) / (float) num_ybins;
-
- count = 0;
- for (i = 0; i < num_xbins; i++)
- {
- for (j = 0; j < num_ybins; j++)
- {
- bins[i][j] = 0;
- }
- }
-
- each_node(digraph, node)
- loop
- if (!Is_dummy(node))
- {
- /*
- * Compute the bin this node falls into, and increment count.
- */
- xbin = (X_position(Node_member(node)) - absView.min_x) / xDiv;
- ybin = (Y_position(Node_member(node)) - absView.min_y) / yDiv;
- bins[xbin][ybin]++;
- count++;
- }
- endloop
-
- /*
- * Calculate mean and variance for bins entries.
- */
- mean = (float) count / (num_xbins * num_ybins);
- variance = 0.0;
-
- for (i = 0; i < num_xbins; i++)
- {
- for (j = 0; j < num_ybins; j++)
- {
- diff = (float) bins[i][j] - mean;
- variance += diff * diff;
- }
- }
-
- variance = variance / (num_xbins * num_ybins);
- printf("\t%d x %d bins, Var = %5.2f\n", num_xbins, num_ybins, variance);
- }
- } /* DoPrintDistributionStats */
-
- PrintAbsCoordStats()
- {
- BOX absView;
-
- FindRange(digraph, &absView);
- printf("absolute view bounding box: min_x=%d, min_y=%d, max_x=%d, max_y=%d\n",
- absView.min_x, absView.min_y, absView.max_x, absView.max_y);
- }
-
- void DoDumpNodeList()
- {
- NODE *node;
-
- each_node(digraph, node)
- loop
- DumpNode(node);
- endloop
- }
-
- DumpNode(node)
- NODE *node;
- {
- printf("node=/%s/; vno=%d; x_pos=%d; y_pos=%d\n",
- Text(node), Vno(node), X_position(node), Y_position(node));
- }
-
- DIGRAPH* copy_digraph();
-
- DoSaveCkpt()
- {
- int i;
- char *buf;
-
- buf = (char *) malloc(sizeof(char) * MAXLINE);
- IChangeStatusLine("Saving current graph", TRUE);
-
- for (i = curr_ckpt + 1; i < num_ckpts; i++)
- {
- dispose_digraph(ckpts[i]->digraph);
- dispose(ckpts[i]);
- }
-
- create_checkpoint();
- sprintf(buf, "Saved as checkpoint #%d", num_ckpts);
- IChangeStatusLine(buf, FALSE);
- ckpt_done = TRUE;
- dispose(buf);
- }
-
- create_checkpoint()
- {
- curr_ckpt++;
- num_ckpts = curr_ckpt + 1;
-
- if (num_ckpts != 1)
- {
- ckpts = (CHECKPT **) realloc((char *) ckpts,
- num_ckpts * sizeof(CHECKPT *));
- }
- else
- {
- ckpts = (CHECKPT **) malloc(sizeof(CHECKPT *));
- }
-
- new(ckpts[curr_ckpt], CHECKPT);
- ckpts[curr_ckpt]->digraph = copy_digraph(digraph);
- }
-
- DoPrevCkpt()
- {
- char *buf;
-
- buf = (char *) malloc(sizeof(char) * MAXLINE);
- IChangeStatusLine("Going to previous checkpoint", TRUE);
- ISetCursor(waitC);
-
- if (curr_ckpt > 0 || !ckpt_done && curr_ckpt == 0)
- {
- /* if we've changed the graph since the last checkpoint, just go back
- to the current one, otherwise, go back one */
- if (ckpt_done)
- {
- curr_ckpt--;
- }
-
- dispose_digraph(digraph);
- digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
- DisplayNewGraph();
- sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
- IChangeStatusLine(buf, FALSE);
- ckpt_done = TRUE;
- }
- else
- {
- IChangeStatusLine("No checkpoints before this one.", FALSE);
- }
-
- IUnsetCursor();
- dispose(buf);
- }
-
- DoNextCkpt()
- {
- char *buf;
-
- buf = (char *) malloc(sizeof(char) * MAXLINE);
- IChangeStatusLine("Going to next checkpoint", TRUE);
- ISetCursor(waitC);
-
- if (curr_ckpt + 1 < num_ckpts)
- {
- curr_ckpt++;
- dispose_digraph(digraph);
- digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
- DisplayNewGraph();
- sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
- IChangeStatusLine(buf, FALSE);
- ckpt_done = TRUE;
- }
- else
- {
- IChangeStatusLine("No checkpoints after this one.", FALSE);
- }
-
- IUnsetCursor();
- dispose(buf);
- }
-
- double GetAspRatio()
- {
- return (double) aspratio;
- }
-