Skip to content

Commit 673f7ba

Browse files
committed
add HistogramItem from qwt5 examples for use by histogram widget
1 parent 5f91848 commit 673f7ba

File tree

1 file changed

+347
-0
lines changed

1 file changed

+347
-0
lines changed

src/gui/raster/qwt5_histogram_item.h

+347
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2+
* Qwt Widget Library
3+
* Copyright (C) 1997 Josef Wilgen
4+
* Copyright (C) 2002 Uwe Rathmann
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the Qwt License, Version 1.0
8+
*****************************************************************************/
9+
10+
#ifndef HISTOGRAM_ITEM_H
11+
#define HISTOGRAM_ITEM_H
12+
13+
#include <qglobal.h>
14+
#include <qcolor.h>
15+
16+
#include "qwt_plot_item.h"
17+
18+
class QwtIntervalData;
19+
class QString;
20+
21+
class HistogramItem: public QwtPlotItem
22+
{
23+
public:
24+
explicit HistogramItem(const QString &title = QString::null);
25+
explicit HistogramItem(const QwtText &title);
26+
virtual ~HistogramItem();
27+
28+
void setData(const QwtIntervalData &data);
29+
const QwtIntervalData &data() const;
30+
31+
void setColor(const QColor &);
32+
QColor color() const;
33+
34+
virtual QwtDoubleRect boundingRect() const;
35+
36+
virtual int rtti() const;
37+
38+
virtual void draw(QPainter *, const QwtScaleMap &xMap,
39+
const QwtScaleMap &yMap, const QRect &) const;
40+
41+
void setBaseline(double reference);
42+
double baseline() const;
43+
44+
enum HistogramAttribute
45+
{
46+
Auto = 0,
47+
Xfy = 1
48+
};
49+
50+
void setHistogramAttribute(HistogramAttribute, bool on = true);
51+
bool testHistogramAttribute(HistogramAttribute) const;
52+
53+
protected:
54+
virtual void drawBar(QPainter *,
55+
Qt::Orientation o, const QRect &) const;
56+
57+
private:
58+
void init();
59+
60+
class PrivateData;
61+
PrivateData *d_data;
62+
};
63+
64+
#include <qstring.h>
65+
#include <qpainter.h>
66+
#include <qwt_plot.h>
67+
#include <qwt_interval_data.h>
68+
#include <qwt_painter.h>
69+
#include <qwt_scale_map.h>
70+
71+
class HistogramItem::PrivateData
72+
{
73+
public:
74+
int attributes;
75+
QwtIntervalData data;
76+
QColor color;
77+
double reference;
78+
};
79+
80+
HistogramItem::HistogramItem(const QwtText &title):
81+
QwtPlotItem(title)
82+
{
83+
init();
84+
}
85+
86+
HistogramItem::HistogramItem(const QString &title):
87+
QwtPlotItem(QwtText(title))
88+
{
89+
init();
90+
}
91+
92+
HistogramItem::~HistogramItem()
93+
{
94+
delete d_data;
95+
}
96+
97+
void HistogramItem::init()
98+
{
99+
d_data = new PrivateData();
100+
d_data->reference = 0.0;
101+
d_data->attributes = HistogramItem::Auto;
102+
103+
setItemAttribute(QwtPlotItem::AutoScale, true);
104+
setItemAttribute(QwtPlotItem::Legend, true);
105+
106+
setZ(20.0);
107+
}
108+
109+
void HistogramItem::setBaseline(double reference)
110+
{
111+
if ( d_data->reference != reference )
112+
{
113+
d_data->reference = reference;
114+
itemChanged();
115+
}
116+
}
117+
118+
double HistogramItem::baseline() const
119+
{
120+
return d_data->reference;
121+
}
122+
123+
void HistogramItem::setData(const QwtIntervalData &data)
124+
{
125+
d_data->data = data;
126+
itemChanged();
127+
}
128+
129+
const QwtIntervalData &HistogramItem::data() const
130+
{
131+
return d_data->data;
132+
}
133+
134+
void HistogramItem::setColor(const QColor &color)
135+
{
136+
if ( d_data->color != color )
137+
{
138+
d_data->color = color;
139+
itemChanged();
140+
}
141+
}
142+
143+
QColor HistogramItem::color() const
144+
{
145+
return d_data->color;
146+
}
147+
148+
QwtDoubleRect HistogramItem::boundingRect() const
149+
{
150+
QwtDoubleRect rect = d_data->data.boundingRect();
151+
if ( !rect.isValid() )
152+
return rect;
153+
154+
if ( d_data->attributes & Xfy )
155+
{
156+
rect = QwtDoubleRect( rect.y(), rect.x(),
157+
rect.height(), rect.width() );
158+
159+
if ( rect.left() > d_data->reference )
160+
rect.setLeft( d_data->reference );
161+
else if ( rect.right() < d_data->reference )
162+
rect.setRight( d_data->reference );
163+
}
164+
else
165+
{
166+
if ( rect.bottom() < d_data->reference )
167+
rect.setBottom( d_data->reference );
168+
else if ( rect.top() > d_data->reference )
169+
rect.setTop( d_data->reference );
170+
}
171+
172+
return rect;
173+
}
174+
175+
176+
int HistogramItem::rtti() const
177+
{
178+
return QwtPlotItem::Rtti_PlotHistogram;
179+
}
180+
181+
void HistogramItem::setHistogramAttribute(HistogramAttribute attribute, bool on)
182+
{
183+
if ( bool(d_data->attributes & attribute) == on )
184+
return;
185+
186+
if ( on )
187+
d_data->attributes |= attribute;
188+
else
189+
d_data->attributes &= ~attribute;
190+
191+
itemChanged();
192+
}
193+
194+
bool HistogramItem::testHistogramAttribute(HistogramAttribute attribute) const
195+
{
196+
return d_data->attributes & attribute;
197+
}
198+
199+
void HistogramItem::draw(QPainter *painter, const QwtScaleMap &xMap,
200+
const QwtScaleMap &yMap, const QRect &) const
201+
{
202+
const QwtIntervalData &iData = d_data->data;
203+
204+
painter->setPen(QPen(d_data->color));
205+
206+
const int x0 = xMap.transform(baseline());
207+
const int y0 = yMap.transform(baseline());
208+
209+
for ( int i = 0; i < (int)iData.size(); i++ )
210+
{
211+
if ( d_data->attributes & HistogramItem::Xfy )
212+
{
213+
const int x2 = xMap.transform(iData.value(i));
214+
if ( x2 == x0 )
215+
continue;
216+
217+
int y1 = yMap.transform( iData.interval(i).minValue());
218+
int y2 = yMap.transform( iData.interval(i).maxValue());
219+
if ( y1 > y2 )
220+
qSwap(y1, y2);
221+
222+
if ( i < (int)iData.size() - 2 )
223+
{
224+
const int yy1 = yMap.transform(iData.interval(i+1).minValue());
225+
const int yy2 = yMap.transform(iData.interval(i+1).maxValue());
226+
227+
if ( y2 == qwtMin(yy1, yy2) )
228+
{
229+
const int xx2 = xMap.transform(
230+
iData.interval(i+1).minValue());
231+
if ( xx2 != x0 && ( (xx2 < x0 && x2 < x0) ||
232+
(xx2 > x0 && x2 > x0) ) )
233+
{
234+
// One pixel distance between neighboured bars
235+
y2++;
236+
}
237+
}
238+
}
239+
240+
drawBar(painter, Qt::Horizontal,
241+
QRect(x0, y1, x2 - x0, y2 - y1));
242+
}
243+
else
244+
{
245+
const int y2 = yMap.transform(iData.value(i));
246+
if ( y2 == y0 )
247+
continue;
248+
249+
int x1 = xMap.transform(iData.interval(i).minValue());
250+
int x2 = xMap.transform(iData.interval(i).maxValue());
251+
if ( x1 > x2 )
252+
qSwap(x1, x2);
253+
254+
if ( i < (int)iData.size() - 2 )
255+
{
256+
const int xx1 = xMap.transform(iData.interval(i+1).minValue());
257+
const int xx2 = xMap.transform(iData.interval(i+1).maxValue());
258+
259+
if ( x2 == qwtMin(xx1, xx2) )
260+
{
261+
const int yy2 = yMap.transform(iData.value(i+1));
262+
if ( yy2 != y0 && ( (yy2 < y0 && y2 < y0) ||
263+
(yy2 > y0 && y2 > y0) ) )
264+
{
265+
// One pixel distance between neighboured bars
266+
x2--;
267+
}
268+
}
269+
}
270+
drawBar(painter, Qt::Vertical,
271+
QRect(x1, y0, x2 - x1, y2 - y0) );
272+
}
273+
}
274+
}
275+
276+
void HistogramItem::drawBar(QPainter *painter,
277+
Qt::Orientation, const QRect& rect) const
278+
{
279+
painter->save();
280+
281+
const QColor color(painter->pen().color());
282+
#if QT_VERSION >= 0x040000
283+
const QRect r = rect.normalized();
284+
#else
285+
const QRect r = rect.normalize();
286+
#endif
287+
288+
const int factor = 125;
289+
const QColor light(color.light(factor));
290+
const QColor dark(color.dark(factor));
291+
292+
painter->setBrush(color);
293+
painter->setPen(Qt::NoPen);
294+
QwtPainter::drawRect(painter, r.x() + 1, r.y() + 1,
295+
r.width() - 2, r.height() - 2);
296+
painter->setBrush(Qt::NoBrush);
297+
298+
painter->setPen(QPen(light, 2));
299+
#if QT_VERSION >= 0x040000
300+
QwtPainter::drawLine(painter,
301+
r.left() + 1, r.top() + 2, r.right() + 1, r.top() + 2);
302+
#else
303+
QwtPainter::drawLine(painter,
304+
r.left(), r.top() + 2, r.right() + 1, r.top() + 2);
305+
#endif
306+
307+
painter->setPen(QPen(dark, 2));
308+
#if QT_VERSION >= 0x040000
309+
QwtPainter::drawLine(painter,
310+
r.left() + 1, r.bottom(), r.right() + 1, r.bottom());
311+
#else
312+
QwtPainter::drawLine(painter,
313+
r.left(), r.bottom(), r.right() + 1, r.bottom());
314+
#endif
315+
316+
painter->setPen(QPen(light, 1));
317+
318+
#if QT_VERSION >= 0x040000
319+
QwtPainter::drawLine(painter,
320+
r.left(), r.top() + 1, r.left(), r.bottom());
321+
QwtPainter::drawLine(painter,
322+
r.left() + 1, r.top() + 2, r.left() + 1, r.bottom() - 1);
323+
#else
324+
QwtPainter::drawLine(painter,
325+
r.left(), r.top() + 1, r.left(), r.bottom() + 1);
326+
QwtPainter::drawLine(painter,
327+
r.left() + 1, r.top() + 2, r.left() + 1, r.bottom());
328+
#endif
329+
330+
painter->setPen(QPen(dark, 1));
331+
332+
#if QT_VERSION >= 0x040000
333+
QwtPainter::drawLine(painter,
334+
r.right() + 1, r.top() + 1, r.right() + 1, r.bottom());
335+
QwtPainter::drawLine(painter,
336+
r.right(), r.top() + 2, r.right(), r.bottom() - 1);
337+
#else
338+
QwtPainter::drawLine(painter,
339+
r.right() + 1, r.top() + 1, r.right() + 1, r.bottom() + 1);
340+
QwtPainter::drawLine(painter,
341+
r.right(), r.top() + 2, r.right(), r.bottom());
342+
#endif
343+
344+
painter->restore();
345+
}
346+
347+
#endif

0 commit comments

Comments
 (0)