1 #include "wx/wx.h"
2 #include <vector>
3 #include <utility>
4 
5 using namespace std;
6 
7 #ifndef _WX_MOL_GRAPH_H_
8 #define _WX_MOL_GRAPH_H_
9 
10 extern const int wxEVT_AXIS_DCLICK;
11 extern const int wxEVT_GRAPH_CLICK;
12 
13 #define EVT_AXIS_DCLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_AXIS_DCLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxCommandEventFunction, &fn ), (wxObject *) NULL ),
14 #define EVT_GRAPH_CLICK(id, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_GRAPH_CLICK, id, -1, (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( wxCommandEventFunction, &fn ), (wxObject *) NULL ),
15 
16 #define MG_AXIS_X  0x00
17 #define MG_AXIS_Y1 0x01
18 #define MG_AXIS_Y2 0x02
19 
20 #define MG_STYLE_NONE  0x00
21 #define MG_STYLE_POINT 0x01
22 #define MG_STYLE_LINE  0x02
23 #define MG_STYLE_BAR   0x04
24 
25 #define MG_STYLE_POINT_LINE 0x03
26 
27 #define MG_SHAPE_CIRCLE  0x01
28 #define MG_SHAPE_DIAMOND 0x02
29 #define MG_SHAPE_SQUARE  0x03
30 
31 typedef pair< vector< double >, int > XSet;
32 typedef vector< pair< int, double > > YSet;
33 typedef vector< pair< XSet, vector< YSet > > > DataSet;
34 typedef struct _YSettings YSettings;
35 
36 struct _YSettings {
37     bool     visible;
38     bool     exists;
39     int      axis;
40     int      style;
41     wxColour color;
42     int      shape;
43     int      size;
44 };
45 
46 /**
47  * A custom widget designed for graphing various types of data associated
48  * with molecules in wxMacMolPlt.
49  */
50 class wxMolGraph : public wxControl {
51   private:
52     DataSet data;
53     vector< vector< YSettings > > dataSettings;
54 
55     wxString xAxisText;
56     wxString y1AxisText;
57     wxString y2AxisText;
58 
59     double xMax;
60     double xMin;
61     double y1Max;
62     double y1Min;
63     double y2Max;
64     double y2Min;
65 
66     int numY1Graphs;
67     int numY2Graphs;
68     int numY1Visible;
69     int numY2Visible;
70 
71     wxRegion xAxisRegion;
72     wxRegion y1AxisRegion;
73     wxRegion y2AxisRegion;
74     wxRegion graphRegion;
75 
76     int precision;
77 
78     wxCoord clickedX;
79     wxCoord clickedY;
80 
81     double xConversion;
82     double y1Conversion;
83     double y2Conversion;
84 
85     wxCoord xScaleMin;
86     wxCoord xScaleMax;
87     wxCoord yScaleMin;
88     wxCoord yScaleMax;
89 
90     double y1Offset;
91     double y2Offset;
92 
DECLARE_DYNAMIC_CLASS(wxMolGraph)93     DECLARE_DYNAMIC_CLASS(wxMolGraph) /* NOTE:  Everything after this will be
94                                        * public!
95                                        */
96 
97   public:
98     /**
99      * Default constructor.  This is here to keep wxWidgets RTTI happy.  You
100      * shouldn't actually use it.
101      */
102     wxMolGraph() {}
103 
104 
105     /**
106      * Constructor for general use.
107      *
108      * @param parent The parent window of the new wxMolGraph.
109      * @param id The window ID of the new wxMolGraph.
110      * @param pos The initial position of the new wxMolGraph.
111      * @param size The initial size of the new wxMolGraph.
112      * @param style The initial style of the new wxMolGraph.
113      */
114     wxMolGraph(wxWindow       *parent,
115                wxWindowID      id,
116                const wxPoint  &pos   = wxDefaultPosition,
117                const wxSize   &size  = wxDefaultSize,
118                long            style = wxSUNKEN_BORDER);
119     /* TODO:  Write more useful doxygen comments for this function. */
120 
121 
122     /**
123      * Destructor.  TODO:  Write something interesting for doxygen.
124      */
~wxMolGraph()125     ~wxMolGraph() {}
126 
127 
128     /**
129      * Adds a new set of x-values to the wxMolGraph.  If necessary, the scale
130      * of the x-axis will be adjusted to contain the new values, but no data
131      * points will be drawn for the new x-set until a y-set is associated with
132      * it.
133      *
134      * @param data A vector of the x-values in the set.  The elements  of the
135      *             vector are expected to be in increasing order, and no two
136      *             elements may have the same value.  If these requirements are
137      *             not met, the behavior of the widget is undefined.
138      * @param selectable Sets the selectable flag for the set.  If it is true,
139      *                   points may be selected with a mouse (or arrow keys?).
140      * @return On success this function returns the index of the x-set within
141      *         the wxMolGraph.  This will be one greater than the index of the
142      *         last x-set added, with the first x-set added having an index of
143      *         zero.  On failure this function returns a value less than zero.
144      */
145     int addXSet(vector<double> data, bool selectable);
146 
147 
148     /**
149      * Adds a new set of y-values and associates it with an x-set.  This causes
150      * the wxMolGraph to be redrawn.  The scales of all axis are unaffected.
151      *
152      * @param data A vector of pairs, one for each y-value.  The first element
153      *             of each pair is the index of the x-value (within the
154      *             associated x-set) with which the y-value is associated.
155      *             The indices are expected to occur in increasing order, and
156      *             no two y-values in a set may be associated with the same
157      *             x-index; however, there need not be a y-value associated
158      *             with every possible index in the x-set.  If an x-index is
159      *             outside the range of the x-set, the widget's behavior is
160      *             undefined.  The second element of each pair is the y-value
161      *             itself.
162      * @param xSet The index of the x-set with which to associate the new y-set.
163      * @param axis Specifies which axis to graph the y-set on.  Must be one of
164      *             MG_AXIS_Y1 or MG_AXIS_Y2.
165      * @param style Specifies the style which should be used to draw the data
166      *              points.  This is a bitmask of style flags.  Valid style
167      *              flags are:
168      *                  MG_STYLE_NONE  - Draw nothing.
169      *                  MG_STYLE_POINT - Draw a colored dot at each data point.
170      *                  MG_STYLE_LINE  - Draw a line between adjacent
171      *                                   data points.
172      *                  MG_STYLE_BAR   - Draw a vertical bar between each data
173      *                                   point and the x-axis.
174      *                  MG_STYLE_POINT_LINE - The same as
175      *                                   (MG_STYLE_POINT | MG_STYLE_LINE)
176      *
177      * @param color If the style includes MG_STYLE_POINT, the point will be
178      *              filled with this color.
179      * @param shape If the style includes MG_STYLE_POINT, the point will be
180      *              drawn with this shape.  Valid shape flags are:
181      *                  MG_SHAPE_CIRCLE
182      *                  MG_SHAPE_DIAMOND
183      *                  MG_SHAPE_SQUARE
184      * @param size  If the style includes MG_STYLE_POINT, the point will be
185      *              drawn with approximately this diameter in pixels.
186      * @return On success this function returns the index of the y-set within
187      *         the associated x-set.  This will be one greater than the index
188      *         of the last y-set associated with the same x-set, with the first
189      *         y-set associated with a given x-set having and index of zero.
190      *         On failure this function returns a value less than zero.
191      */
192     int addYSet(YSet data,
193                 int xSet,
194                 int axis,
195                 int style,
196                 wxColour color,
197                 int shape = MG_SHAPE_CIRCLE,
198                 int size  = 8);
199 
200 
201     /**
202      * Removes an x-set, and all y-sets associated with it, from the
203      * wxMolGraph.  This causes the x-axis to be auto-scaled and the wxMolGraph
204      * to be redrawn.  Note that this has no effect on the index assigned to
205      * the next x-set added.
206      *
207      * @param xSet The index of the x-set to remove.
208      */
209     void delXSet(int xSet);
210 
211 
212     /**
213      * Disassociates a y-set from its x-set and removes it from the wxMolGraph.
214      * This causes the wxMolGraph to be redrawn.  Note that this has no effect
215      * on the index assigned to the next y-set associated with the same x-set.
216      *
217      * @param xSet The index of the x-set from which to remove the y-set.
218      * @param ySet The index of the y-set to remove.
219      */
220     void delYSet(int xSet, int ySet);
221 
222 
223     /**
224      * Returns the currently selected index for the given x-set.
225      *
226      * @param xSet The x-set for which to get the selected index.
227      * @return The currently selected index for the x-set, or 0 if the x-set's
228      *         selectable flag is set to false.
229      */
230     int getSelection(int xSet);
231 
232 
233     /**
234      * Sets the currently selected index for the given x-set.  This causes
235      * the wxMolGraph to be redrawn.  Note that if the x-set's selectable flag
236      * is set to false, this function has no effect.
237      *
238      * @param xSet The x-set for which to set the selected index.
239      * @param index The new selected index.  If the index is not in the x-set,
240      *              the selection will remain unchanged.
241      */
242     void setSelection(int xSet, int index);
243 
244 
245     /**
246      * Sets the lower bound for the given y-axis, adjusts the scale, and then
247      * redraws the wxMolGraph.  If the lower bound is greater than or equal to
248      * the current upper bound, no scale will be drawn for the axis, and none
249      * of the data sets on the axis will be drawn.
250      *
251      * @param axis Specifies which axis to modify the lower bound of.  Must be
252      *             one of MG_AXIS_Y1 or MG_AXIS_Y2.
253      * @param val The new lower bound.
254      */
255     void setYAxisMin(int axis, double val);
256 
257 
258     /**
259      * Sets the upper bound for the given y-axis, adjusts the scale, and then
260      * redraws the wxMolGraph.  If the upper bound is less than or equal to the
261      * current lower bound, no scale will be drawn for the axis, and none of
262      * the data sets on the axis will be drawn.
263      *
264      * @param axis Specifies which axis to modify the upper bound of.  Must be
265      *             one of MG_AXIS_Y1 or MG_AXIS_Y2.
266      * @param val The new upper bound.
267      */
268     void setYAxisMax(int axis, double val);
269 
270 
271     double getYAxisMin(int axis);
272     double getYAxisMax(int axis);
273 
274 
275     /**
276      * Adjusts the upper and lower bounds of the given y-axis and adjusts the
277      * scale to show all data graphed on the axis.  After adjusting, the
278      * wxMolGraph is redrawn.
279      *
280      * @param axis Specifies which y-axis to auto-scale.  Must be one of
281      *             MG_AXIS_Y1 or MG_AXIS_Y2.
282      */
283     void autoScaleY(int axis);
284 
285     void setXAxisMin(double val);
286     void setXAxisMax(double val);
287     double getXAxisMin();
288     double getXAxisMax();
289     void autoScaleX(void);
290 
291 
292     /**
293      * Sets the label for the given axis.
294      *
295      * @param axis The axis for which to set the label.  Must be one of
296      *             MG_AXIS_X, MG_AXIS_Y1, or MG_AXIS_Y2.
297      * @param label The new label for the axis.
298      */
299     void setAxisLabel(int axis, const wxString &label);
300 
301 
302     /**
303      * Changes the scale offset for the given y-axis.  An offset of X will
304      * cause the zero point for the offset scale to be placed at X on the
305      * actual scale.  This causes the wxMolGraph to be redrawn.
306      *
307      * @param axis Specifies which y-axis for which to modify the offset.  Must
308      *             be one of MG_AXIS_Y1 or MG_AXIS_Y2.
309      * @param offset The new offset.
310      */
311     void setOffsetY(int axis, double offset);
312 
313 
314     /**
315      * Sets the visibility of the given y-set.  Y-sets that are not visible do
316      * not affect axis autoscaling.  All sets are visible by default.
317      *
318      * @param xSet The x-set which the y-set belongs to.
319      * @param ySet The y-set.
320      * @param visible If true, the y-set will be visible.  If false, the y-set
321      *                will not be drawn.
322      */
323     void setVisible(int xSet, int ySet, bool visible);
324 
325 
326     /**
327      * Restores the wxMolGraph to its initial state.  Axis information, such as
328      * min/max and offset, is reset, all sets are removed, and the indices of
329      * newly added sets will restart at zero.
330      */
331     void reset();
332 
333 
334     /**
335      * Sets the number of places after the decimal point that should be
336      * displayed.  The default value is 4.
337      *
338      * @param p The new precision value.
339      */
340     void setPrecision(int p);
341 
342 
343     /**
344      * Overloaded wxControl member function that handles sizing of the control.
345      *
346      * @return The minimum size the control can be.
347      */
348     wxSize DoGetBestSize() const;
349 
350 
351     void draw(wxDC &dc);
352 
353 
354     /* EVENT HANDLERS */
355 
356     void onSize(wxSizeEvent &event);
357     void onPaint(wxPaintEvent &event);
358 
359     void onLeftClick(wxMouseEvent &event);
360     void onLeftDblClick(wxMouseEvent &event);
361     void onMotion(wxMouseEvent &event);
362     void onLeaveWindow(wxMouseEvent &event);
363 
364 
365     DECLARE_EVENT_TABLE();
366 };
367 
368 #endif /* _WX_MOL_GRAPH_H_ */
369 
370