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