~ubuntu-branches/ubuntu/oneiric/koffice/oneiric-updates

« back to all changes in this revision

Viewing changes to kchart/kdchart/src/LeveyJennings/KDChartLeveyJenningsAxis.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/****************************************************************************
2
 
 ** Copyright (C) 2007 Klarävdalens Datakonsult AB.  All rights reserved.
3
 
 **
4
 
 ** This file is part of the KD Chart library.
5
 
 **
6
 
 ** This file may be used under the terms of the GNU General Public
7
 
 ** License versions 2.0 or 3.0 as published by the Free Software
8
 
 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
9
 
 ** included in the packaging of this file.  Alternatively you may (at
10
 
 ** your option) use any later version of the GNU General Public
11
 
 ** License if such license has been publicly approved by
12
 
 ** Klarälvdalens Datakonsult AB (or its successors, if any).
13
 
 ** 
14
 
 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
15
 
 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
16
 
 ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
17
 
 ** not expressly granted herein.
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
 
 **********************************************************************/
23
 
 
24
 
#include "KDChartLeveyJenningsAxis.h"
25
 
#include "KDChartLeveyJenningsAxis_p.h"
26
 
 
27
 
#include <QDateTime>
28
 
#include <QPainter>
29
 
 
30
 
#include "KDChartPaintContext.h"
31
 
#include "KDChartChart.h"
32
 
#include "KDChartAbstractCartesianDiagram.h"
33
 
#include "KDChartAbstractGrid.h"
34
 
#include "KDChartPainterSaver_p.h"
35
 
#include "KDChartLayoutItems.h"
36
 
#include "KDChartPrintingParameters.h"
37
 
 
38
 
#include <KDABLibFakes>
39
 
 
40
 
#include <limits>
41
 
 
42
 
using namespace KDChart;
43
 
 
44
 
#define d (d_func())
45
 
 
46
 
LeveyJenningsAxis::LeveyJenningsAxis ( LeveyJenningsDiagram* diagram )
47
 
    : CartesianAxis ( new Private( diagram, this ), diagram )
48
 
{
49
 
    init();
50
 
}
51
 
 
52
 
LeveyJenningsAxis::~LeveyJenningsAxis ()
53
 
{
54
 
    // when we remove the first axis it will unregister itself and
55
 
    // propagate the next one to the primary, thus the while loop
56
 
    while ( d->mDiagram ) {
57
 
        LeveyJenningsDiagram *cd = qobject_cast< LeveyJenningsDiagram* >( d->mDiagram );
58
 
        cd->takeAxis( this );
59
 
    }
60
 
    Q_FOREACH( AbstractDiagram *diagram, d->secondaryDiagrams ) {
61
 
        LeveyJenningsDiagram *cd = qobject_cast< LeveyJenningsDiagram* >( diagram );
62
 
        cd->takeAxis( this );
63
 
    }
64
 
}
65
 
 
66
 
void LeveyJenningsAxis::init ()
67
 
{
68
 
    setType( LeveyJenningsGridAttributes::Expected );
69
 
    setDateFormat( Qt::TextDate );
70
 
    const QStringList labels = QStringList() << tr( "-3sd" ) << tr( "-2sd" ) << tr( "mean" )
71
 
                                             << tr( "+2sd" ) << tr( "+3sd" );
72
 
 
73
 
    setLabels( labels );
74
 
}
75
 
 
76
 
/**
77
 
  * @return The axis' type.
78
 
  */
79
 
LeveyJenningsGridAttributes::GridType LeveyJenningsAxis::type() const
80
 
{
81
 
    return d->type;
82
 
}
83
 
 
84
 
/**
85
 
  * Sets the type of the axis to \a type.
86
 
  * This method colors the label to the default color of the
87
 
  * respective type.
88
 
  * Please make sure to re-set the colors after calling this,
89
 
  * if you want them different.
90
 
  * Setting the type is only valid for axes located right or left
91
 
  * from the diagram. An axis on the bottom always shows the timeline.
92
 
  */
93
 
void LeveyJenningsAxis::setType( LeveyJenningsGridAttributes::GridType type )
94
 
{
95
 
    if( type != d->type )
96
 
    {
97
 
        TextAttributes ta = textAttributes();
98
 
        QPen pen = ta.pen();
99
 
        QColor color = type == LeveyJenningsGridAttributes::Expected ? Qt::black : Qt::blue;
100
 
        if( qobject_cast< const LeveyJenningsDiagram* >( d->diagram() ) && 
101
 
            qobject_cast< const LeveyJenningsCoordinatePlane* >( d->diagram()->coordinatePlane() ) )
102
 
        {
103
 
            color = qobject_cast< const LeveyJenningsCoordinatePlane* >( d->diagram()->coordinatePlane() )->gridAttributes().gridPen( type ).color();
104
 
        }
105
 
        pen.setColor( color );
106
 
        ta.setPen( pen );
107
 
        setTextAttributes( ta );
108
 
    }
109
 
    d->type = type;
110
 
}
111
 
 
112
 
Qt::DateFormat LeveyJenningsAxis::dateFormat() const
113
 
{
114
 
    return d->format;
115
 
}
116
 
 
117
 
void LeveyJenningsAxis::setDateFormat(Qt::DateFormat format)
118
 
{
119
 
    d->format = format;
120
 
}
121
 
 
122
 
bool LeveyJenningsAxis::compare( const LeveyJenningsAxis* other )const
123
 
{
124
 
    if( other == this ) return true;
125
 
    if( ! other ){
126
 
        //qDebug() << "CartesianAxis::compare() cannot compare to Null pointer";
127
 
        return false;
128
 
    }
129
 
    return  ( static_cast<const CartesianAxis*>(this)->compare( other ) ) &&
130
 
            ( type() == other->type() );
131
 
}
132
 
 
133
 
void LeveyJenningsAxis::paintCtx( PaintContext* context )
134
 
{
135
 
 
136
 
    Q_ASSERT_X ( d->diagram(), "LeveyJenningsAxis::paint",
137
 
                 "Function call not allowed: The axis is not assigned to any diagram." );
138
 
 
139
 
    LeveyJenningsCoordinatePlane* plane = dynamic_cast<LeveyJenningsCoordinatePlane*>(context->coordinatePlane());
140
 
    Q_ASSERT_X ( plane, "LeveyJenningsAxis::paint",
141
 
                 "Bad function call: PaintContext::coodinatePlane() NOT a levey jennings plane." );
142
 
 
143
 
    // note: Not having any data model assigned is no bug
144
 
    //       but we can not draw an axis then either.
145
 
    if( ! d->diagram()->model() )
146
 
        return;
147
 
 
148
 
    if( isOrdinate() )
149
 
        paintAsOrdinate( context );
150
 
    else
151
 
        paintAsAbscissa( context );
152
 
}
153
 
 
154
 
void LeveyJenningsAxis::paintAsOrdinate( PaintContext* context )
155
 
{
156
 
    const LeveyJenningsDiagram* const diag = dynamic_cast< const LeveyJenningsDiagram* >( d->diagram() );
157
 
 
158
 
    Q_ASSERT( isOrdinate() );
159
 
    LeveyJenningsCoordinatePlane* plane = dynamic_cast<LeveyJenningsCoordinatePlane*>(context->coordinatePlane());
160
 
    
161
 
    const qreal meanValue =         type() == LeveyJenningsGridAttributes::Expected ? diag->expectedMeanValue() 
162
 
                                                                                    : diag->calculatedMeanValue();
163
 
    const qreal standardDeviation = type() == LeveyJenningsGridAttributes::Expected ? diag->expectedStandardDeviation() 
164
 
                                                                                    : diag->calculatedStandardDeviation();
165
 
    const TextAttributes labelTA = textAttributes();
166
 
    const bool drawLabels = labelTA.isVisible();
167
 
 
168
 
    // nothing to draw, since we've no ticks
169
 
    if( !drawLabels )
170
 
        return;
171
 
    
172
 
    const QObject* referenceArea = plane->parent();
173
 
 
174
 
    const QVector< qreal > values = QVector< qreal >() << ( meanValue - 3 * standardDeviation )
175
 
                                                       << ( meanValue - 2 * standardDeviation )
176
 
                                                       << ( meanValue )
177
 
                                                       << ( meanValue + 2 * standardDeviation )
178
 
                                                       << ( meanValue + 3 * standardDeviation );
179
 
 
180
 
    Q_ASSERT_X( values.count() <= labels().count(), "LeveyJenningsAxis::paintAsOrdinate", "Need to have at least 5 labels" );
181
 
 
182
 
    TextLayoutItem labelItem( tr( "mean" ), 
183
 
                              labelTA,
184
 
                              referenceArea,
185
 
                              KDChartEnums::MeasureOrientationMinimum,
186
 
                              Qt::AlignLeft );
187
 
 
188
 
    QPainter* const painter = context->painter();
189
 
    const PainterSaver ps( painter );
190
 
    painter->setRenderHint( QPainter::Antialiasing, true );
191
 
    painter->setClipping( false );
192
 
    
193
 
    painter->setPen ( PrintingParameters::scalePen( labelTA.pen() ) ); // perhaps we want to add a setter method later?
194
 
 
195
 
    for( int i = 0; i < values.count(); ++i )
196
 
    {
197
 
        const QPointF labelPos = plane->translate( QPointF( 0.0, values.at( i ) ) );
198
 
        const QString label = customizedLabel( labels().at( i ) );
199
 
        labelItem.setText( label );
200
 
        const QSize size = labelItem.sizeHint();
201
 
        const float xPos = position() == Left ? geometry().right() - size.width() : geometry().left();
202
 
        labelItem.setGeometry( QRectF( QPointF( xPos, labelPos.y() - size.height() / 2.0 ), size ).toRect() );
203
 
 
204
 
        // don't draw labels which aren't in the valid range (might happen for calculated SDs)
205
 
        if( values.at( i ) > diag->expectedMeanValue() + 4 * diag->expectedStandardDeviation() )
206
 
            continue;
207
 
 
208
 
        if( values.at( i ) < diag->expectedMeanValue() - 4 * diag->expectedStandardDeviation() )
209
 
            continue;
210
 
 
211
 
        labelItem.paint( painter );
212
 
    }    
213
 
}
214
 
 
215
 
void LeveyJenningsAxis::paintAsAbscissa( PaintContext* context )
216
 
{
217
 
    Q_ASSERT( isAbscissa() );
218
 
 
219
 
    // this triggers drawing of the ticks
220
 
    setLabels( QStringList() << QString::fromLatin1( " " ) );
221
 
    CartesianAxis::paintCtx( context );
222
 
 
223
 
    const LeveyJenningsDiagram* const diag = dynamic_cast< const LeveyJenningsDiagram* >( d->diagram() );
224
 
    LeveyJenningsCoordinatePlane* plane = dynamic_cast<LeveyJenningsCoordinatePlane*>(context->coordinatePlane());
225
 
 
226
 
    const QObject* referenceArea = plane->parent();
227
 
    const TextAttributes labelTA = textAttributes();
228
 
    
229
 
    const bool drawLabels = labelTA.isVisible();
230
 
 
231
 
    if( !drawLabels )
232
 
        return;
233
 
 
234
 
 
235
 
    const QPair< QDateTime, QDateTime > range = diag->timeRange();
236
 
 
237
 
    QPainter* const painter = context->painter();
238
 
    const PainterSaver ps( painter );
239
 
    painter->setRenderHint( QPainter::Antialiasing, true );
240
 
    painter->setClipping( false );
241
 
     
242
 
 
243
 
    TextLayoutItem labelItem( range.first.date().toString( dateFormat() ), 
244
 
                              labelTA,
245
 
                              referenceArea,
246
 
                              KDChartEnums::MeasureOrientationMinimum,
247
 
                              Qt::AlignLeft );
248
 
    QSize origSize = labelItem.sizeHint();
249
 
    if( range.first.secsTo( range.second ) < 86400 )
250
 
        labelItem = TextLayoutItem( range.first.toString( dateFormat() ), 
251
 
                                  labelTA,
252
 
                                  referenceArea,
253
 
                                  KDChartEnums::MeasureOrientationMinimum,
254
 
                                  Qt::AlignLeft );
255
 
    QSize size = labelItem.sizeHint();
256
 
 
257
 
    float yPos = position() == Bottom ? geometry().bottom() - size.height() : geometry().top();
258
 
    labelItem.setGeometry( QRectF( QPointF( geometry().left() - origSize.width() / 2.0, yPos ), size ).toRect() );
259
 
    labelItem.paint( painter );
260
 
 
261
 
    
262
 
    TextLayoutItem labelItem2( range.second.date().toString( dateFormat() ), 
263
 
                              labelTA,
264
 
                              referenceArea,
265
 
                              KDChartEnums::MeasureOrientationMinimum,
266
 
                              Qt::AlignLeft );
267
 
    origSize = labelItem2.sizeHint();
268
 
    if( range.first.secsTo( range.second ) < 86400 )
269
 
        labelItem2 = TextLayoutItem( range.second.toString( dateFormat() ), 
270
 
                                     labelTA,
271
 
                                     referenceArea,
272
 
                                     KDChartEnums::MeasureOrientationMinimum,
273
 
                                     Qt::AlignLeft );
274
 
    size = labelItem2.sizeHint();
275
 
    yPos = position() == Bottom ? geometry().bottom() - size.height() : geometry().top();
276
 
    labelItem2.setGeometry( QRectF( QPointF( geometry().right() - size.width() + origSize.width() / 2.0, yPos ), size ).toRect() );
277
 
    labelItem2.paint( painter );
278
 
}