~ubuntu-branches/ubuntu/warty/koffice/warty

« back to all changes in this revision

Viewing changes to kchart/kdchart/KDChartBWPainter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ben Burton
  • Date: 2004-05-09 11:33:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040509113300-vfrdadqsvjfuhn3b
Tags: 1:1.3.1-1
* New upstream bugfix release.
* Built against newer imagemagick (closes: #246623).
* Made koffice-libs/kformula recommend/depend on latex-xft-fonts, which
  provides mathematical fonts that the formula editor can use.  Also
  patched the kformula part to make these fonts the default.
* Changed kword menu hint from "WordProcessors" to "Word processors"
  (closes: #246209).
* Spellchecker configuration is now fixed (closes: #221256, #227568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++ -*-
 
2
   KDChart - a multi-platform charting engine
 
3
   */
 
4
 
 
5
/****************************************************************************
 
6
 ** Copyright (C) 2001-2003 Klar�lvdalens Datakonsult AB.  All rights reserved.
 
7
 **
 
8
 ** This file is part of the KDChart library.
 
9
 **
 
10
 ** This file may be distributed and/or modified under the terms of the
 
11
 ** GNU General Public License version 2 as published by the Free Software
 
12
 ** Foundation and appearing in the file LICENSE.GPL included in the
 
13
 ** packaging of this file.
 
14
 **
 
15
 ** Licensees holding valid commercial KDChart licenses may use this file in
 
16
 ** accordance with the KDChart Commercial License Agreement provided with
 
17
 ** the Software.
 
18
 **
 
19
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
20
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
21
 **
 
22
 ** See http://www.klaralvdalens-datakonsult.se/?page=products for
 
23
 **   information about KDChart Commercial License Agreements.
 
24
 **
 
25
 ** Contact info@klaralvdalens-datakonsult.se if any conditions of this
 
26
 ** licensing are not clear to you.
 
27
 **
 
28
 **********************************************************************/
 
29
#include "KDChartBWPainter.h"
 
30
#include <KDChartParams.h>
 
31
#include "KDChartTextPiece.h"
 
32
 
 
33
#include <qpainter.h>
 
34
#if COMPAT_QT_VERSION >= 0x030000
 
35
#include <qmemarray.h>
 
36
#else
 
37
#include <qarray.h>
 
38
#define QMemArray QArray
 
39
#endif
 
40
 
 
41
#include <stdlib.h>
 
42
 
 
43
/**
 
44
  \class KDChartBWPainter KDChartBWPainter.h
 
45
 
 
46
  \brief A chart painter implementation that can paint Box&Whisker charts.
 
47
  */
 
48
 
 
49
/**
 
50
  Constructor. Sets up internal data structures as necessary.
 
51
 
 
52
  \param params the KDChartParams structure that defines the chart
 
53
  */
 
54
    KDChartBWPainter::KDChartBWPainter( KDChartParams* params ) :
 
55
KDChartAxesPainter( params )
 
56
{
 
57
    // This constructor intentionally left blank so far; we cannot setup the
 
58
    // geometry yet since we do not know the size of the painter.
 
59
}
 
60
 
 
61
 
 
62
/**
 
63
  Destructor.
 
64
  */
 
65
KDChartBWPainter::~KDChartBWPainter()
 
66
{
 
67
    // intentionally left blank
 
68
}
 
69
 
 
70
 
 
71
void quicksort( QMemArray<double>& a, int lo, int hi )
 
72
{
 
73
    int    i=lo, j=hi;
 
74
    double h;
 
75
    double x=a[(lo+hi)/2];
 
76
    do
 
77
    {
 
78
        while (a[i]<x) i++;
 
79
        while (a[j]>x) j--;
 
80
        if (i<=j)
 
81
        {
 
82
            h=a[i]; a[i]=a[j]; a[j]=h;
 
83
            i++; j--;
 
84
        }
 
85
    } while (i<=j);
 
86
    if (lo<j) quicksort(a, lo, j);
 
87
    if (i<hi) quicksort(a, i, hi);
 
88
}
 
89
 
 
90
 
 
91
// The following function returns the number of used cells containing a double.
 
92
int KDChartBWPainter::calculateStats( KDChartTableDataBase& data,
 
93
        uint dataset )
 
94
{
 
95
    const uint nMax = data.usedCols();
 
96
    int nUsed = 0;
 
97
    QMemArray<double> values( nMax );
 
98
    double sum = 0.0;
 
99
    if( data.sorted() ){
 
100
        for( uint i=0; i<nMax; ++i)
 
101
            if( data.cell(dataset, i).isDouble(1) ){
 
102
                values[nUsed] = data.cell(dataset, i).doubleValue(1);
 
103
                sum += values[nUsed];
 
104
                ++nUsed;
 
105
            }
 
106
    }else{
 
107
        // make copy of the dataset and look if it is sorted
 
108
        bool sorted = true;
 
109
        double last = 0.0; //  <--  avoids an annoying compile-time warning
 
110
        for( uint i=0; i<nMax; ++i){
 
111
            if( data.cell(dataset, i).isDouble(1) ){
 
112
                values[nUsed] = data.cell(dataset, i).doubleValue(1);
 
113
                if(    nUsed // skip 1st value
 
114
                        && last > values[nUsed] )
 
115
                    sorted = false;
 
116
                last = values[nUsed];
 
117
                sum += last;
 
118
                ++nUsed;
 
119
            }
 
120
        }
 
121
        if( !sorted ){
 
122
            // sort our copy of the dataset
 
123
            quicksort( values, 0, nUsed-1 );
 
124
        }
 
125
    }
 
126
 
 
127
    // Values now contains all used values without empty gaps.
 
128
    // nUsed contains their number, so values[nUsed-1] is the last value.
 
129
 
 
130
    if( nUsed ){
 
131
        // store some values
 
132
        stats[ KDChartParams::MaxValue  ] = values[nUsed-1];
 
133
        stats[ KDChartParams::MinValue  ] = values[0];
 
134
 
 
135
        stats[ KDChartParams::MeanValue ] = sum / nUsed;
 
136
        // calculate statistics
 
137
        bool bOdd = 1 == nUsed % 2;
 
138
        // find median
 
139
        int nUd2 = nUsed/2;
 
140
        if( bOdd )
 
141
            stats[ KDChartParams::Median ] = values[ nUd2 ];
 
142
        else
 
143
            stats[ KDChartParams::Median ] =
 
144
                (values[ QMAX(nUd2-1, 0) ] + values[ nUd2 ]) /2;
 
145
        // find last value of lower quartile
 
146
        nLastQ1  = QMAX( nUd2-1, 0 );
 
147
        // find 1st value of lower quartile
 
148
        nFirstQ1 = nLastQ1 / 2;
 
149
 
 
150
        // determine how many values are below the median ( == how many are above it)
 
151
        int nLowerCount = nLastQ1 - nFirstQ1 + 1;
 
152
 
 
153
        // find 1st value of upper quartile
 
154
        nFirstQ3 = bOdd ? QMIN( nUd2+1, nUsed-1 ) : nUd2;
 
155
        // find last value of upper quartile
 
156
        nLastQ3  = nFirstQ3 + nLowerCount - 1;
 
157
 
 
158
        // find quartiles
 
159
        bool bOdd2 = 1 == nLowerCount % 2;
 
160
        // find lower quartile
 
161
        if( bOdd2 )
 
162
            stats[ KDChartParams::Quartile1 ] = values[ nFirstQ1 ];
 
163
        else
 
164
            stats[ KDChartParams::Quartile1 ] =
 
165
                (values[ QMAX(nFirstQ1-1, 0) ] + values[ nFirstQ1 ]) /2;
 
166
        // find upper quartile
 
167
        if( bOdd2 ){
 
168
            stats[ KDChartParams::Quartile3 ] = values[ nLastQ3 ];
 
169
}
 
170
        else{
 
171
            //qDebug("  "+QString::number(nLastQ3)+"  "+QString::number(KDChartParams::Quartile3)
 
172
            //      +"  "+QString::number(nUsed)+"  "+QString::number(QMIN(nLastQ3+1, nUsed-1)));
 
173
            stats[ KDChartParams::Quartile3 ] =
 
174
                (values[ nLastQ3 ] + values[ QMIN(nLastQ3+1, nUsed-1) ]) /2;
 
175
}
 
176
        // find the interquartile range (IQR)
 
177
        double iqr = stats[ KDChartParams::Quartile3 ] - stats[ KDChartParams::Quartile1 ];
 
178
 
 
179
        // calculate the fences
 
180
        double upperInner, lowerInner, upperOuter, lowerOuter;
 
181
        params()->bWChartFences( upperInner, lowerInner,
 
182
                upperOuter, lowerOuter );
 
183
        stats[ KDChartParams::UpperInnerFence ] =
 
184
            stats[ KDChartParams::Quartile3 ] + iqr * upperInner;
 
185
        stats[ KDChartParams::LowerInnerFence ] =
 
186
            stats[ KDChartParams::Quartile1 ] - iqr * lowerInner;
 
187
        stats[ KDChartParams::UpperOuterFence ] =
 
188
            stats[ KDChartParams::Quartile3 ] + iqr * upperOuter;
 
189
        stats[ KDChartParams::LowerOuterFence ] =
 
190
            stats[ KDChartParams::Quartile1 ] - iqr * lowerOuter;
 
191
    }
 
192
    return nUsed;
 
193
}
 
194
 
 
195
 
 
196
/**
 
197
  This method is a specialization that returns a fallback legend text
 
198
  appropriate for BW that do not have the same notion of a dataset like
 
199
  e.g. bars.
 
200
 
 
201
  This method is only used when automatic legends are used, because
 
202
  manual and first-column legends do not need fallback texts.
 
203
 
 
204
  \param uint dataset the dataset number for which to generate a
 
205
  fallback text
 
206
  \return the fallback text to use for describing the specified
 
207
  dataset in the legend
 
208
  */
 
209
QString KDChartBWPainter::fallbackLegendText( uint dataset ) const
 
210
{
 
211
    return QObject::tr( "Series " ) + QString::number( dataset + 1 );
 
212
}
 
213
 
 
214
 
 
215
/**
 
216
  This methods returns the number of elements to be shown in the
 
217
  legend in case fallback texts are used.
 
218
 
 
219
  This method is only used when automatic legends are used, because
 
220
  manual and first-column legends do not need fallback texts.
 
221
 
 
222
  \return the number of fallback texts to use
 
223
  */
 
224
uint KDChartBWPainter::numLegendFallbackTexts( KDChartTableDataBase* data ) const
 
225
{
 
226
    return data->usedRows();
 
227
}
 
228
 
 
229
 
 
230
bool KDChartBWPainter::isNormalMode() const
 
231
{
 
232
    return KDChartParams::BWNormal == params()->bWChartSubType();
 
233
}
 
234
 
 
235
int KDChartBWPainter::clipShiftUp( bool, double ) const
 
236
{
 
237
    return 0;
 
238
}
 
239
 
 
240
/**
 
241
  Paints the actual data area and registers the region for the data
 
242
  points if \a regions is not 0.
 
243
 
 
244
  \param painter the QPainter onto which the chart should be painted
 
245
  \param data the data that will be displayed as a chart
 
246
  \param paint2nd specifies whether the main chart or the additional chart is to be drawn now
 
247
  \param regions a pointer to a list of regions that will be filled
 
248
  with regions representing the data segments, if not null
 
249
  */
 
250
void KDChartBWPainter::specificPaintData( QPainter* painter,
 
251
        const QRect& ourClipRect,
 
252
        KDChartTableDataBase* data,
 
253
        KDChartDataRegionList* /*regions*/,
 
254
        const KDChartAxisParams* axisPara,
 
255
        bool /*bNormalMode*/,
 
256
        uint /*chart*/,
 
257
        double logWidth,
 
258
        double /*areaWidthP1000*/,
 
259
        double logHeight,
 
260
        double /*axisYOffset*/,
 
261
        double /*minColumnValue*/,
 
262
        double /*maxColumnValue*/,
 
263
        double /*columnValueDistance*/,
 
264
        uint chartDatasetStart,
 
265
        uint chartDatasetEnd,
 
266
        uint datasetStart,
 
267
        uint datasetEnd )
 
268
{
 
269
    //double areaHeightP1000 = logHeight / 1000.0;
 
270
 
 
271
    uint datasetNum = ( chartDatasetEnd - chartDatasetStart ) + 1;
 
272
 
 
273
    double pixelsPerUnit = 0.0;
 
274
    if( 0.0 != axisPara->trueAxisHigh() - axisPara->trueAxisLow() )
 
275
        pixelsPerUnit = logHeight / (axisPara->trueAxisHigh() - axisPara->trueAxisLow());
 
276
    else
 
277
        pixelsPerUnit = logHeight / 10;
 
278
 
 
279
    // Distance between the individual "stocks"
 
280
    double pointDist = logWidth / ( ( double ) datasetNum );
 
281
 
 
282
    // compute the position of the 0 axis
 
283
    double zeroXAxisI = axisPara->axisZeroLineStartY() - _dataRect.y();
 
284
 
 
285
    const int lineWidth   = static_cast<int>( pointDist / 66.0 ) * QMAX(params()->lineWidth(), 1);
 
286
    const int lineWidthD2 = lineWidth * 2 / 3;
 
287
 
 
288
    const bool noBrush = Qt::NoBrush == params()->bWChartBrush().style();
 
289
 
 
290
    // Loop over the datasets, draw one box and whisker shape for each series.
 
291
    for ( uint dataset  = chartDatasetStart;
 
292
            dataset <= chartDatasetEnd;
 
293
            ++dataset ) {
 
294
 
 
295
        if( dataset >= datasetStart &&
 
296
                dataset <= datasetEnd &&
 
297
                0 < calculateStats( *data, dataset ) ) {
 
298
            const QColor color( params()->dataColor( dataset ) );
 
299
            // transform calculated values
 
300
            double drawUOF = stats[ KDChartParams::UpperOuterFence ] * pixelsPerUnit;
 
301
            double drawUIF = stats[ KDChartParams::UpperInnerFence ] * pixelsPerUnit;
 
302
            double drawQu3 = stats[ KDChartParams::Quartile3       ] * pixelsPerUnit;
 
303
            double drawMed = stats[ KDChartParams::Median          ] * pixelsPerUnit;
 
304
            double drawQu1 = stats[ KDChartParams::Quartile1       ] * pixelsPerUnit;
 
305
            double drawLIF = stats[ KDChartParams::LowerInnerFence ] * pixelsPerUnit;
 
306
            double drawLOF = stats[ KDChartParams::LowerOuterFence ] * pixelsPerUnit;
 
307
            double drawMax = stats[ KDChartParams::MaxValue        ] * pixelsPerUnit;
 
308
            double drawMin = stats[ KDChartParams::MinValue        ] * pixelsPerUnit;
 
309
            double drawMean= stats[ KDChartParams::MeanValue       ] * pixelsPerUnit;
 
310
            // get whisker values
 
311
            double drawUWhisker = QMIN(drawUIF, drawMax);
 
312
            double drawLWhisker = QMAX(drawLIF, drawMin);
 
313
            // get the box width
 
314
            const int boxWidth = QMAX( 6, static_cast<int>( pointDist * 0.2 ) );
 
315
            // get marker size (for the outliers and/or for the median value)
 
316
            int markWidth = params()->bWChartOutValMarkerSize();
 
317
            bool drawOutliers = ( 0 != markWidth );
 
318
            if( drawOutliers ){
 
319
                if( 0 > markWidth)
 
320
                    markWidth = QMAX( 4, markWidth * boxWidth / -100 );
 
321
                else
 
322
                    markWidth = QMAX( 4, markWidth );
 
323
            }
 
324
            else
 
325
                markWidth = boxWidth * 25 / 100; // use the default for the Median marker
 
326
 
 
327
            painter->setPen( QPen( color, lineWidth ) );
 
328
            painter->setBrush( params()->bWChartBrush() );
 
329
            // draw the box
 
330
            int boxWidthD2 = boxWidth / 2;
 
331
            int xPos = static_cast<int>(
 
332
                    pointDist * ( (double)(dataset - chartDatasetStart) + 0.5 )
 
333
                    - lineWidth / 2);
 
334
            painter->drawRect( xPos - boxWidthD2,
 
335
                    static_cast<int>( zeroXAxisI - drawQu3 ),
 
336
                    boxWidth,
 
337
                    static_cast<int>( drawQu3 - drawQu1) + 1 );
 
338
            // draw the median
 
339
            painter->drawLine( xPos - boxWidthD2,
 
340
                    static_cast<int>( zeroXAxisI - drawMed ),
 
341
                    xPos - boxWidthD2 + boxWidth,
 
342
                    static_cast<int>( zeroXAxisI - drawMed ) );
 
343
            // draw the whisker
 
344
            painter->drawLine( xPos - boxWidthD2,
 
345
                    static_cast<int>( zeroXAxisI - drawUWhisker ),
 
346
                    xPos - boxWidthD2 + boxWidth,
 
347
                    static_cast<int>( zeroXAxisI - drawUWhisker ) );
 
348
            painter->drawLine( xPos,
 
349
                    static_cast<int>( zeroXAxisI - drawUWhisker ),
 
350
                    xPos,
 
351
                    static_cast<int>( zeroXAxisI - drawQu3 ) );
 
352
            painter->drawLine( xPos - boxWidthD2,
 
353
                    static_cast<int>( zeroXAxisI - drawLWhisker ),
 
354
                    xPos - boxWidthD2 + boxWidth,
 
355
                    static_cast<int>( zeroXAxisI - drawLWhisker ) );
 
356
            painter->drawLine( xPos,
 
357
                    static_cast<int>( zeroXAxisI - drawLWhisker ),
 
358
                    xPos,
 
359
                    static_cast<int>( zeroXAxisI - drawQu1 ) );
 
360
            // draw the values
 
361
            int xPos2 = static_cast<int>(
 
362
                    pointDist * ( (double)(dataset - chartDatasetStart) + 0.5 )
 
363
                    - lineWidthD2 / 2);
 
364
            int markWidthD2 =  QMAX(markWidth / 2, 2);
 
365
            int markWidthD25 = QMAX(static_cast<int>( 0.85 * markWidth / 2.0), 2);
 
366
            int markWidthD35 = QMAX(static_cast<int>( 0.85 * markWidth / 3.0), 2);
 
367
            // draw the outliers
 
368
            if( drawOutliers ){
 
369
                const uint nMax = data->usedCols();
 
370
                int drawVal;
 
371
                for( uint i=0; i<nMax; ++i)
 
372
                    if( data->cell(dataset, i).isDouble(1) ) {
 
373
                        drawVal = static_cast<int>( pixelsPerUnit *
 
374
                                data->cell(dataset, i).doubleValue(1) );
 
375
                        if( drawLOF > drawVal || drawUOF < drawVal ) {
 
376
                            painter->setPen( Qt::NoPen );
 
377
                            painter->drawChord( xPos2 - markWidthD2,
 
378
                                    static_cast<int>(zeroXAxisI - drawVal) - markWidthD2,
 
379
                                    markWidth,
 
380
                                    markWidth,
 
381
                                    0, 5760 );
 
382
                            painter->setPen( QPen( color, lineWidthD2 ) );
 
383
                            painter->drawArc( xPos2 - markWidthD2,
 
384
                                    static_cast<int>(zeroXAxisI - drawVal) - markWidthD2,
 
385
                                    markWidth,
 
386
                                    markWidth,
 
387
                                    0, 5760 );
 
388
                        } else if( drawLIF > drawVal || drawUIF < drawVal ) {
 
389
                            painter->setPen( Qt::NoPen );
 
390
                            painter->drawChord( xPos2 - markWidthD2,
 
391
                                    static_cast<int>( zeroXAxisI - drawVal) - markWidthD2,
 
392
                                    markWidth,
 
393
                                    markWidth,
 
394
                                    0, 5760 );
 
395
                            painter->setPen( QPen( color, lineWidthD2 ) );
 
396
                            painter->drawLine( xPos2,
 
397
                                    static_cast<int>(zeroXAxisI - drawVal) - markWidthD2,
 
398
                                    xPos2,
 
399
                                    static_cast<int>(zeroXAxisI - drawVal) + markWidthD2 );
 
400
                            painter->drawLine( xPos2 - markWidthD25,
 
401
                                    static_cast<int>(zeroXAxisI - drawVal) - markWidthD35,
 
402
                                    xPos2 + markWidthD25,
 
403
                                    static_cast<int>(zeroXAxisI - drawVal) + markWidthD35 );
 
404
                            painter->drawLine( xPos2 + markWidthD25,
 
405
                                    static_cast<int>(zeroXAxisI - drawVal) - markWidthD35,
 
406
                                    xPos2 - markWidthD25,
 
407
                                    static_cast<int>(zeroXAxisI - drawVal) + markWidthD35 );
 
408
                        }
 
409
                    }
 
410
            }
 
411
            // draw the mean value
 
412
            bool evenLineWidthD2 = floor( ((double)lineWidthD2)/2.0 ) == ((double)lineWidthD2)/2.0;
 
413
            painter->setPen( params()->bWChartBrush().color() );
 
414
            painter->drawChord( xPos2 - markWidthD2-1 - (evenLineWidthD2 ? 0 : 1),
 
415
                    static_cast<int>( zeroXAxisI - drawMean ) - markWidthD2 - 1,
 
416
                    markWidthD2*2 + (evenLineWidthD2 ? 2 : 3),
 
417
                    markWidthD2*2 + (evenLineWidthD2 ? 2 : 3),
 
418
                    0, 5760 );
 
419
            if( noBrush ) {
 
420
                // use different color brightness for the Mean marker
 
421
                int h,s,v;
 
422
                color.hsv(&h,&s,&v);
 
423
                painter->setPen( QPen( 128 > v ? color.light(150) : color.dark(150),
 
424
                            lineWidthD2 ) );
 
425
            } else
 
426
                painter->setPen( QPen( color, lineWidthD2 ) );
 
427
            painter->drawLine( xPos2 - markWidthD2 - (evenLineWidthD2 ? 0 : 1),
 
428
                               static_cast<int>( zeroXAxisI - drawMean ),
 
429
                               xPos2 + markWidthD2,
 
430
                               static_cast<int>( zeroXAxisI - drawMean ) );
 
431
            painter->drawLine( xPos2 - (evenLineWidthD2 ? 0 : 1),
 
432
                               static_cast<int>( zeroXAxisI - drawMean ) - markWidthD2,
 
433
                               xPos2 - (evenLineWidthD2 ? 0 : 1),
 
434
                               static_cast<int>( zeroXAxisI - drawMean ) + markWidthD2 + (evenLineWidthD2 ? 0 : 1) );
 
435
 
 
436
            // draw the statistical value texts
 
437
            painter->setPen( Qt::NoPen );
 
438
            for( int ii =  KDChartParams::BWStatValSTART;
 
439
                    ii <= KDChartParams::BWStatValEND;
 
440
                    ++ii ){
 
441
                KDChartParams::BWStatVal i = (KDChartParams::BWStatVal)ii;
 
442
                if( params()->bWChartPrintStatistics( i ) ) {
 
443
                    QFont statFont( params()->bWChartStatisticsFont( i ) );
 
444
                    float nTxtHeight = statFont.pointSizeFloat();
 
445
                    if ( params()->bWChartStatisticsUseRelSize( i ) ) {
 
446
                        nTxtHeight = params()->bWChartStatisticsFontRelSize( i )
 
447
                            * boxWidth / 100;
 
448
                        statFont.setPointSizeFloat( nTxtHeight );
 
449
                    }
 
450
                    double drawStat = pixelsPerUnit * stats[i];
 
451
                    KDChartTextPiece statText( QString::number( stats[i] ),
 
452
                            statFont );
 
453
                    int tw = statText.width();
 
454
                    int xDelta = (    KDChartParams::MaxValue  == i
 
455
                            || KDChartParams::MeanValue == i
 
456
                            || KDChartParams::MinValue  == i )
 
457
                        ? -1 * (tw + static_cast<int>( 1.3*boxWidthD2 ))
 
458
                        : static_cast<int>( 1.3*boxWidthD2 );
 
459
                    QBrush brush( params()->bWChartStatisticsBrush( i ) );
 
460
                    painter->setBrush( brush );
 
461
                    int y = static_cast<int>( zeroXAxisI - drawStat - nTxtHeight/2);
 
462
                    painter->drawRect( xPos + xDelta - 1,
 
463
                            y,
 
464
                            tw + 2,
 
465
                                       static_cast<int>( QMAX(nTxtHeight, 8) + 1 ) );
 
466
                    statText.draw( painter,
 
467
                            xPos + xDelta,
 
468
                            y,
 
469
                            ourClipRect,
 
470
                            params()->bWChartStatisticsColor( i ),
 
471
                            0 );
 
472
                }
 
473
            }
 
474
 
 
475
        } else
 
476
            continue; // we cannot display this value
 
477
    }
 
478
}