QGIS API Documentation  2.14.0-Essen
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
int top() const
bool inherits(const char *className) const
void setPen(const QColor &color)
int left() const
void setBrush(const QBrush &brush)
QRect rect() const
void restore()
int width() const
QWidget * find(WId id)
int bottom() const
void setLeft(int x)