Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
HistogramItem.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$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50
51 #ifdef WITH_QWT
52
53 #include <qwt_plot.h>
54
55 #if QWT_VERSION < 0x060000
56 #include <qstring.h>
57 #include <qpainter.h>
58
59 #include <qwt_interval_data.h>
60 #include <qwt_painter.h>
61 #include <qwt_scale_map.h>
62 #include "HistogramItem.hh"
63
64 class HistogramItem::PrivateData
65 {
66 public:
67 int attributes;
68 QwtIntervalData data;
69 std::vector< QColor > colors_;
70 double reference;
71 };
72
73 HistogramItem::HistogramItem(const QwtText &title):
74 QwtPlotItem(title)
75 {
76 init();
77 }
78
79 HistogramItem::HistogramItem(const QString &title):
80 QwtPlotItem(QwtText(title))
81 {
82 init();
83 }
84
85 HistogramItem::~HistogramItem()
86 {
87 delete d_data;
88 }
89
90 void HistogramItem::init()
91 {
92 d_data = new PrivateData();
93 d_data->reference = 0.0;
94 d_data->attributes = HistogramItem::Auto;
95
96 setItemAttribute(QwtPlotItem::AutoScale, true);
97 setItemAttribute(QwtPlotItem::Legend, true);
98
99 setZ(20.0);
100 }
101
102 void HistogramItem::setBaseline(double reference)
103 {
104 if ( d_data->reference != reference )
105 {
106 d_data->reference = reference;
107 itemChanged();
108 }
109 }
110
111 double HistogramItem::baseline() const
112 {
113 return d_data->reference;
114 }
115
116 void HistogramItem::setData(const QwtIntervalData &data)
117 {
118 d_data->data = data;
119 itemChanged();
120 }
121
122 const QwtIntervalData &HistogramItem::data() const
123 {
124 return d_data->data;
125 }
126
127 void HistogramItem::setColors( std::vector< QColor >& _colors)
128 {
129 d_data->colors_ = _colors;
130 itemChanged();
131 }
132
133 QColor HistogramItem::color(uint i) const
134 {
135 if ( i < d_data->colors_.size() )
136 return d_data->colors_[i];
137 else
138 return Qt::darkBlue;
139 }
140
141 QwtDoubleRect HistogramItem::boundingRect() const
142 {
143 QwtDoubleRect rect = d_data->data.boundingRect();
144 if ( !rect.isValid() )
145 return rect;
146
147 if ( d_data->attributes & Xfy )
148 {
149 rect = QwtDoubleRect( rect.y(), rect.x(), rect.height(), rect.width() );
150
151 if ( rect.left() > d_data->reference )
152 rect.setLeft( d_data->reference );
153 else if ( rect.right() < d_data->reference )
154 rect.setRight( d_data->reference );
155 }
156 else
157 {
158 if ( rect.bottom() < d_data->reference )
159 rect.setBottom( d_data->reference );
160 else if ( rect.top() > d_data->reference )
161 rect.setTop( d_data->reference );
162 }
163
164 return rect;
165 }
166
167
168 int HistogramItem::rtti() const
169 {
170 return QwtPlotItem::Rtti_PlotHistogram;
171 }
172
173 void HistogramItem::setHistogramAttribute(HistogramAttribute attribute, bool on)
174 {
175 if ( bool(d_data->attributes & attribute) == on )
176 return;
177
178 if ( on )
179 d_data->attributes |= attribute;
180 else
181 d_data->attributes &= ~attribute;
182
183 itemChanged();
184 }
185
186 bool HistogramItem::testHistogramAttribute(HistogramAttribute attribute) const
187 {
188 return d_data->attributes & attribute;
189 }
190
191 void HistogramItem::draw(QPainter *painter, const QwtScaleMap &xMap,
192 const QwtScaleMap &yMap, const QRect &) const
193 {
194 const QwtIntervalData &iData = d_data->data;
195
196 const int x0 = xMap.transform(baseline());
197 const int y0 = yMap.transform(baseline());
198
199 for ( int i = 0; i < (int)iData.size(); i++ )
200 {
201 if ( d_data->attributes & HistogramItem::Xfy )
202 {
203 const int x2 = xMap.transform(iData.value(i));
204 if ( x2 == x0 )
205 continue;
206
207 int y1 = yMap.transform( iData.interval(i).minValue());
208 int y2 = yMap.transform( iData.interval(i).maxValue());
209 if ( y1 > y2 )
210 qSwap(y1, y2);
211
212 if ( i < (int)iData.size() - 2 )
213 {
214 const int yy1 = yMap.transform(iData.interval(i+1).minValue());
215 const int yy2 = yMap.transform(iData.interval(i+1).maxValue());
216
217 if ( y2 == qwtMin(yy1, yy2) )
218 {
219 const int xx2 = xMap.transform(
220 iData.interval(i+1).minValue());
221 if ( xx2 != x0 && ( (xx2 < x0 && x2 < x0) ||
222 (xx2 > x0 && x2 > x0) ) )
223 {
224 // One pixel distance between neighboured bars
225 y2++;
226 }
227 }
228 }
229
230 painter->setPen( QPen( color(i) ) );
231
232 drawBar(painter, Qt::Horizontal,
233 QRect(x0, y1, x2 - x0, y2 - y1));
234 }
235 else
236 {
237 const int y2 = yMap.transform(iData.value(i));
238 if ( y2 == y0 )
239 continue;
240
241 int x1 = xMap.transform(iData.interval(i).minValue());
242 int x2 = xMap.transform(iData.interval(i).maxValue());
243 if ( x1 > x2 )
244 qSwap(x1, x2);
245
246 if ( i < (int)iData.size() - 2 )
247 {
248 const int xx1 = xMap.transform(iData.interval(i+1).minValue());
249 const int xx2 = xMap.transform(iData.interval(i+1).maxValue());
250
251 if ( x2 == qwtMin(xx1, xx2) )
252 {
253 const int yy2 = yMap.transform(iData.value(i+1));
254 if ( yy2 != y0 && ( (yy2 < y0 && y2 < y0) || (yy2 > y0 && y2 > y0) ) )
255 {
256 // One pixel distance between neighboured bars
257 x2--;
258 }
259 }
260 }
261
262 painter->setPen( QPen( color(i) ) );
263
264 drawBar(painter, Qt::Vertical,
265 QRect(x1, y0, x2 - x1, y2 - y0) );
266 }
267 }
268 }
269
270 void HistogramItem::drawBar(QPainter *painter,
271 Qt::Orientation, const QRect& rect) const
272 {
273 painter->save();
274
275 const QColor color(painter->pen().color());
276 const QRect r = rect.normalized();
277
278
279 const int factor = 125;
280 const QColor light(color.light(factor));
281 const QColor dark(color.dark(factor));
282
283 painter->setBrush(color);
284 painter->setPen(Qt::NoPen);
285 QwtPainter::drawRect(painter, r.x() + 1, r.y() + 1,
286 r.width() - 2, r.height() - 2);
287 painter->setBrush(Qt::NoBrush);
288
289 painter->setPen(QPen(light, 2));
290
291 QwtPainter::drawLine(painter,
292 r.left() + 1, r.top() + 2, r.right() + 1, r.top() + 2);
293
294 painter->setPen(QPen(dark, 2));
295
296 QwtPainter::drawLine(painter,
297 r.left() + 1, r.bottom(), r.right() + 1, r.bottom());
298
299 painter->setPen(QPen(light, 1));
300
301 QwtPainter::drawLine(painter,
302 r.left(), r.top() + 1, r.left(), r.bottom());
303 QwtPainter::drawLine(painter,
304 r.left() + 1, r.top() + 2, r.left() + 1, r.bottom() - 1);
305
306
307 painter->setPen(QPen(dark, 1));
308
309 QwtPainter::drawLine(painter,
310 r.right() + 1, r.top() + 1, r.right() + 1, r.bottom());
311 QwtPainter::drawLine(painter,
312 r.right(), r.top() + 2, r.right(), r.bottom() - 1);
313
314 painter->restore();
315 }
316
317 #endif // QWT 5
318
319 #endif // WITH_QWT
HistogramItem::HistogramItem
HistogramItem(const QString &title=QString::null)
Constructor.
HistogramItem::~HistogramItem
virtual ~HistogramItem()
Destructor.
HistogramItem::setColors
void setColors(std::vector< QColor > &_colors)
Set colors.
HistogramItem::boundingRect
virtual QwtDoubleRect boundingRect() const
Function hat will return the datas bounding rectangle (for rendering)
HistogramItem::setData
void setData(const QwtIntervalData &data)
set data to render
HistogramItem::draw
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRect &) const
The actual draw function, drawing the bars inside the plot widget.
HistogramItem::drawBar
virtual void drawBar(QPainter *, Qt::Orientation o, const QRect &) const
Draws a single bar.