source: ntrip/trunk/BNC/qwt/qwt_plot_abstract_barchart.cpp@ 8418

Last change on this file since 8418 was 8127, checked in by stoecker, 8 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 9.1 KB
Line 
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#include "qwt_plot_abstract_barchart.h"
11#include "qwt_scale_map.h"
12
13static inline double qwtTransformWidth(
14 const QwtScaleMap &map, double value, double width )
15{
16 const double w2 = 0.5 * width;
17
18 const double v1 = map.transform( value - w2 );
19 const double v2 = map.transform( value + w2 );
20
21 return qAbs( v2 - v1 );
22}
23
24class QwtPlotAbstractBarChart::PrivateData
25{
26public:
27 PrivateData():
28 layoutPolicy( QwtPlotAbstractBarChart::AutoAdjustSamples ),
29 layoutHint( 0.5 ),
30 spacing( 10 ),
31 margin( 5 ),
32 baseline( 0.0 )
33 {
34 }
35
36 QwtPlotAbstractBarChart::LayoutPolicy layoutPolicy;
37 double layoutHint;
38 int spacing;
39 int margin;
40 double baseline;
41};
42
43/*!
44 Constructor
45 \param title Title of the chart
46*/
47QwtPlotAbstractBarChart::QwtPlotAbstractBarChart( const QwtText &title ):
48 QwtPlotSeriesItem( title )
49{
50 d_data = new PrivateData;
51
52 setItemAttribute( QwtPlotItem::Legend, true );
53 setItemAttribute( QwtPlotItem::AutoScale, true );
54 setItemAttribute( QwtPlotItem::Margins, true );
55 setZ( 19.0 );
56}
57
58//! Destructor
59QwtPlotAbstractBarChart::~QwtPlotAbstractBarChart()
60{
61 delete d_data;
62}
63
64/*!
65 The combination of layoutPolicy() and layoutHint() define how the width
66 of the bars is calculated
67
68 \param policy Layout policy
69
70 \sa layoutPolicy(), layoutHint()
71 */
72void QwtPlotAbstractBarChart::setLayoutPolicy( LayoutPolicy policy )
73{
74 if ( policy != d_data->layoutPolicy )
75 {
76 d_data->layoutPolicy = policy;
77 itemChanged();
78 }
79}
80
81/*!
82 The combination of layoutPolicy() and layoutHint() define how the width
83 of the bars is calculated
84
85 \return Layout policy of the chart item
86 \sa setLayoutPolicy(), layoutHint()
87 */
88QwtPlotAbstractBarChart::LayoutPolicy QwtPlotAbstractBarChart::layoutPolicy() const
89{
90 return d_data->layoutPolicy;
91}
92
93/*!
94 The combination of layoutPolicy() and layoutHint() define how the width
95 of the bars is calculated
96
97 \param hint Layout hint
98
99 \sa LayoutPolicy, layoutPolicy(), layoutHint()
100 */
101void QwtPlotAbstractBarChart::setLayoutHint( double hint )
102{
103 hint = qMax( 0.0, hint );
104 if ( hint != d_data->layoutHint )
105 {
106 d_data->layoutHint = hint;
107 itemChanged();
108 }
109}
110
111/*!
112 The combination of layoutPolicy() and layoutHint() define how the width
113 of the bars is calculated
114
115 \return Layout policy of the chart item
116 \sa LayoutPolicy, setLayoutHint(), layoutPolicy()
117*/
118double QwtPlotAbstractBarChart::layoutHint() const
119{
120 return d_data->layoutHint;
121}
122
123/*!
124 \brief Set the spacing
125
126 The spacing is the distance between 2 samples ( bars for QwtPlotBarChart or
127 a group of bars for QwtPlotMultiBarChart ) in paint device coordinates.
128
129 \sa spacing()
130 */
131void QwtPlotAbstractBarChart::setSpacing( int spacing )
132{
133 spacing = qMax( spacing, 0 );
134 if ( spacing != d_data->spacing )
135 {
136 d_data->spacing = spacing;
137 itemChanged();
138 }
139}
140
141/*!
142 \return Spacing between 2 samples ( bars or groups of bars )
143 \sa setSpacing(), margin()
144 */
145int QwtPlotAbstractBarChart::spacing() const
146{
147 return d_data->spacing;
148}
149/*!
150 \brief Set the margin
151
152 The margin is the distance between the outmost bars and the contentsRect()
153 of the canvas. The default setting is 5 pixels.
154
155 \param margin Margin
156
157 \sa spacing(), margin()
158 */
159void QwtPlotAbstractBarChart::setMargin( int margin )
160{
161 margin = qMax( margin, 0 );
162 if ( margin != d_data->margin )
163 {
164 d_data->margin = margin;
165 itemChanged();
166 }
167}
168
169/*!
170 \return Margin between the outmost bars and the contentsRect()
171 of the canvas.
172
173 \sa setMargin(), spacing()
174 */
175int QwtPlotAbstractBarChart::margin() const
176{
177 return d_data->margin;
178}
179
180/*!
181 \brief Set the baseline
182
183 The baseline is the origin for the chart. Each bar is
184 painted from the baseline in the direction of the sample
185 value. In case of a horizontal orientation() the baseline
186 is interpreted as x - otherwise as y - value.
187
188 The default value for the baseline is 0.
189
190 \param value Value for the baseline
191
192 \sa baseline(), QwtPlotSeriesItem::orientation()
193*/
194void QwtPlotAbstractBarChart::setBaseline( double value )
195{
196 if ( value != d_data->baseline )
197 {
198 d_data->baseline = value;
199 itemChanged();
200 }
201}
202
203/*!
204 \return Value for the origin of the bar chart
205 \sa setBaseline(), QwtPlotSeriesItem::orientation()
206 */
207double QwtPlotAbstractBarChart::baseline() const
208{
209 return d_data->baseline;
210}
211
212/*!
213 Calculate the width for a sample in paint device coordinates
214
215 \param map Scale map for the corresponding scale
216 \param canvasSize Size of the canvas in paint device coordinates
217 \param boundingSize Bounding size of the chart in plot coordinates
218 ( used in AutoAdjustSamples mode )
219 \param value Value of the sample
220
221 \return Sample width
222 \sa layoutPolicy(), layoutHint()
223*/
224double QwtPlotAbstractBarChart::sampleWidth( const QwtScaleMap &map,
225 double canvasSize, double boundingSize, double value ) const
226{
227 double width;
228
229 switch( d_data->layoutPolicy )
230 {
231 case ScaleSamplesToAxes:
232 {
233 width = qwtTransformWidth( map, value, d_data->layoutHint );
234 break;
235 }
236 case ScaleSampleToCanvas:
237 {
238 width = canvasSize * d_data->layoutHint;
239 break;
240 }
241 case FixedSampleSize:
242 {
243 width = d_data->layoutHint;
244 break;
245 }
246 case AutoAdjustSamples:
247 default:
248 {
249 const size_t numSamples = dataSize();
250
251 double w = 1.0;
252 if ( numSamples > 1 )
253 {
254 w = qAbs( boundingSize / ( numSamples - 1 ) );
255 }
256
257 width = qwtTransformWidth( map, value, w );
258 width -= d_data->spacing;
259 width = qMax( width, d_data->layoutHint );
260 }
261 }
262
263 return width;
264}
265
266/*!
267 \brief Calculate a hint for the canvas margin
268
269 Bar charts need to reserve some space for displaying the bars
270 for the first and the last sample. The hint is calculated
271 from the layoutHint() depending on the layoutPolicy().
272
273 The margins are in target device coordinates ( pixels on screen )
274
275 \param xMap Maps x-values into pixel coordinates.
276 \param yMap Maps y-values into pixel coordinates.
277 \param canvasRect Contents rectangle of the canvas in painter coordinates
278 \param left Returns the left margin
279 \param top Returns the top margin
280 \param right Returns the right margin
281 \param bottom Returns the bottom margin
282
283 \return Margin
284
285 \sa layoutPolicy(), layoutHint(), QwtPlotItem::Margins
286 QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins()
287 */
288void QwtPlotAbstractBarChart::getCanvasMarginHint( const QwtScaleMap &xMap,
289 const QwtScaleMap &yMap, const QRectF &canvasRect,
290 double &left, double &top, double &right, double &bottom ) const
291{
292 double hint = -1.0;
293
294 switch( layoutPolicy() )
295 {
296 case ScaleSampleToCanvas:
297 {
298 if ( orientation() == Qt::Vertical )
299 hint = 0.5 * canvasRect.width() * d_data->layoutHint;
300 else
301 hint = 0.5 * canvasRect.height() * d_data->layoutHint;
302
303 break;
304 }
305 case FixedSampleSize:
306 {
307 hint = 0.5 * d_data->layoutHint;
308 break;
309 }
310 case AutoAdjustSamples:
311 case ScaleSamplesToAxes:
312 default:
313 {
314 const size_t numSamples = dataSize();
315 if ( numSamples <= 0 )
316 break;
317
318 // doesn't work for nonlinear scales
319
320 const QRectF br = dataRect();
321 double spacing = 0.0;
322 double sampleWidthS = 1.0;
323
324 if ( layoutPolicy() == ScaleSamplesToAxes )
325 {
326 sampleWidthS = qMax( d_data->layoutHint, 0.0 );
327 }
328 else
329 {
330 spacing = d_data->spacing;
331
332 if ( numSamples > 1 )
333 {
334 sampleWidthS = qAbs( br.width() / ( numSamples - 1 ) );
335 }
336 }
337
338 double ds, w;
339 if ( orientation() == Qt::Vertical )
340 {
341 ds = qAbs( xMap.sDist() );
342 w = canvasRect.width();
343 }
344 else
345 {
346 ds = qAbs( yMap.sDist() );
347 w = canvasRect.height();
348 }
349
350 const double sampleWidthP = ( w - spacing * ( numSamples - 1 ) )
351 * sampleWidthS / ( ds + sampleWidthS );
352
353 hint = 0.5 * sampleWidthP;
354 hint += qMax( d_data->margin, 0 );
355 }
356 }
357
358 if ( orientation() == Qt::Vertical )
359 {
360 left = right = hint;
361 top = bottom = -1.0; // no hint
362 }
363 else
364 {
365 left = right = -1.0; // no hint
366 top = bottom = hint;
367 }
368}
Note: See TracBrowser for help on using the repository browser.