Developer Documentation
QwtFunctionPlot.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision: 13770 $ *
45 * $LastChangedBy: moebius $ *
46 * $Date: 2012-02-13 16:19:41 +0100 (Mo, 13. Feb 2012) $ *
47 * *
48 \*===========================================================================*/
49 
50 //=============================================================================
51 //
52 // CLASS QtFunctionPlot - IMPLEMENTATION
53 //
54 //=============================================================================
55 
56 //== INCLUDES =================================================================
57 
58 #ifdef WITH_QWT
59 
60 #include "QwtFunctionPlot.hh"
61 
62 #include <iostream>
63 #include <algorithm>
64 
65 #include <QPen>
66 
67 #include <QLineEdit>
68 #include <QLabel>
69 #include <QPainter>
70 #include <qwt_curve_fitter.h>
71 #include <qwt_plot_panner.h>
72 #include <qwt_symbol.h>
73 #include <qwt_plot_histogram.h>
74 
75 #include <ACG/Utils/ColorCoder.hh>
76 
77 
78 #include <cfloat>
79 #include <cmath>
80 
81 //== NAMESPACES ===============================================================
82 
83 //== IMPLEMENTATION ==========================================================
84 
85 
87 QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
88  QDialog( _parent ),
89  Ui::QwtFunctionPlotBase(),
90  plot_zoomer_(0),
91  clampMinMarker_(0),
92  minSymbol_(0),
93  clampMaxMarker_(0),
94  maxSymbol_(0),
95  min_(FLT_MAX),
96  max_(FLT_MIN)
97 {
98  setupUi( this );
99 
100  qwtPlot->setAxisTitle(QwtPlot::yLeft, "count" );
101 
102  plot_zoomer_ = new QwtPlotZoomer( qwtPlot->canvas());
103  plot_zoomer_->initKeyPattern();
104 
105  QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
106  panner->setMouseButton( Qt::MidButton );
107 
108  // delete widget on close
109  setAttribute(Qt::WA_DeleteOnClose, true);
110 
111  histogram_ = new Histogram();
112 }
113 
114 //------------------------------------------------------------------------------
115 
116 void QwtFunctionPlot::setFunction(const std::vector<double>& _values)
117 {
118  values_ = _values;
119 }
120 
121 //------------------------------------------------------------------------------
122 
123 void QwtFunctionPlot::replot()
124 {
125  //create intervals
126  const int intervalCount = 100;
127 
128  QVector<QwtIntervalSample> intervals(intervalCount);
129  std::vector< QColor > colors;
130 
131  double realMin = FLT_MAX;
132  double realMax = -FLT_MAX;
133 
134  for ( unsigned int i=0; i < values_.size(); i++) {
135  realMin = std::min(realMin,values_[i]);
136  realMax = std::max(realMax,values_[i]);
137  }
138 
139  double pos = realMin;
140  double width = ( realMax - realMin ) / intervalCount;
141 
142  QColor lastColor = Qt::black;
143 
144  ACG::ColorCoder cCoder(std::max(min_,realMin),std::min(max_,realMax));
145 
146  for ( int i = 0; i < (int)intervals.size(); i++ )
147  {
148 
149  intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
150  pos += width;
151 
152  //compute a color for the given interval
153  const double intervalCenter = pos + (width/2.0);
154 
155  colors.push_back( cCoder.color_qcolor(intervalCenter) );
156  lastColor = colors.back();
157  }
158 
159  // sort values into intervals
160  // Could be more efficient when we calculate the correct interval based on the above loop directly
161  for ( uint i=0; i < values_.size(); i++)
162  for ( int j = 0; j < (int)intervals.size(); j++ )
163  if ( intervals[j].interval.contains( values_[i] ) ) {
164  intervals[j].value++;
165  break;
166  }
167 
168  //get max Count for scaling the y-axis
169  double maxCount = 0;
170 
171  for ( int i = 0; i < (int)intervals.size(); i++ )
172  maxCount = std::max(maxCount, intervals[i].value);
173 
174 
175  QwtIntervalSeriesData* data = new QwtIntervalSeriesData(intervals);
176  histogram_->setData(data);
177  histogram_->setColors(colors);
178  histogram_->attach(qwtPlot);
179 
180  qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
181  qwtPlot->setAxisScale(QwtPlot::xBottom, realMin, realMax);
182 
183  //define this scaling as the zoomBase
184  plot_zoomer_->setZoomBase();
185 
186  //Mark the clamp values in the histogram.
187  if ( min_ > realMin ) {
188  if ( ! clampMinMarker_ ) {
189  clampMinMarker_ = new QwtPlotMarker();
190  minSymbol_ = new QwtSymbol(QwtSymbol::VLine);
191  minSymbol_->setColor(cCoder.color_qcolor(std::max(min_,realMin)));
192  minSymbol_->setSize(200,1000);
193  QPen pen = minSymbol_->pen();
194  pen.setWidth(3);
195  minSymbol_->setPen(pen);
196  clampMinMarker_->setSymbol(minSymbol_);
197  clampMinMarker_->attach(qwtPlot);
198  clampMinMarker_->show();
199  }
200 
201  // Draw at right boundary if greater than the maximal value we get from the function
202  clampMinMarker_->setXValue(std::max(min_,realMin));
203 
204  } else {
205  if ( clampMinMarker_ ) {
206  clampMinMarker_->detach();
207  delete clampMinMarker_;
208  clampMinMarker_ = 0;
209  }
210  }
211 
212  //Mark the clamp values in the histogram.
213  if ( max_ < realMax ) {
214  if ( ! clampMaxMarker_ ) {
215  clampMaxMarker_ = new QwtPlotMarker();
216  maxSymbol_ = new QwtSymbol(QwtSymbol::VLine);
217  maxSymbol_->setColor(cCoder.color_qcolor(std::min(max_,realMax)));
218  maxSymbol_->setSize(200,1000);
219  QPen pen = maxSymbol_->pen();
220  pen.setWidth(3);
221  maxSymbol_->setPen(pen);
222  clampMaxMarker_->setSymbol(maxSymbol_);
223  clampMaxMarker_->attach(qwtPlot);
224  clampMaxMarker_->show();
225  }
226 
227  // Draw at right boundary if greater than the maximal value we get from the function
228  clampMaxMarker_->setXValue(std::min(max_,realMax));
229 
230  } else {
231  if ( clampMaxMarker_ ) {
232  clampMaxMarker_->detach();
233  delete clampMaxMarker_;
234  clampMaxMarker_ = 0;
235  }
236  }
237 
238  // an plot it
239  qwtPlot->replot();
240 }
241 
242 void QwtFunctionPlot::setMinMax(double _min, double _max) {
243  min_ = _min;
244  max_ = _max;
245 }
246 
247 
248 
249 //=============================================================================
250 //=============================================================================
251 
252 #endif // WITH_QWT
Histogram plot.
Class for generating nice colors for doubles.
Definition: ColorCoder.hh:75