Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
topfisheyeview.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#include "topfisheyeview.h"
11#include <cgraph/alloc.h>
12#include <math.h>
13#include "viewport.h"
14#include "viewportcamera.h"
15#include "draw.h"
16#include "smyrna_utils.h"
17
18#include <assert.h>
19#include "hier.h"
20#include "topfisheyeview.h"
21#include <string.h>
22#include <common/color.h>
23#include <common/colorprocs.h>
24
25static int get_temp_coords(topview * t, int level, int v, double *coord_x,
26 double *coord_y);
27
28static void color_interpolation(glCompColor srcColor, glCompColor tarColor,
29 glCompColor * color, int levelcount,
30 int level)
31{
32 if (levelcount <= 0)
33 return;
34
35
36 color->R =
37 ((float) level * tarColor.R - (float) level * srcColor.R +
38 (float) levelcount * srcColor.R) / (float) levelcount;
39 color->G =
40 ((float) level * tarColor.G - (float) level * srcColor.G +
41 (float) levelcount * srcColor.G) / (float) levelcount;
42 color->B =
43 ((float) level * tarColor.B - (float) level * srcColor.B +
44 (float) levelcount * srcColor.B) / (float) levelcount;
45}
46
47static v_data *makeGraph(Agraph_t* gg, int *nedges)
48{
49 int i;
50 int ne = agnedges(gg);
51 int nv = agnnodes(gg);
52 v_data *graph = gv_calloc(nv, sizeof(v_data));
53 int *edges = gv_calloc(2 * ne + nv, sizeof(int)); /* reserve space for self loops */
54 float *ewgts = gv_calloc(2 * ne + nv, sizeof(float));
55 Agnode_t *np;
56 Agedge_t *ep;
57 Agraph_t *g = NULL;
58 int i_nedges;
59 ne = 0;
60 i=0;
61 for (np = agfstnode(gg); np; np = agnxtnode(gg, np))
62 {
63 graph[i].edges = edges++; /* reserve space for the self loop */
64 graph[i].ewgts = ewgts++;
65#ifdef STYLES
66 graph[i].styles = NULL;
67#endif
68 i_nedges = 1; /* one for the self */
69
70 if (!g)
71 g = agraphof(np);
72 for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np))
73 {
74 Agnode_t *vp;
75 Agnode_t *tp = agtail(ep);
76 Agnode_t *hp = aghead(ep);
77 assert(hp != tp);
78 /* FIX: handle multiedges */
79 vp = (tp == np ? hp : tp);
80 ne++;
81 i_nedges++;
82 *edges++ = ND_TVref(vp);
83 *ewgts++ = 1;
84
85 }
86
87 graph[i].nedges = i_nedges;
88 graph[i].edges[0] = i;
89 graph[i].ewgts[0] = 1 - i_nedges;
90 i++;
91 }
92 ne /= 2; /* each edge counted twice */
93 *nedges = ne;
94 return graph;
95}
96
98{
99 int level, v;
100 Hierarchy *hp = t->fisheyeParams.h;
101 for (level = 0; level < hp->nlevels; level++) {
102 for (v = 0; v < hp->nvtxs[level]; v++) {
103 ex_vtx_data *gg = hp->geom_graphs[level];
106 gg[v].old_active_level = gg[v].active_level;
107 }
108 }
109
110}
111
112/* To use:
113 * double* x_coords; // initial x coordinates
114 * double* y_coords; // initial y coordinates
115 * focus_t* fs;
116 * int ne;
117 * v_data* graph = makeGraph (topview*, &ne);
118 * hierarchy = makeHier(topview->NodeCount, ne, graph, x_coords, y_coords);
119 * freeGraph (graph);
120 * fs = initFocus (topview->Nodecount); // create focus set
121 */
123{
124 double *x_coords = gv_calloc(t->Nodecount, sizeof(double)); // initial x coordinates
125 double *y_coords = gv_calloc(t->Nodecount, sizeof(double)); // initial y coordinates
126 focus_t *fs;
127 int ne;
128 int i;
129 int closest_fine_node;
130 int cur_level = 0;
131 Hierarchy *hp;
132 gvcolor_t cl;
133 Agnode_t *np;
134
135 v_data *graph = makeGraph(g, &ne);
136
137 i=0;
138 for (np = agfstnode(g); np; np = agnxtnode(g, np))
139 {
140 x_coords[i]=ND_A(np).x;
141 y_coords[i]=ND_A(np).y;
142 i++;
143 }
144 hp = t->fisheyeParams.h =
145 makeHier(agnnodes(g), ne, graph, x_coords, y_coords,
146 &(t->fisheyeParams.hier));
148 free(x_coords);
149 free(y_coords);
150
151 fs = t->fisheyeParams.fs = initFocus(agnnodes(g)); // create focus set
152
153 closest_fine_node = 0; /* first node */
154 fs->num_foci = 1;
155 fs->foci_nodes[0] = closest_fine_node;
156 fs->x_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].x_coord;
157 fs->y_foci[0] = hp->geom_graphs[cur_level][closest_fine_node].y_coord;
158
160 (int) (view->bdxRight - view->bdxLeft);
162 (int) (view->bdyTop - view->bdyBottom);
163
164 //topological fisheye
165
167 ("topologicalfisheyefinestcolor", view,
168 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
169 view->Topview->fisheyeParams.srcColor.R = (float) cl.u.RGBA[0];
170 view->Topview->fisheyeParams.srcColor.G = (float) cl.u.RGBA[1];
171 view->Topview->fisheyeParams.srcColor.B = (float) cl.u.RGBA[2];
173 ("topologicalfisheyecoarsestcolor", view,
174 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
175 view->Topview->fisheyeParams.tarColor.R = (float) cl.u.RGBA[0];
176 view->Topview->fisheyeParams.tarColor.G = (float) cl.u.RGBA[1];
177 view->Topview->fisheyeParams.tarColor.B = (float) cl.u.RGBA[2];
178
179
180 sscanf(agget
182 "topologicalfisheyedistortionfactor"), "%lf",
184 sscanf(agget
185 (view->g[view->activeGraph], "topologicalfisheyefinenodes"),
187 sscanf(agget
189 "topologicalfisheyecoarseningfactor"), "%lf",
191 sscanf(agget
192 (view->g[view->activeGraph], "topologicalfisheyedist2limit"),
194 sscanf(agget(view->g[view->activeGraph], "topologicalfisheyeanimate"),
196
198 positionAllItems(hp, fs, &(t->fisheyeParams.repos));
200}
201
202static void drawtopfishnodes(topview * t)
203{
204 glCompColor srcColor;
205 glCompColor tarColor;
207 int level, v;
208 Hierarchy *hp = t->fisheyeParams.h;
209 static int max_visible_level = 0;
210 srcColor.R = view->Topview->fisheyeParams.srcColor.R;
211 srcColor.G = view->Topview->fisheyeParams.srcColor.G;
212 srcColor.B = view->Topview->fisheyeParams.srcColor.B;
213 tarColor.R = view->Topview->fisheyeParams.tarColor.R;
214 tarColor.G = view->Topview->fisheyeParams.tarColor.G;
215 tarColor.B = view->Topview->fisheyeParams.tarColor.B;
216
217 //drawing nodes
218 glPointSize(7);
219 level = 0;
220 glBegin(GL_POINTS);
221 for (level = 0; level < hp->nlevels; level++) {
222 for (v = 0; v < hp->nvtxs[level]; v++) {
223 double x0, y0;
224 if (get_temp_coords(t, level, v, &x0, &y0)) {
225
226 if (!(((-x0 / view->zoom > view->clipX1)
227 && (-x0 / view->zoom < view->clipX2)
228 && (-y0 / view->zoom > view->clipY1)
229 && (-y0 / view->zoom < view->clipY2))))
230 continue;
231
232 if (max_visible_level < level)
233 max_visible_level = level;
234 color_interpolation(srcColor, tarColor, &color,
235 max_visible_level, level);
236 glColor4f(color.R, color.G, color.B, view->defaultnodealpha);
237
238 glVertex3f((float)x0, (float)y0, 0.0f);
239 }
240 }
241 }
242 glEnd();
243
244}
245
246static void drawtopfishedges(topview * t)
247{
248 glCompColor srcColor;
249 glCompColor tarColor;
251
252 int level, v, i, n;
253 Hierarchy *hp = t->fisheyeParams.h;
254 static int max_visible_level = 0;
255 srcColor.R = view->Topview->fisheyeParams.srcColor.R;
256 srcColor.G = view->Topview->fisheyeParams.srcColor.G;
257 srcColor.B = view->Topview->fisheyeParams.srcColor.B;
258 tarColor.R = view->Topview->fisheyeParams.tarColor.R;
259 tarColor.G = view->Topview->fisheyeParams.tarColor.G;
260 tarColor.B = view->Topview->fisheyeParams.tarColor.B;
261
262 //and edges
263 glBegin(GL_LINES);
264 for (level = 0; level < hp->nlevels; level++) {
265 for (v = 0; v < hp->nvtxs[level]; v++) {
266 v_data *g = hp->graphs[level];
267 double x0, y0;
268 if (get_temp_coords(t, level, v, &x0, &y0)) {
269 for (i = 1; i < g[v].nedges; i++) {
270 double x, y;
271 n = g[v].edges[i];
272
273
274 if (max_visible_level < level)
275 max_visible_level = level;
276 color_interpolation(srcColor, tarColor, &color,
277 max_visible_level, level);
278 glColor4f(color.R, color.G, color.B, view->defaultnodealpha);
279
280 if (get_temp_coords(t, level, n, &x, &y)) {
281 glVertex3f((float)x0, (float)y0, 0.0f);
282 glVertex3f((float)x, (float)y, 0.0f);
283 } else
284 {
285 int levell, nodee;
286 find_active_ancestor_info(hp, level, n, &levell,
287 &nodee);
288 if (get_temp_coords(t, levell, nodee, &x, &y)) {
289
290 if (!(-x0 / view->zoom > view->clipX1
291 && -x0 / view->zoom < view->clipX2
292 && -y0 / view->zoom > view->clipY1
293 && -y0 / view->zoom < view->clipY2)
294 && !(-x / view->zoom > view->clipX1
295 && -x / view->zoom < view->clipX2
296 && -y / view->zoom > view->clipY1
297 && -y / view->zoom < view->clipY2))
298
299 continue;
300
301
302 glVertex3f((float)x0, (float)y0, 0.0f);
303 glVertex3f((float)x, (float)y, 0.0f);
304 }
305 }
306 }
307 }
308 }
309 }
310 glEnd();
311
312}
313
314static int get_active_frame(void)
315{
316 gulong microseconds;
317 gdouble seconds;
318 int fr;
319 seconds = g_timer_elapsed(view->timer, &microseconds);
320 fr = (int)(seconds * 1000.0);
321 if (fr < view->total_frames) {
322
323 if (fr == view->active_frame)
324 return 0;
325 else {
326 view->active_frame = fr;
327 return 1;
328 }
329 } else {
330 g_timer_stop(view->timer);
332 return 0;
333 }
334
335}
336
343
344static void get_interpolated_coords(double x0, double y0, double x1, double y1,
345 int fr, int total_fr, double *x, double *y)
346{
347 *x = x0 + (x1 - x0) / (double) total_fr *(double) (fr + 1);
348 *y = y0 + (y1 - y0) / (double) total_fr *(double) (fr + 1);
349}
350
351static int get_temp_coords(topview * t, int level, int v, double *coord_x,
352 double *coord_y)
353{
354 Hierarchy *hp = t->fisheyeParams.h;
355 ex_vtx_data *gg = hp->geom_graphs[level];
356
357 if (!t->fisheyeParams.animate) {
358 if (gg[v].active_level != level)
359 return 0;
360
361 *coord_x = (double) gg[v].physical_x_coord;
362 *coord_y = (double) gg[v].physical_y_coord;
363 } else {
364
365
366 double x0, y0, x1, y1;
367 int OAL, AL;
368
369 x0 = 0;
370 y0 = 0;
371 x1 = 0;
372 y1 = 0;
373 AL = gg[v].active_level;
374 OAL = gg[v].old_active_level;
375
376 if ((OAL < level) || (AL < level)) //no draw
377 return 0;
378 if ((OAL >= level) || (AL >= level)) //draw the node
379 {
380 if ((OAL == level) && (AL == level)) //draw as is from old coords to new)
381 {
382 x0 = (double) gg[v].old_physical_x_coord;
383 y0 = (double) gg[v].old_physical_y_coord;
384 x1 = (double) gg[v].physical_x_coord;
385 y1 = (double) gg[v].physical_y_coord;
386 }
387 if ((OAL > level) && (AL == level)) //draw as from ancs to new)
388 {
389 find_old_physical_coords(t->fisheyeParams.h, level, v, &x0, &y0);
390 x1 = (double) gg[v].physical_x_coord;
391 y1 = (double) gg[v].physical_y_coord;
392 }
393 if ((OAL == level) && (AL > level)) //draw as from ancs to new)
394 {
395 find_physical_coords(t->fisheyeParams.h, level, v, &x1, &y1);
396 x0 = (double) gg[v].old_physical_x_coord;
397 y0 = (double) gg[v].old_physical_y_coord;
398 }
400 view->total_frames, coord_x, coord_y);
401 if ((x0 == 0) || (x1 == 0))
402 return 0;
403
404 }
405 }
406 return 1;
407}
408
409void changetopfishfocus(topview * t, float *x, float *y, int num_foci)
410{
411
412 gvcolor_t cl;
413 focus_t *fs = t->fisheyeParams.fs;
414 int i;
415 int closest_fine_node;
416 int cur_level = 0;
417
418 Hierarchy *hp = t->fisheyeParams.h;
420 fs->num_foci = num_foci;
421 for (i = 0; i < num_foci; i++) {
422 find_closest_active_node(hp, x[i], y[i], &closest_fine_node);
423 fs->foci_nodes[i] = closest_fine_node;
424 fs->x_foci[i] =
425 hp->geom_graphs[cur_level][closest_fine_node].x_coord;
426 fs->y_foci[i] =
427 hp->geom_graphs[cur_level][closest_fine_node].y_coord;
428 }
429
430
432 (int) (view->bdxRight - view->bdxLeft);
434 (int) (view->bdyTop - view->bdyBottom);
435
437 ("topologicalfisheyefinestcolor", view,
438 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
439 view->Topview->fisheyeParams.srcColor.R = (float) cl.u.RGBA[0];
440 view->Topview->fisheyeParams.srcColor.G = (float) cl.u.RGBA[1];
441 view->Topview->fisheyeParams.srcColor.B = (float) cl.u.RGBA[2];
443 ("topologicalfisheyecoarsestcolor", view,
444 view->g[view->activeGraph]), &cl, RGBA_DOUBLE);
445 view->Topview->fisheyeParams.tarColor.R = (float) cl.u.RGBA[0];
446 view->Topview->fisheyeParams.tarColor.G = (float) cl.u.RGBA[1];
447 view->Topview->fisheyeParams.tarColor.B = (float) cl.u.RGBA[2];
448
449
450
451 sscanf(agget
453 "topologicalfisheyedistortionfactor"), "%lf",
455 sscanf(agget
456 (view->g[view->activeGraph], "topologicalfisheyefinenodes"),
458 sscanf(agget
460 "topologicalfisheyecoarseningfactor"), "%lf",
462 sscanf(agget
463 (view->g[view->activeGraph], "topologicalfisheyedist2limit"),
465 sscanf(agget(view->g[view->activeGraph], "topologicalfisheyeanimate"),
467
468
469
470
472
473
474 positionAllItems(hp, fs, &(t->fisheyeParams.repos));
475
477
478 if (t->fisheyeParams.animate) {
479 view->active_frame = 0;
480 g_timer_start(view->timer);
481 }
482
483}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
@ RGBA_DOUBLE
Definition color.h:27
void colorxlate(char *str, agxbuf *buf)
Definition colxlate.c:48
void freeGraph(v_data *graph)
Definition delaunay.c:852
void free(void *)
node NULL
Definition grammar.y:149
int agnedges(Agraph_t *g)
Definition graph.c:164
int agnnodes(Agraph_t *g)
Definition graph.c:158
char * agget(void *obj, char *name)
Definition attr.c:442
#define agtail(e)
Definition cgraph.h:889
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:93
#define aghead(e)
Definition cgraph.h:890
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:84
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
Agraph_t * agraphof(void *obj)
Definition obj.c:184
Agraph_t * graph(char *name)
Definition gv.cpp:31
static void color(Agraph_t *g)
Definition gvcolor.c:128
Hierarchy * makeHier(int nn, int ne, v_data *graph, double *x_coords, double *y_coords, hierparms_t *parms)
Definition hier.c:99
void positionAllItems(Hierarchy *hp, focus_t *fs, reposition_t *parms)
Definition hier.c:18
focus_t * initFocus(int ncnt)
Definition hier.c:130
void set_active_levels(Hierarchy *hierarchy, int *foci_nodes, int num_foci, levelparms_t *parms)
Definition hierarchy.c:753
double find_closest_active_node(Hierarchy *hierarchy, double x, double y, int *closest_fine_node)
Definition hierarchy.c:929
void find_active_ancestor_info(Hierarchy *hierarchy, int level, int node, int *levell, int *nodee)
Definition hierarchy.c:1078
void find_old_physical_coords(Hierarchy *hierarchy, int level, int node, double *x, double *y)
Definition hierarchy.c:1097
void find_physical_coords(Hierarchy *hierarchy, int level, int node, double *x, double *y)
Definition hierarchy.c:1064
static int nedges
total no. of edges used in routing
Definition routespl.c:31
ViewInfo * view
Definition viewport.c:38
#define ND_TVref(n)
Definition smyrnadefs.h:183
#define ND_A(n)
Definition smyrnadefs.h:181
graph or subgraph
Definition cgraph.h:425
v_data ** graphs
Definition hierarchy.h:40
int * nvtxs
Definition hierarchy.h:42
ex_vtx_data ** geom_graphs
Definition hierarchy.h:41
int nlevels
Definition hierarchy.h:39
float bdxLeft
Definition smyrnadefs.h:307
int active_frame
Definition smyrnadefs.h:341
topview * Topview
Definition smyrnadefs.h:334
Agraph_t ** g
Definition smyrnadefs.h:313
int total_frames
Definition smyrnadefs.h:342
float clipX2
Definition smyrnadefs.h:278
float bdyTop
Definition smyrnadefs.h:307
GTimer * timer
Definition smyrnadefs.h:336
int activeGraph
Definition smyrnadefs.h:317
float bdxRight
Definition smyrnadefs.h:308
float bdyBottom
Definition smyrnadefs.h:308
float zoom
Definition smyrnadefs.h:275
float clipY1
Definition smyrnadefs.h:278
float clipX1
Definition smyrnadefs.h:278
float clipY2
Definition smyrnadefs.h:278
float defaultnodealpha
Definition smyrnadefs.h:293
double RGBA[4]
Definition color.h:32
union color_s::@72 u
float physical_y_coord
Definition hierarchy.h:29
float old_physical_y_coord
Definition hierarchy.h:32
float old_physical_x_coord
Definition hierarchy.h:31
int old_active_level
Definition hierarchy.h:33
float physical_x_coord
Definition hierarchy.h:28
float x_coord
Definition hierarchy.h:24
int active_level
Definition hierarchy.h:20
float y_coord
Definition hierarchy.h:25
Definition hier.h:15
int * foci_nodes
Definition hier.h:17
int num_foci
Definition hier.h:16
double * y_foci
Definition hier.h:19
double * x_foci
Definition hier.h:18
int dist2_limit
Definition hierarchy.h:63
int num_fine_nodes
Definition hierarchy.h:56
double coarsening_rate
Definition hierarchy.h:57
double distortion
Definition hier.h:26
int height
Definition hier.h:25
int width
Definition hier.h:24
hierparms_t hier
Definition smyrnadefs.h:242
int animate
Definition smyrnadefs.h:244
Hierarchy * h
Definition smyrnadefs.h:243
glCompColor srcColor
Definition smyrnadefs.h:245
reposition_t repos
Definition smyrnadefs.h:240
focus_t * fs
Definition smyrnadefs.h:247
struct topview::@55 fisheyeParams
size_t Nodecount
Definition smyrnadefs.h:237
levelparms_t level
Definition smyrnadefs.h:241
glCompColor tarColor
Definition smyrnadefs.h:246
int nedges
Definition sparsegraph.h:22
int * edges
Definition sparsegraph.h:23
static void get_interpolated_coords(double x0, double y0, double x1, double y1, int fr, int total_fr, double *x, double *y)
void changetopfishfocus(topview *t, float *x, float *y, int num_foci)
static void color_interpolation(glCompColor srcColor, glCompColor tarColor, glCompColor *color, int levelcount, int level)
static void refresh_old_values(topview *t)
static void drawtopfishedges(topview *t)
static int get_temp_coords(topview *t, int level, int v, double *coord_x, double *coord_y)
static void drawtopfishnodes(topview *t)
static int get_active_frame(void)
void drawtopologicalfisheye(topview *t)
void prepare_topological_fisheye(Agraph_t *g, topview *t)
static v_data * makeGraph(Agraph_t *gg, int *nedges)
char * get_attribute_value(char *attr, ViewInfo *vi, Agraph_t *g)
Definition viewport.c:80