QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qwt5_histogram_item.cpp
Go to the documentation of this file.
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 #include <qwt_global.h>
10 
11 #if defined( QWT_VERSION ) && QWT_VERSION<0x060000
12 
13 #include <qglobal.h>
14 #include <qcolor.h>
15 
16 #include "qwt5_histogram_item.h"
17 
18 HistogramItem::HistogramItem( const QwtText &title ):
19  QwtPlotItem( title )
20 {
21  init();
22 }
23 
24 HistogramItem::HistogramItem( const QString &title ):
25  QwtPlotItem( QwtText( title ) )
26 {
27  init();
28 }
29 
30 HistogramItem::~HistogramItem()
31 {
32  delete d_data;
33 }
34 
35 void HistogramItem::init()
36 {
37  d_data = new PrivateData();
38  d_data->reference = 0.0;
39  d_data->attributes = HistogramItem::Auto;
40  d_data->flat = false;
41  d_data->spacing = 1;
42  d_data->pen = Qt::NoPen;
43 
44  setItemAttribute( QwtPlotItem::AutoScale, true );
45  setItemAttribute( QwtPlotItem::Legend, true );
46 
47  setZ( 20.0 );
48 }
49 
50 void HistogramItem::setBaseline( double reference )
51 {
52  if ( d_data->reference != reference )
53  {
54  d_data->reference = reference;
55  itemChanged();
56  }
57 }
58 
59 double HistogramItem::baseline() const
60 {
61  return d_data->reference;
62 }
63 
64 void HistogramItem::setData( const QwtIntervalData &data )
65 {
66  d_data->data = data;
67  itemChanged();
68 }
69 
70 const QwtIntervalData &HistogramItem::data() const
71 {
72  return d_data->data;
73 }
74 
75 void HistogramItem::setColor( const QColor &color )
76 {
77  if ( d_data->color != color )
78  {
79  d_data->color = color;
80  itemChanged();
81  }
82 }
83 
84 QColor HistogramItem::color() const
85 {
86  return d_data->color;
87 }
88 
89 void HistogramItem::setFlat( bool flat )
90 {
91  if ( d_data->flat != flat )
92  {
93  d_data->flat = flat;
94  itemChanged();
95  }
96 }
97 
98 bool HistogramItem::flat() const
99 {
100  return d_data->flat;
101 }
102 
103 void HistogramItem::setSpacing( int spacing )
104 {
105  if ( d_data->spacing != spacing )
106  {
107  d_data->spacing = spacing;
108  itemChanged();
109  }
110 }
111 
112 int HistogramItem::spacing() const
113 {
114  return d_data->spacing;
115 }
116 
117 void HistogramItem::setPen( const QPen &pen )
118 {
119  if ( d_data->pen != pen )
120  {
121  d_data->pen = pen;
122  itemChanged();
123  }
124 }
125 
126 QPen HistogramItem::pen() const
127 {
128  return d_data->pen;
129 }
130 
131 QwtDoubleRect HistogramItem::boundingRect() const
132 {
133  QwtDoubleRect rect = d_data->data.boundingRect();
134  if ( !rect.isValid() )
135  return rect;
136 
137  if ( d_data->attributes & Xfy )
138  {
139  rect = QwtDoubleRect( rect.y(), rect.x(),
140  rect.height(), rect.width() );
141 
142  if ( rect.left() > d_data->reference )
143  rect.setLeft( d_data->reference );
144  else if ( rect.right() < d_data->reference )
145  rect.setRight( d_data->reference );
146  }
147  else
148  {
149  if ( rect.bottom() < d_data->reference )
150  rect.setBottom( d_data->reference );
151  else if ( rect.top() > d_data->reference )
152  rect.setTop( d_data->reference );
153  }
154 
155  return rect;
156 }
157 
158 
159 int HistogramItem::rtti() const
160 {
161  return QwtPlotItem::Rtti_PlotHistogram;
162 }
163 
164 void HistogramItem::setHistogramAttribute( HistogramAttribute attribute, bool on )
165 {
166  if ( bool( d_data->attributes & attribute ) == on )
167  return;
168 
169  if ( on )
170  d_data->attributes |= attribute;
171  else
172  d_data->attributes &= ~attribute;
173 
174  itemChanged();
175 }
176 
177 bool HistogramItem::testHistogramAttribute( HistogramAttribute attribute ) const
178 {
179  return d_data->attributes & attribute;
180 }
181 
182 void HistogramItem::draw( QPainter *painter, const QwtScaleMap &xMap,
183  const QwtScaleMap &yMap, const QRect & ) const
184 {
185  const QwtIntervalData &iData = d_data->data;
186  const int x0 = xMap.transform( baseline() );
187  const int y0 = yMap.transform( baseline() );
188 
189  for ( int i = 0; i < ( int )iData.size(); i++ )
190  {
191  if ( d_data->attributes & HistogramItem::Xfy )
192  {
193  const int x2 = xMap.transform( iData.value( i ) );
194  if ( x2 == x0 )
195  continue;
196 
197  int y1 = yMap.transform( iData.interval( i ).minValue() );
198  int y2 = yMap.transform( iData.interval( i ).maxValue() );
199  if ( y1 > y2 )
200  qSwap( y1, y2 );
201 
202  if ( i < ( int )iData.size() - 2 )
203  {
204  const int yy1 = yMap.transform( iData.interval( i + 1 ).minValue() );
205  const int yy2 = yMap.transform( iData.interval( i + 1 ).maxValue() );
206 
207  if ( y2 == qwtMin( yy1, yy2 ) )
208  {
209  const int xx2 = xMap.transform(
210  iData.interval( i + 1 ).minValue() );
211  if ( xx2 != x0 && (( xx2 < x0 && x2 < x0 ) ||
212  ( xx2 > x0 && x2 > x0 ) ) )
213  {
214  // distance between neighboured bars
215  y2 += d_data->spacing;
216  }
217  }
218  }
219 
220  drawBar( painter, Qt::Horizontal,
221  QRect( x0, y1, x2 - x0, y2 - y1 ) );
222  }
223  else
224  {
225  const int y2 = yMap.transform( iData.value( i ) );
226  if ( y2 == y0 )
227  continue;
228 
229  int x1 = xMap.transform( iData.interval( i ).minValue() );
230  int x2 = xMap.transform( iData.interval( i ).maxValue() );
231  if ( x1 > x2 )
232  qSwap( x1, x2 );
233 
234  if ( i < ( int )iData.size() - 2 )
235  {
236  const int xx1 = xMap.transform( iData.interval( i + 1 ).minValue() );
237  const int xx2 = xMap.transform( iData.interval( i + 1 ).maxValue() );
238 
239  if ( x2 == qwtMin( xx1, xx2 ) )
240  {
241  const int yy2 = yMap.transform( iData.value( i + 1 ) );
242  if ( yy2 != y0 && (( yy2 < y0 && y2 < y0 ) ||
243  ( yy2 > y0 && y2 > y0 ) ) )
244  {
245  //distance between neighboured bars
246  x2 -= d_data->spacing;
247  }
248  }
249  }
250  drawBar( painter, Qt::Vertical,
251  QRect( x1, y0, x2 - x1, y2 - y0 ) );
252  }
253  }
254 }
255 
256 void HistogramItem::drawBar( QPainter *painter,
257  Qt::Orientation, QRect rect ) const
258 {
259  painter->save();
260 
261  const QRect r = rect.normalized();
262  painter->setBrush( d_data->color );
263 
264  if ( d_data->flat )
265  {
266  painter->setPen( d_data->pen );
267  int penWidth = d_data->pen == Qt::NoPen ? 0 :
268  ( d_data->pen.isCosmetic() ? 1 : d_data->pen.width() );
269  QwtPainter::drawRect( painter, r.x(), r.y(),
270  r.width(), r.height() - penWidth );
271  }
272  else
273  {
274  const int factor = 125;
275  const QColor light( d_data->color.light( factor ) );
276  const QColor dark( d_data->color.dark( factor ) );
277 
278  QwtPainter::drawRect( painter, r.x() + 1, r.y() + 1,
279  r.width() - 2, r.height() - 2 );
280 
281  painter->setBrush( Qt::NoBrush );
282 
283  painter->setPen( QPen( light, 2 ) );
284  QwtPainter::drawLine( painter,
285  r.left() + 1, r.top() + 2, r.right() + 1, r.top() + 2 );
286 
287  painter->setPen( QPen( dark, 2 ) );
288  QwtPainter::drawLine( painter,
289  r.left() + 1, r.bottom(), r.right() + 1, r.bottom() );
290 
291  painter->setPen( QPen( light, 1 ) );
292 
293  QwtPainter::drawLine( painter,
294  r.left(), r.top() + 1, r.left(), r.bottom() );
295  QwtPainter::drawLine( painter,
296  r.left() + 1, r.top() + 2, r.left() + 1, r.bottom() - 1 );
297 
298  painter->setPen( QPen( dark, 1 ) );
299 
300  QwtPainter::drawLine( painter,
301  r.right() + 1, r.top() + 1, r.right() + 1, r.bottom() );
302  QwtPainter::drawLine( painter,
303  r.right(), r.top() + 2, r.right(), r.bottom() - 1 );
304  }
305 
306  painter->restore();
307 }
308 
310 // this was adapted from QwtPlotCurve::updateLegend()
311 void HistogramItem::updateLegend( QwtLegend *legend ) const
312 {
313  if ( !legend )
314  return;
315 
316  QwtPlotItem::updateLegend( legend );
317 
318  QWidget *widget = legend->find( this );
319  if ( !widget || !widget->inherits( "QwtLegendItem" ) )
320  return;
321 
322  QwtLegendItem *legendItem = ( QwtLegendItem * )widget;
323 
324  const bool doUpdate = legendItem->updatesEnabled();
325  legendItem->setUpdatesEnabled( false );
326 
327  const int policy = legend->displayPolicy();
328 
329  if ( policy == QwtLegend::FixedIdentifier )
330  {
331  int mode = legend->identifierMode();
332 
333  legendItem->setCurvePen( QPen( color() ) );
334 
335  if ( mode & QwtLegendItem::ShowText )
336  legendItem->setText( title() );
337  else
338  legendItem->setText( QwtText() );
339 
340  legendItem->setIdentifierMode( mode );
341  }
342  else if ( policy == QwtLegend::AutoIdentifier )
343  {
344  int mode = 0;
345 
346  legendItem->setCurvePen( QPen( color() ) );
347  mode |= QwtLegendItem::ShowLine;
348  if ( !title().isEmpty() )
349  {
350  legendItem->setText( title() );
351  mode |= QwtLegendItem::ShowText;
352  }
353  else
354  {
355  legendItem->setText( QwtText() );
356  }
357  legendItem->setIdentifierMode( mode );
358  }
359 
360  legendItem->setUpdatesEnabled( doUpdate );
361  legendItem->update();
362 }
363 
364 #endif
QRect normalized() const
int right() const
void save()
int height() const
int x() const
int y() const
virtual QVariant data(int column, int role) const
int top() const
bool inherits(const char *className) const
void setPen(const QColor &color)
int left() const
void setBrush(const QBrush &brush)
void restore()
int width() const
QWidget * find(WId id)
int bottom() const