File: Readme

package info (click to toggle)
xgobi 19980302-1
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 3,344 kB
  • ctags: 4,179
  • sloc: ansic: 48,103; makefile: 843
file content (198 lines) | stat: -rw-r--r-- 7,561 bytes parent folder | download | duplicates (2)
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
-------- Extending XGobi --------

There are two ways in which you can add your own functionality to
XGobi.  The first is to modify the code directly.  This has been
successfully done by one person, but I suspect that it is the
more difficult of the two options.  The second is to write your
own main() and call XGobi as a function, and the files in this
directory provide a simple example of how to do this.

Before going into any detail, let me say that I hope that anyone
choosing this option will communicate with us while designing and
writing the code.  First because we're interested in knowing what
people want to do with XGobi, and second because we might be able
to help you do it better or more easily.  And third, come to
think of it, because you can let us know that we should be
careful not to modify the XGobi code in such a way that your work
has to be done over. 
  Deborah, dfs@research.att.com; Di, dicook@iastate.edu

-------- Sample program --------

The files in this directory are as follows:

prog.c contains main() and a few other functions used in prog.

widgets.c contains the code that creates the simple prog control
  panel and attaches functionality to its two buttons.

prog.h contains declarations of a small number of global
  variables.

Prog contains resources for the color and font of the prog
  control panel.

runprog is a shell script that tells prog where to find
  the resource file; that is, if you run prog without the
  resource file, you'll just get a black and white control panel;
  if you move Prog to wherever you keep your resource files or
  use runprog, you'll see a more colorful panel with a big italic
  font.

The sample program prog is called with an argument, and two
sample datafiles are in the data subdirectory.  'runprog
data/river' and 'runprog data/tes' can be run.

Essentially, prog creates its own control panel, then initiates
an XGobi process by passing its single argument through as a
string so that XGobi knows where to find the data.  Prog then has
its own version of a function called RunWorkProcs() instead of
using XGobi's version.

-------- The Event Loop --------

An X program always has an event loop running, looking for
input:  usually user-generated mouse motions and so forth.  The
XGobi event loop is called XGobiMainLoop() and it's in
xgobitop.h.

A work proc is a routine that runs once whenever the event loop
finds no events, a sort of run-while-idle routine.  In XGobi,
continuous processes such as rotation are handled using work
procs:  for example, if no user input is found, spin_once().
Usually, an X programmer doesn't write her own RunWorkProcs()
routine, but we found it necessary to do so for XGobi.

In prog, I added one additional background routine to the set
used in XGobi -- it is called loop_once() and it changes the
color, plotting character and location of each point every time
it runs.

-------- How it works --------

It's easy to change color, plotting character and even point
location because prog owns every one of XGobi's data structures.
In loop_once(), prog uses xg->nrows and xg->ncols_used to
define its for loops, and it writes directly into the following
data arrays:

   xg->color_now[]
   xg->glyph_now[].type
   xg->glyph_now[].size
   xg->raw_data[][]

The changes to color and glyph will show up on the screen
with the next plot_once() command; the changes to the raw data
need to be sent through the data pipeline:  the raw data
values are mapped to big integers (xg->world_data[][]) then projected
down into the plane (xg->planar[].x and xg->planar[].y) and
finally mapped onto the screen (xg->screen[].x and .y).  (I've
skipped a couple of steps, but that's the idea.)

Here is a list of data structures you might want to write into:

 xg->raw_data[][]
   float, xg->nrows x xg->ncols

   Actually, there's one tricky point about the number of
   columns.  The user supplies a matrix of size n by p; XGobi
   builds a data matrix of size n by p+1 so that it can allow
   the user to create a variable during brushing.  So you
   probably want to look over xg->ncols_used (p before the
   extra variable has been created, p+1 afterwards) rather than
   xg->ncols (always p+1).

   In fact, there's a similar tricky point about xg->nrows.
   If the user has deleted points during brushing, then the
   number of points actually displayed in the plot is
   xg->nrows_in_plot.  In the XGobi code, we often loop over
   xg->nrows_in_plot to save time.

   I don't recommend trying to muck about with xg->nrows or
   xg->ncols once you've initiated an XGobi.  So many things
   would need to be reallocated that we haven't dared to
   try this ourselves.  If you aren't sure in advance how
   much space you're going to need, then allocate space for
   lots of columns and lots of rows, and then use rows_in_plot[]
   to hold the data you're really working with.

 xg->color_now[]
   unsigned long, of length xg->nrows
 xg->glyph_now[].type
   int, of length xg->nrows.  The types are defined in xgobitypes.h

   #define PLUS_GLYPH 1
   #define X_GLYPH 2
   #define OPEN_RECTANGLE_GLYPH 3
   #define FILLED_RECTANGLE_GLYPH 4
   #define OPEN_CIRCLE_GLYPH 5
   #define FILLED_CIRCLE_GLYPH 6
   #define POINT_GLYPH 7

 xg->glyph_now[].size
   int, of length xg->nrows.  The values range from 1 (TINY) to
   5 (JUMBO).

 xg->erased[]
   unsigned short, of length xg->nrows, 0 if not erased,
   1 if erased

 xg->nrows_in_plot
   int, number of points to be plotted
 xg->rows_in_plot[]
   int *, of length xg->nrows_in_plot

 xg->delete_erased_points
   Boolean; if True, then the currently erased points are
   deleted:  that is, they aren't considered when scaling
   or doing projection pursuit.

 xg->nlinks
   int, number of connecting line segments
 xg->connecting_lines[]
   connect_lines:  struct {int a, b;}, of length xg->nlinks,
   specifies the row numbers of the pair of points to be
   connected.  If you change of xg->nlinks, you can use
   XtRealloc() to reallocate this vector.
 xg->line_color_now[]
   unsigned long, the color of each line, in the order
   in which they appear in xg->connecting_lines[]

 xg->nsticky_ids
   int, number of sticky (persistent) labels
 xg->sticky_ids[]
   Cardinal (unsigned int), of length xg->nsticky_ids, 
   the row numbers of the points to be labelled with sticky
   labels.  If you change of xg->nsticky_ids, you can
   use XtRealloc() to reallocate this vector.

 xg->rowlab[][]
   char **, of length xg->nrows, the label of each row

 xg->collab[][]
   char **, of length xg->ncols, the label of each column

In some cases, you might want to call routines rather than write
into data structures.  Let's suppose that you want to use
software to choose the variables that will be used in a grand
tour.  You can call tour_varselect(j, &xgobi) where j is the
number of the variable that you want to add or delete from the
current set.  This routine will set the value of xg->numvars_t,
the number of variables in the current tour, add or subtract an
item from xg->tour_vars[], and fix up the appearance of the
variable selection panel.

-------- Compiling --------

The XGobi main(), found in xgobi.c, has simply been replaced
with the main() for prog.  So when prog is compiled, it needs
the XGobi include files and libxgobi.a, an archive containing
every .o file from the XGobi source with the exception of
xgobi.o.  We build that library by including these lines in our
XGobi Makefile:

lib: ${OBJ}
        rm -f libxgobi.a
        ar cr libxgobi.a ${OBJ}
        ranlib libxgobi.a