OpenWalnut  1.5.0dev
WMMultiHistogramView.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WMMULTIHISTOGRAMVIEW_H
26 #define WMMULTIHISTOGRAMVIEW_H
27 
28 #include <memory>
29 #include <string>
30 #include <vector>
31 
32 #include <boost/thread.hpp>
33 #include <osg/Geode>
34 
35 #include "core/common/WCounter.h"
36 #include "core/common/WHistogramBasic.h"
37 #include "core/common/math/linearAlgebra/WMatrixFixed.h"
38 #include "core/dataHandler/WDataSetSingle.h"
39 #include "core/graphicsEngine/WGEGroupNode.h"
40 #include "core/kernel/WModule.h"
41 #include "core/kernel/WModuleInputData.h"
42 #include "core/kernel/WModuleOutputData.h"
43 #include "core/ui/WUIViewWidget.h"
44 
45 // TODO(reichenbach): choose color of frame and marker depending on the user's chosen window background color
46 /**
47  * \class WMMultiHistogramView
48  *
49  * A module that draws a histogram of one or mode scalar datasets in a custom widget.
50  *
51  * \ingroup modules
52  */
54 {
55 public:
56  /**
57  * Constuctor.
58  */
60 
61  /**
62  * Destructor.
63  */
64  virtual ~WMMultiHistogramView();
65 
66  /**
67  * Gives back the name of this module.
68  * \return the module's name.
69  */
70  virtual const std::string getName() const;
71 
72  /**
73  * Gives back a description of this module.
74  * \return description to module.
75  */
76  virtual const std::string getDescription() const;
77 
78  /**
79  * Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
80  * should never be initialized or modified in some other way. A simple new instance is required.
81  *
82  * \return the prototype used to create every module in OpenWalnut.
83  */
84  virtual std::shared_ptr< WModule > factory() const;
85 
86  /**
87  * Get the icon for this module in XPM format.
88  *
89  * \return The icon.
90  */
91  virtual const char** getXPMIcon() const;
92 
93 protected:
94  /**
95  * Entry point after loading the module. Runs in separate thread.
96  */
97  virtual void moduleMain();
98 
99  /**
100  * Initialize the connectors this module is using.
101  */
102  virtual void connectors();
103 
104  /**
105  * Initialize the properties for this module.
106  */
107  virtual void properties();
108 
109  /**
110  * Initialize requirements for this module.
111  */
112  virtual void requirements();
113 
114 private:
115  /**
116  * Called on every mouse move event from the custom widget.
117  *
118  * \note this runs in OSG thread.
119  * \param pos New mouse position.
120  */
121  void handleMouseMove( WVector2f pos );
122 
123  /**
124  * Called on every resize event from the custom widget.
125  *
126  * \note this runs in OSG thread.
127  * \param x X pos
128  * \param y Y pos
129  * \param width Widht
130  * \param height Height
131  */
132  void handleResize( int x, int y, int width, int height );
133 
134  /**
135  * Whenever a new info node is made this mutex should be used.
136  */
137  boost::mutex m_createInfoMutex;
138 
139  /**
140  * Whenever a redraw is made this mutex should be used.
141  */
142  boost::mutex m_redrawMutex;
143 
144  /**
145  * Redraws the histogram and add it to the main geode.
146  */
147  void redraw();
148 
149  /**
150  * This updates the maximum value of the histograms.
151  *
152  * \param cumulative If true, histogram values of the datasets will be added for each bin.
153  */
154  void updateHistogramMax( bool cumulative );
155 
156  /**
157  * Finds a good size for the frame, depending on the chosen spacing for axis labels.
158  */
159  void calculateFrameSize();
160 
161  /**
162  * Finds a good position of the frame relative to the lower left corner of the window.
163  * Depends on the current frame size and the size of the text to be written left to/under the
164  * frame.
165  */
166  void calculateFramePosition();
167 
168  /**
169  * This simply calculates a histogram per dataset, where the bin sizes and positions are the same for
170  * each histogram.
171  */
172  void calculateHistograms();
173 
174  /**
175  * Creates the geometry for histogram bars. The type parameter defines how the bars are drawn:
176  *
177  * 1 - transparent bars on top of each other
178  * 2 - bars of a bin are drawn next to each other
179  * 3 - stacked bars
180  *
181  * \param type The type of the bars.
182  */
183  void createGeometryBars( int type );
184 
185  /**
186  * Creates the geometry for stairs (i.e. bars that are not filled).
187  * The type parameter can be 1 (normal) or 2 (stacked).
188  *
189  * \param type The type of the stairs.
190  */
191  void createGeometryStairs( int type );
192 
193  /**
194  * Creates the geometry for curves.
195  * The type parameter can be 1 (normal) or 2 (stacked).
196  *
197  * \param type The type of the curves.
198  */
199  void createGeometryCurves( int type );
200 
201  /**
202  * Creates the geometry for the frame and the ticks/labels.
203  */
204  void createFrame();
205 
206  /**
207  * Writes the values of the currently selected histogram bin to the top right
208  * corner of the window. The selected bin is the one pointed to by the mouse cursor.
209  *
210  * Also adds a quad denoting the currently selected bin that is drawn behind the geometry.
211  *
212  * \param mousePos Current mouse position
213  */
214  void createInfo( WVector2f mousePos );
215 
216  /**
217  * This finds a suitable spacing of ticks to use for an axis with a certain length and
218  * value interval.
219  *
220  * \param intervalLength The length of the value interval to represent.
221  * \param availableSpace The space available (in pixels on screen) for the interval.
222  * \param textSize The estimated size of the text for every tick.
223  *
224  * \return A good distance between ticks to use for labeling an axis.
225  */
226  double findOptimalSpacing( double intervalLength, double availableSpace, double textSize );
227 
228  /**
229  * This transforms histogram space coordinates to window coordinates. Histogram coordinates
230  * range from the minimum to the maximum values of all histograms in x-direction and from
231  * 0 to the maximum bin value over all histograms (or the maximum bin value where the bins of all
232  * datasets are added; this is for cumulative histogram types).
233  *
234  * \note The frame size and position must be already calculated for this function to give meaningful results.
235  *
236  * \param v The input in histogram coords.
237  * \return The given position in window coords.
238  */
240 
241  /**
242  * This is the inverse of histogramSpaceToWindowSpace.
243  * \see histogramSpaceToWindowSpace
244  *
245  * \note The frame size and position must be already calculated for this function to give meaningful results.
246  *
247  * \param v The input in window coords.
248  * \return The given position in histogram coords.
249  */
251 
252  /**
253  * This simply prints a NYI message to the errorLog.
254  */
255  void createNothing();
256 
257  /**
258  * A vector of histograms, one histogram per input. Histograms may be empty if an input
259  * does not have a valid dataset.
260  */
261  std::vector< std::shared_ptr< WHistogramBasic > > m_histograms;
262 
263  //! A condition for property updates.
264  std::shared_ptr< WCondition > m_propCondition;
265 
266  //! The width of the window.
268 
269  //! The height of the window.
271 
272  //! The position of the mouse cursor in window coordinates.
274 
275  //! Draws histogram bin info to the top right corner of the window.
276  osg::ref_ptr< osg::Geode > m_infoNode;
277 
278  //! Draws a marker showing the currently selected histogram bin.
279  osg::ref_ptr< osg::Geode > m_markerNode;
280 
281  //! Holds the reference to the custom widget used for displaying the histogram
283 
284  //! Draws the frame and ticks/labels.
285  osg::ref_ptr< osg::Geode > m_frameNode;
286 
287  //! The lower left corner of the histogram in histogram coordinates.
289 
290  //! The upper right corner of the histogram in histogram coordinates.
292 
293  //! The lower left vertex of the frame box in histogram coordinates.
295 
296  //! The upper right vertex of the frame box in histogram coordinates.
298 
299  //! The spacing between labels at the histogram axis in histogram coordinates.
301 
302  //! The space to the left and under the frame in window coordinates.
304 
305  //! The distance between the histogram frame and the top resp. right side of the window in relative window coordinates.
306  double const m_frameSize;
307 
308  //! The number of this WMHistogram instance. Used to generate a unique window title for every instance of this module.
310 
311  //! The instance counter used to get the instance ID.
313 
314  //! The scene node of the custom window. All geometry nodes are added as children of this node.
315  osg::ref_ptr< WGEGroupNode > m_mainNode;
316 
317  // the next 3 vectors all have the same size, which is the maximum number of inputs allowed for this module
318  // see NUM_INPUTS in the .cpp
319  //! A vector of input connectors.
320  std::vector< std::shared_ptr< WModuleInputData< WDataSetSingle > > > m_input;
321 
322  //! A vector of current datasets.
323  std::vector< std::shared_ptr< WDataSetSingle > > m_data;
324 
325  //! A vector of color properties for the datasets.
326  std::vector< WPropColor > m_colors;
327 
328  //! A property that is used to set the number of bins to use.
329  WPropInt m_histoBins;
330 
331  // the next two implement a kind of strategy pattern; the index of the selected element
332  // is used as an index to the geometry functions vector
333  //! Allows to select which one of the geometry generation functions should be used.
334  WPropSelection m_styleSelection;
335 
336  //! A vector containing functions to use for histogram geometry generation.
337  std::vector< boost::function< void( void ) > > m_geometryFunctions;
338 };
339 
340 #endif // WMMULTIHISTOGRAMVIEW_H
341 
This is a simple but thread-safe counter.
Definition: WCounter.h:37
A module that draws a histogram of one or mode scalar datasets in a custom widget.
void createFrame()
Creates the geometry for the frame and the ticks/labels.
virtual void requirements()
Initialize requirements for this module.
int m_instanceID
The number of this WMHistogram instance. Used to generate a unique window title for every instance of...
WVector2d m_frameLowerLeft
The lower left vertex of the frame box in histogram coordinates.
osg::ref_ptr< osg::Geode > m_infoNode
Draws histogram bin info to the top right corner of the window.
void redraw()
Redraws the histogram and add it to the main geode.
void calculateFramePosition()
Finds a good position of the frame relative to the lower left corner of the window.
void createGeometryBars(int type)
Creates the geometry for histogram bars.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
WVector2d windowSpaceToHistogramSpace(WVector2d const &v)
This is the inverse of histogramSpaceToWindowSpace.
std::vector< boost::function< void(void) > > m_geometryFunctions
A vector containing functions to use for histogram geometry generation.
void calculateFrameSize()
Finds a good size for the frame, depending on the chosen spacing for axis labels.
virtual void moduleMain()
Entry point after loading the module.
virtual void properties()
Initialize the properties for this module.
std::vector< WPropColor > m_colors
A vector of color properties for the datasets.
std::shared_ptr< WCondition > m_propCondition
A condition for property updates.
boost::mutex m_redrawMutex
Whenever a redraw is made this mutex should be used.
void handleMouseMove(WVector2f pos)
Called on every mouse move event from the custom widget.
osg::ref_ptr< osg::Geode > m_frameNode
Draws the frame and ticks/labels.
void calculateHistograms()
This simply calculates a histogram per dataset, where the bin sizes and positions are the same for ea...
void createGeometryStairs(int type)
Creates the geometry for stairs (i.e.
void handleResize(int x, int y, int width, int height)
Called on every resize event from the custom widget.
virtual const std::string getDescription() const
Gives back a description of this module.
void createNothing()
This simply prints a NYI message to the errorLog.
WVector2d m_frameSpacing
The spacing between labels at the histogram axis in histogram coordinates.
virtual const std::string getName() const
Gives back the name of this module.
std::vector< std::shared_ptr< WDataSetSingle > > m_data
A vector of current datasets.
int m_windowHeight
The height of the window.
osg::ref_ptr< WGEGroupNode > m_mainNode
The scene node of the custom window. All geometry nodes are added as children of this node.
WPropInt m_histoBins
A property that is used to set the number of bins to use.
WUIViewWidget::SPtr m_widget
Holds the reference to the custom widget used for displaying the histogram.
double findOptimalSpacing(double intervalLength, double availableSpace, double textSize)
This finds a suitable spacing of ticks to use for an axis with a certain length and value interval.
WVector2d m_frameUpperRight
The upper right vertex of the frame box in histogram coordinates.
void createInfo(WVector2f mousePos)
Writes the values of the currently selected histogram bin to the top right corner of the window.
int m_windowWidth
The width of the window.
WVector2d m_histogramUpperRight
The upper right corner of the histogram in histogram coordinates.
WVector2d histogramSpaceToWindowSpace(WVector2d const &v)
This transforms histogram space coordinates to window coordinates.
static WCounter m_instanceCounter
The instance counter used to get the instance ID.
std::vector< std::shared_ptr< WModuleInputData< WDataSetSingle > > > m_input
A vector of input connectors.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
std::vector< std::shared_ptr< WHistogramBasic > > m_histograms
A vector of histograms, one histogram per input.
WVector2d m_histogramLowerLeft
The lower left corner of the histogram in histogram coordinates.
virtual ~WMMultiHistogramView()
Destructor.
boost::mutex m_createInfoMutex
Whenever a new info node is made this mutex should be used.
WVector2d m_framePosition
The space to the left and under the frame in window coordinates.
double const m_frameSize
The distance between the histogram frame and the top resp. right side of the window in relative windo...
void createGeometryCurves(int type)
Creates the geometry for curves.
virtual void connectors()
Initialize the connectors this module is using.
WPropSelection m_styleSelection
Allows to select which one of the geometry generation functions should be used.
void updateHistogramMax(bool cumulative)
This updates the maximum value of the histograms.
WVector2d m_mousePos
The position of the mouse cursor in window coordinates.
osg::ref_ptr< osg::Geode > m_markerNode
Draws a marker showing the currently selected histogram bin.
A fixed size matrix class.
Definition: WMatrixFixed.h:150
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
std::shared_ptr< WUIViewWidget > SPtr
Abbreviation for a shared pointer on a instance of this class.
Definition: WUIViewWidget.h:72