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