1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
|
/*
* Smithsonian Astrophysical Observatory, Cambridge, MA, USA
* This code has been modified under the terms listed below and is made
* available under the same terms.
*/
/*
* Copyright 1993-2004 George A Howlett.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _BLT_GRAPH_H
#define _BLT_GRAPH_H
#include "bltInt.h"
#include "bltBind.h"
#include "bltChain.h"
#include "bltPs.h"
#define MARGIN_NONE -1
#define MARGIN_BOTTOM 0 /* x */
#define MARGIN_LEFT 1 /* y */
#define MARGIN_TOP 2 /* x2 */
#define MARGIN_RIGHT 3 /* y2 */
#define rightMargin margins[MARGIN_RIGHT]
#define leftMargin margins[MARGIN_LEFT]
#define topMargin margins[MARGIN_TOP]
#define bottomMargin margins[MARGIN_BOTTOM]
typedef struct _Graph Graph;
typedef struct _Legend Legend;
typedef struct _Crosshairs Crosshairs;
typedef struct _Element Element;
typedef struct _Pen Pen;
typedef struct _Marker Marker;
typedef enum {
CID_NONE, CID_AXIS_X, CID_AXIS_Y, CID_ELEM_BAR, CID_ELEM_LINE,
CID_MARKER_BITMAP, CID_MARKER_IMAGE, CID_MARKER_LINE, CID_MARKER_POLYGON,
CID_MARKER_TEXT, CID_MARKER_WINDOW, CID_LEGEND_ENTRY,
} ClassId;
typedef struct {
/* Inputs */
int halo; /* Maximal screen distance a candidate point
* can be from the sample window coordinate */
int mode; /* Indicates whether to find the closest data
* point or the closest point on the trace by
* interpolating the line segments. Can also
* be SEARCH_AUTO, indicating to choose how to
* search.*/
int x, y; /* Screen coordinates of test point */
int along; /* Indicates to let search run along a
* particular axis: x, y, or both. */
/* Outputs */
Element* elemPtr; /* Name of the closest element */
Point2d point; /* Graph coordinates of closest point */
int index; /* Index of closest data point */
double dist; /* Distance in screen coordinates */
} ClosestSearch;
typedef struct {
/* Generic fields common to all graph objects. */
ClassId classId; /* Class type of object. */
const char *name; /* Identifier to refer the object. */
const char *className; /* Class name of object. */
Graph* graphPtr; /* Graph containing of the object. */
const char **tags; /* Binding tags for the object. */
} GraphObj;
#include "bltGrAxis.h"
#include "bltGrLegd.h"
typedef struct {
Segment2d *segments;
int length;
int *map;
} GraphSegments;
typedef struct {
int nSegments; /* Number of occurrences of
* x-coordinate */
Axis2d axes; /* The axes associated with this
* group. (mapped to the x-value) */
float sum; /* Sum of the ordinates (y-coorinate) of
* each duplicate abscissa. Used to
* determine height of stacked bars. */
int count; /* Current number of bars seen. Used to
* position of the next bar in the
* group. */
float lastY; /* y-cooridinate position of the
* last bar seen. */
size_t index; /* Order of group in set (an unique
* abscissa may have more than one
* group). */
} BarGroup;
typedef struct {
float value; /* Duplicated abscissa */
Axis2d axes; /* Axis mapping of element */
} BarSetKey;
typedef enum BarModes {
BARS_INFRONT, BARS_STACKED, BARS_ALIGNED, BARS_OVERLAP
} BarMode;
typedef Pen *(PenCreateProc)(void);
typedef int (PenConfigureProc)(Graph* graphPtr, Pen* penPtr);
typedef void (PenDestroyProc)(Graph* graphPtr, Pen* penPtr);
typedef struct {
short int width, height; /* Dimensions of the margin */
short int axesOffset;
short int axesTitleLength; /* Width of the widest title to be
* shown. Multiple titles are displayed
* in another margin. This is the
* minimum space requirement. */
short int maxTickWidth;
short int maxTickHeight;
unsigned int nAxes; /* # of axes to be displayed */
Blt_Chain axes; /* Axes associated with this margin */
const char *varName; /* If non-NULL, name of variable to be
* updated when the margin size
* changes */
int reqSize; /* Requested size of margin */
int site; /* Indicates where margin is located:
* left, right, top, or bottom. */
} Margin;
struct _Graph {
Tcl_Interp* interp; /* Interpreter associated with graph */
Tk_Window tkwin; /* Window that embodies the graph.
* NULL means that the window has been
* destroyed but the data structures
* haven't yet been cleaned up. */
Display *display; /* Display containing widget; used to
* release resources after tkwin has
* already gone away. */
Tcl_Command cmdToken; /* Token for graph's widget command. */
Tk_OptionTable optionTable;
ClassId classId; /* Default element type */
Tk_Cursor cursor;
int inset; /* Sum of focus highlight and 3-D
* border. Indicates how far to
* offset the graph from outside edge
* of the window. */
int borderWidth; /* Width of the exterior border */
int relief; /* Relief of the exterior border. */
unsigned int flags; /* Flags; see below for definitions. */
Tk_3DBorder normalBg; /* 3-D border used to delineate the
* plot surface and outer edge of
* window. */
int highlightWidth; /* Width in pixels of highlight to
* draw around widget when it has the
* focus. <= 0 means don't draw a
* highlight. */
XColor* highlightBgColor; /* Color for drawing traversal
* highlight area when highlight is
* off. */
XColor* highlightColor; /* Color for drawing traversal
* highlight. */
const char *title; /* Graph title */
short int titleX, titleY; /* Position of title on graph. */
short int titleWidth, titleHeight; /* Dimensions of title. */
TextStyle titleTextStyle; /* Title attributes: font, color,
* etc.*/
const char *takeFocus; /* Not used in C code */
Axis *focusPtr; /* The axis that currently has focus. */
int reqWidth, reqHeight; /* Requested size of graph window */
int reqPlotWidth, reqPlotHeight; /* Requested size of plot area. Zero
* means to adjust the dimension
* according to the available space
* left in the window. */
int width, height; /* Actual size (in pixels) of graph
* window or PostScript page. */
Tcl_HashTable penTable; /* Table of pens */
struct Component {
Tcl_HashTable table; /* Hash table of ids. */
Blt_Chain displayList; /* Display list. */
Tcl_HashTable tagTable; /* Table of bind tags. */
} elements, markers, axes;
Tcl_HashTable dataTables; /* Hash table of datatable clients. */
Blt_BindTable bindTable;
int nextMarkerId; /* Tracks next marker identifier
* available */
Blt_Chain axisChain[4]; /* Chain of axes for each of the
* margins. They're separate from the
* margin structures to make it easier
* to invert the X-Y axes by simply
* switching chain pointers. */
Margin margins[4];
PageSetup *pageSetup; /* Page layout options: see bltGrPS.c */
Legend *legend; /* Legend information: see
* bltGrLegd.c */
Crosshairs *crosshairs; /* Crosshairs information: see
* bltGrHairs.c */
int halo; /* Maximum distance allowed between
* points when searching for a point */
int inverted; /* If non-zero, indicates the x and y
* axis positions should be inverted. */
int stackAxes; /* If non-zero, indicates to stack
* mulitple axes in a margin, rather
* than layering them one on top of
* another. */
GC drawGC; /* GC for drawing on the margins. This
* includes the axis lines */
int plotBW; /* Width of interior 3-D border. */
int plotRelief; /* 3-d effect: TK_RELIEF_RAISED etc. */
Tk_3DBorder plotBg; /* Color of plotting surface */
/* If non-zero, force plot to conform to aspect ratio W/H */
double aspect;
short int left, right; /* Coordinates of plot bbox */
short int top, bottom;
int xPad; /* Vertical padding for plotarea */
int vRange, vOffset; /* Vertical axis range and offset from
* the left side of the graph
* window. Used to transform coordinates
* to vertical axes. */
int yPad; /* Horizontal padding for plotarea */
int hRange, hOffset; /* Horizontal axis range and offset from
* the top of the graph window. Used to
* transform horizontal axes */
float vScale, hScale;
int doubleBuffer; /* If non-zero, draw the graph into a
* pixmap first to reduce flashing. */
int backingStore; /* If non-zero, cache elements by
* drawing them into a pixmap */
Pixmap cache; /* Pixmap used to cache elements
* displayed. If *backingStore* is
* non-zero, each element is drawn into
* this pixmap before it is copied onto
* the screen. The pixmap then acts as
* a cache (only the pixmap is
* redisplayed if the none of elements
* have changed). This is done so that
* markers can be redrawn quickly over
* elements without redrawing each
* element. */
short int cacheWidth, cacheHeight; /* Size of element backing store
* pixmap. */
/*
* barchart specific information
*/
double baseline; /* Baseline from bar chart. */
double barWidth; /* Default width of each bar in graph
* units. The default width is 1.0
* units. */
BarMode barMode; /* Mode describing how to display bars
* with the same x-coordinates. Mode can
* be "stacked", "aligned", "overlap",
* or "infront" */
BarGroup *barGroups; /* Contains information about duplicate
* x-values in bar elements (malloc-ed).
* This information can also be accessed
* by the group hash table */
int nBarGroups; /* # of entries in barGroups array. If
* zero, indicates nothing special
* needs to be * done for "stack" or
* "align" modes */
Tcl_HashTable setTable; /* Table managing sets of bars with
* the same abscissas. The bars in a
* set may be displayed is various
* ways: aligned, overlap, infront, or
* stacked. */
int maxBarSetSize;
ClosestSearch search;
};
/*
* Bit flags definitions:
*
* All kinds of state information kept here. All these things happen
* when the window is available to draw into (DisplayGraph). Need the
* window width and height before we can calculate graph layout (i.e. the
* screen coordinates of the axes, elements, titles, etc). But we want to
* do this only when we have to, not every time the graph is redrawn.
*
* Same goes for maintaining a pixmap to double buffer graph elements.
* Need to mark when the pixmap needs to updated.
*
*
* MAP_ITEM Indicates that the element/marker/axis
* configuration has changed such that
* its layout of the item (i.e. its
* position in the graph window) needs
* to be recalculated.
*
* MAP_ALL Indicates that the layout of the axes and
* all elements and markers and the graph need
* to be recalculated. Otherwise, the layout
* of only those markers and elements that
* have changed will be reset.
*
* GET_AXIS_GEOMETRY Indicates that the size of the axes needs
* to be recalculated.
*
* RESET_AXES Flag to call to Blt_ResetAxes routine.
* This routine recalculates the scale offset
* (used for mapping coordinates) of each axis.
* If an axis limit has changed, then it sets
* flags to re-layout and redraw the entire
* graph. This needs to happend before the axis
* can compute transformations between graph and
* screen coordinates.
*
* LAYOUT_NEEDED
*
* CACHE_DIRTY If set, redraw all elements into the pixmap
* used for buffering elements.
*
* REDRAW_PENDING Non-zero means a DoWhenIdle handler has
* already been queued to redraw this window.
*
* DRAW_LEGEND Non-zero means redraw the legend. If this is
* the only DRAW_* flag, the legend display
* routine is called instead of the graph
* display routine.
*
* DRAW_MARGINS Indicates that the margins bordering
* the plotting area need to be redrawn.
* The possible reasons are:
*
* 1) an axis configuration changed
* 2) an axis limit changed
* 3) titles have changed
* 4) window was resized.
*
* GRAPH_FOCUS
*/
#define HIDE (1<<0) /* 0x0001 */
#define DELETE_PENDING (1<<1) /* 0x0002 */
#define REDRAW_PENDING (1<<2) /* 0x0004 */
#define ACTIVE_PENDING (1<<3) /* 0x0008 */
#define MAP_ITEM (1<<4) /* 0x0010 */
#define DIRTY (1<<5) /* 0x0020 */
#define ACTIVE (1<<6) /* 0x0040 */
#define FOCUS (1<<7) /* 0x0080 */
#define MAP_ALL (1<<8) /* 0x0100 */
#define LAYOUT_NEEDED (1<<9) /* 0x0200 */
#define RESET_AXES (1<<10)/* 0x0400 */
#define GET_AXIS_GEOMETRY (1<<11)/* 0x0800 */
#define DRAW_LEGEND (1<<12)/* 0x1000 */
#define DRAW_MARGINS (1<<13)/* 0x2000 */
#define CACHE_DIRTY (1<<14)/* 0x4000 */
#define GRAPH_DELETED (1<<15)/* 0x4000 */
#define MAP_WORLD (MAP_ALL|RESET_AXES|GET_AXIS_GEOMETRY)
#define REDRAW_WORLD (DRAW_LEGEND)
#define RESET_WORLD (REDRAW_WORLD | MAP_WORLD)
extern int Blt_CreateCrosshairs(Graph* graphPtr);
extern int Blt_CreatePageSetup(Graph* graphPtr);
extern void Blt_ConfigureAxes(Graph* graphPtr);
extern void Blt_DestroyCrosshairs(Graph* graphPtr);
extern double Blt_InvHMap(Axis *axisPtr, double x);
extern double Blt_InvVMap(Axis *axisPtr, double x);
extern double Blt_HMap(Axis *axisPtr, double x);
extern double Blt_VMap(Axis *axisPtr, double y);
extern Point2d Blt_InvMap2D(Graph* graphPtr, double x, double y,
Axis2d *pairPtr);
extern Point2d Blt_Map2D(Graph* graphPtr, double x, double y,
Axis2d *pairPtr);
extern Graph *Blt_GetGraphFromWindowData(Tk_Window tkwin);
extern void Blt_AdjustAxisPointers(Graph* graphPtr);
extern int Blt_PolyRectClip(Region2d *extsPtr, Point2d *inputPts,
int nInputPts, Point2d *outputPts);
extern void Blt_ComputeBarStacks(Graph* graphPtr);
extern void Blt_ReconfigureGraph(Graph* graphPtr);
extern void Blt_DestroyAxes(Graph* graphPtr);
extern void Blt_DestroyElements(Graph* graphPtr);
extern void Blt_DestroyPageSetup(Graph* graphPtr);
extern void Blt_DrawAxes(Graph* graphPtr, Drawable drawable);
extern void Blt_DrawAxisLimits(Graph* graphPtr, Drawable drawable);
extern void Blt_DrawElements(Graph* graphPtr, Drawable drawable);
extern void Blt_DrawActiveElements(Graph* graphPtr, Drawable drawable);
extern void Blt_DrawGraph(Graph* graphPtr, Drawable drawable);
extern void Blt_Draw2DSegments(Display *display, Drawable drawable, GC gc,
Segment2d *segments, int nSegments);
extern int Blt_GetCoordinate(Tcl_Interp* interp, const char *string,
double *valuePtr);
extern void Blt_InitBarSetTable(Graph* graphPtr);
extern void Blt_LayoutGraph(Graph* graphPtr);
extern void Blt_EventuallyRedrawGraph(Graph* graphPtr);
extern void Blt_ResetAxes(Graph* graphPtr);
extern void Blt_ResetBarGroups(Graph* graphPtr);
extern void Blt_GraphExtents(Graph* graphPtr, Region2d *extsPtr);
extern void Blt_DisableCrosshairs(Graph* graphPtr);
extern void Blt_EnableCrosshairs(Graph* graphPtr);
extern void Blt_MapGraph(Graph* graphPtr);
extern void Blt_MapAxes(Graph* graphPtr);
extern void Blt_MapElements(Graph* graphPtr);
extern void Blt_DestroyPens(Graph* graphPtr);
extern int Blt_GetPenFromObj(Tcl_Interp* interp, Graph* graphPtr,
Tcl_Obj *objPtr, ClassId classId, Pen **penPtrPtr);
extern Pen* Blt_BarPen(Graph* graphPtr, const char* penName);
extern Pen* Blt_LinePen(Graph* graphPtr, const char* penName);
extern int Blt_CreatePen(Graph* graphPtr, Tcl_Interp* interp,
const char* penName, ClassId classId,
int objc, Tcl_Obj* const objv[]);
extern int Blt_InitLinePens(Graph* graphPtr);
extern int Blt_InitBarPens(Graph* graphPtr);
extern void Blt_FreePen(Pen* penPtr);
extern int Blt_AxisOp(Graph* graphPtr, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[]);
extern int Blt_DefAxisOp(Tcl_Interp* interp, Graph* graphPtr, int margin,
int objc, Tcl_Obj* const objv[]);
extern int Blt_ElementOp(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[], ClassId classId);
extern int Blt_CrosshairsOp(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[]);
extern int Blt_PenOp(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[]);
extern int Blt_PointInPolygon(Point2d *samplePtr, Point2d *screenPts,
int nScreenPts);
extern int Blt_RegionInPolygon(Region2d *extsPtr, Point2d *points,
int nPoints, int enclosed);
extern int Blt_PointInSegments(Point2d *samplePtr, Segment2d *segments,
int nSegments, double halo);
extern int Blt_PostScriptOp(Graph* graphPtr, Tcl_Interp* interp, int objc,
Tcl_Obj* const objv[]);
extern int Blt_GraphUpdateNeeded(Graph* graphPtr);
extern int Blt_CreateAxes(Graph* graphPtr);
extern Axis *Blt_GetFirstAxis(Blt_Chain chain);
extern void Blt_UpdateAxisBackgrounds(Graph* graphPtr);
extern Axis *Blt_NearestAxis(Graph* graphPtr, int x, int y);
typedef ClientData (MakeTagProc)(Graph* graphPtr, const char *tagName);
extern MakeTagProc Blt_MakeElementTag;
extern MakeTagProc Blt_MakeAxisTag;
extern Blt_BindTagProc Blt_GraphTags;
extern Blt_BindTagProc Blt_AxisTags;
extern void Blt_GraphSetObjectClass(GraphObj *graphObjPtr,ClassId classId);
extern void Blt_ElementsToPostScript(Graph* graphPtr, Blt_Ps ps);
extern void Blt_ActiveElementsToPostScript(Graph* graphPtr, Blt_Ps ps);
extern void Blt_LegendToPostScript(Graph* graphPtr, Blt_Ps ps);
extern void Blt_AxesToPostScript(Graph* graphPtr, Blt_Ps ps);
extern void Blt_AxisLimitsToPostScript(Graph* graphPtr, Blt_Ps ps);
extern Element *Blt_LineElement(Graph* graphPtr);
extern Element *Blt_BarElement(Graph* graphPtr);
extern void Blt_DrawGrids(Graph* graphPtr, Drawable drawable);
extern void Blt_GridsToPostScript(Graph* graphPtr, Blt_Ps ps);
extern void Blt_InitBarSetTable(Graph* graphPtr);
extern void Blt_DestroyBarSets(Graph* graphPtr);
extern const char *Blt_GraphClassName(ClassId classId);
extern void Blt_DestroyMarkers(Graph* graphPtr);
extern void Blt_DrawMarkers(Graph* graphPtr, Drawable drawable, int under);
extern ClientData Blt_MakeMarkerTag(Graph* graphPtr, const char* tagName);
extern void Blt_MapMarkers(Graph* graphPtr);
extern int Blt_MarkerOp(Graph* graphPtr, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[]);
extern void Blt_MarkersToPostScript(Graph* graphPtr, Blt_Ps ps, int under);
extern Marker* Blt_NearestMarker(Graph* graphPtr, int x, int y, int under);
#endif
|