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 //
45 // CLASS QtFunctionPlot - IMPLEMENTATION
46 //
47 //=============================================================================
48
49 //== INCLUDES =================================================================
50
51 #ifdef WITH_QWT
52
53 #include "QwtFunctionPlot.hh"
54
55 #include <iostream>
56 #include <algorithm>
57
58 #include <QPen>
59
60 #include <QLineEdit>
61 #include <QLabel>
62 #include <QPainter>
63 #include <qwt_curve_fitter.h>
64 #include <qwt_plot_panner.h>
65 #include <qwt_symbol.h>
66 #include <qwt_plot_histogram.h>
67
68 #include <ACG/Utils/ColorCoder.hh>
69
70
71 #include <cfloat>
72 #include <cmath>
73
74 //== NAMESPACES ===============================================================
75
76 //== IMPLEMENTATION ==========================================================
77
78
80 QwtFunctionPlot::QwtFunctionPlot(QWidget* _parent) :
81 QDialog( _parent ),
82 Ui::QwtFunctionPlotBase(),
83 plot_zoomer_(0),
84 clampMinMarker_(0),
85 minSymbol_(0),
86 clampMaxMarker_(0),
87 maxSymbol_(0),
88 min_(FLT_MAX),
89 max_(FLT_MIN)
90 {
91 setupUi( this );
92
93 qwtPlot->setAxisTitle(QwtPlot::yLeft, "count" );
94
95 plot_zoomer_ = new QwtPlotZoomer( qwtPlot->canvas());
96 plot_zoomer_->initKeyPattern();
97
98 QwtPlotPanner *panner = new QwtPlotPanner( qwtPlot->canvas() );
99 panner->setMouseButton( Qt::MidButton );
100
101 // delete widget on close
102 setAttribute(Qt::WA_DeleteOnClose, true);
103
104 histogram_ = new Histogram();
105 }
106
107 //------------------------------------------------------------------------------
108
109 void QwtFunctionPlot::setFunction(const std::vector<double>& _values)
110 {
111 values_ = _values;
112 }
113
114 //------------------------------------------------------------------------------
115
116 void QwtFunctionPlot::replot()
117 {
118 //create intervals
119 const int intervalCount = 100;
120
121 QVector<QwtIntervalSample> intervals(intervalCount);
122 std::vector< QColor > colors;
123
124 double realMin = FLT_MAX;
125 double realMax = -FLT_MAX;
126
127 for ( unsigned int i=0; i < values_.size(); i++) {
128 realMin = std::min(realMin,values_[i]);
129 realMax = std::max(realMax,values_[i]);
130 }
131
132 double pos = realMin;
133 double width = ( realMax - realMin ) / intervalCount;
134
135 QColor lastColor = Qt::black;
136
137 ACG::ColorCoder cCoder(std::max(min_,realMin),std::min(max_,realMax));
138
139 for ( int i = 0; i < (int)intervals.size(); i++ )
140 {
141
142 intervals[i] = QwtIntervalSample(0.0,pos, pos + width);
143 pos += width;
144
145 //compute a color for the given interval
146 const double intervalCenter = pos + (width/2.0);
147
148 colors.push_back( cCoder.color_qcolor(intervalCenter) );
149 lastColor = colors.back();
150 }
151
152 // sort values into intervals
153 // Could be more efficient when we calculate the correct interval based on the above loop directly
154 for ( uint i=0; i < values_.size(); i++)
155 for ( int j = 0; j < (int)intervals.size(); j++ )
156 if ( intervals[j].interval.contains( values_[i] ) ) {
157 intervals[j].value++;
158 break;
159 }
160
161 //get max Count for scaling the y-axis
162 double maxCount = 0;
163
164 for ( int i = 0; i < (int)intervals.size(); i++ )
165 maxCount = std::max(maxCount, intervals[i].value);
166
167
168 QwtIntervalSeriesData* data = new QwtIntervalSeriesData(intervals);
169 histogram_->setData(data);
170 histogram_->setColors(colors);
171 histogram_->attach(qwtPlot);
172
173 qwtPlot->setAxisScale(QwtPlot::yLeft, 0.0, maxCount);
174 qwtPlot->setAxisScale(QwtPlot::xBottom, realMin, realMax);
175
176 //define this scaling as the zoomBase
177 plot_zoomer_->setZoomBase();
178
179 //Mark the clamp values in the histogram.
180 if ( min_ > realMin ) {
181 if ( ! clampMinMarker_ ) {
182 clampMinMarker_ = new QwtPlotMarker();
183 minSymbol_ = new QwtSymbol(QwtSymbol::VLine);
184 minSymbol_->setColor(cCoder.color_qcolor(std::max(min_,realMin)));
185 minSymbol_->setSize(200,1000);
186 QPen pen = minSymbol_->pen();
187 pen.setWidth(3);
188 minSymbol_->setPen(pen);
189 clampMinMarker_->setSymbol(minSymbol_);
190 clampMinMarker_->attach(qwtPlot);
191 clampMinMarker_->show();
192 }
193
194 // Draw at right boundary if greater than the maximal value we get from the function
195 clampMinMarker_->setXValue(std::max(min_,realMin));
196
197 } else {
198 if ( clampMinMarker_ ) {
199 clampMinMarker_->detach();
200 delete clampMinMarker_;
201 clampMinMarker_ = 0;
202 }
203 }
204
205 //Mark the clamp values in the histogram.
206 if ( max_ < realMax ) {
207 if ( ! clampMaxMarker_ ) {
208 clampMaxMarker_ = new QwtPlotMarker();
209 maxSymbol_ = new QwtSymbol(QwtSymbol::VLine);
210 maxSymbol_->setColor(cCoder.color_qcolor(std::min(max_,realMax)));
211 maxSymbol_->setSize(200,1000);
212 QPen pen = maxSymbol_->pen();
213 pen.setWidth(3);
214 maxSymbol_->setPen(pen);
215 clampMaxMarker_->setSymbol(maxSymbol_);
216 clampMaxMarker_->attach(qwtPlot);
217 clampMaxMarker_->show();
218 }
219
220 // Draw at right boundary if greater than the maximal value we get from the function
221 clampMaxMarker_->setXValue(std::min(max_,realMax));
222
223 } else {
224 if ( clampMaxMarker_ ) {
225 clampMaxMarker_->detach();
226 delete clampMaxMarker_;
227 clampMaxMarker_ = 0;
228 }
229 }
230
231 // an plot it
232 qwtPlot->replot();
233 }
234
235 void QwtFunctionPlot::setMinMax(double _min, double _max) {
236 min_ = _min;
237 max_ = _max;
238 }
239
240
241
242 //=============================================================================
243 //=============================================================================
244
245 #endif // WITH_QWT
ACG::ColorCoder
Class for generating nice colors for doubles.
Definition: ColorCoder.hh:68
Histogram
Histogram plot.
Definition: QwtHistogramm.hh:63