~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to kchart/kdchart/src/KDChartPlotter_p.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
 
/* -*- Mode: C++ -*-
2
 
   KDChart - a multi-platform charting engine
3
 
   */
4
 
 
5
 
/****************************************************************************
6
 
 ** Copyright (C) 2005-2007 Klarälvdalens Datakonsult AB.  All rights reserved.
7
 
 **
8
 
 ** This file is part of the KD Chart library.
9
 
 **
10
 
 ** This file may be used under the terms of the GNU General Public
11
 
 ** License versions 2.0 or 3.0 as published by the Free Software
12
 
 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
13
 
 ** included in the packaging of this file.  Alternatively you may (at
14
 
 ** your option) use any later version of the GNU General Public
15
 
 ** License if such license has been publicly approved by
16
 
 ** Klarälvdalens Datakonsult AB (or its successors, if any).
17
 
 ** 
18
 
 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
19
 
 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
20
 
 ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
21
 
 ** not expressly granted herein.
22
 
 ** 
23
 
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24
 
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25
 
 **
26
 
 **********************************************************************/
27
 
 
28
 
#include "KDChartPlotter_p.h"
29
 
#include "KDChartPlotter.h"
30
 
 
31
 
#include "KDChartValueTrackerAttributes.h"
32
 
 
33
 
using namespace KDChart;
34
 
 
35
 
Plotter::Private::Private( const Private& rhs )
36
 
    : AbstractCartesianDiagram::Private( rhs )
37
 
{
38
 
}
39
 
 
40
 
void Plotter::Private::setCompressorResolution(
41
 
    const QSizeF& size,
42
 
    const AbstractCoordinatePlane* plane )
43
 
{
44
 
    compressor.setResolution( static_cast<int>( size.width()  * plane->zoomFactorX() ),
45
 
                              static_cast<int>( size.height() * plane->zoomFactorY() ) );
46
 
}
47
 
 
48
 
 
49
 
void Plotter::Private::paintPolyline(
50
 
    PaintContext* ctx,
51
 
    const QBrush& brush, const QPen& pen,
52
 
    const QPolygonF& points ) const
53
 
{
54
 
    ctx->painter()->setBrush( brush );
55
 
    ctx->painter()->setPen( PrintingParameters::scalePen(
56
 
        QPen( pen.color(),
57
 
              pen.width(),
58
 
              pen.style(),
59
 
              Qt::FlatCap,
60
 
              Qt::MiterJoin ) ) );
61
 
#if QT_VERSION > 0x040299
62
 
    ctx->painter()->drawPolyline( points );
63
 
#else
64
 
    // FIXME (Mirko) verify, this sounds reverse-logical
65
 
    // For Qt versions older than 4.3 drawPolyline is VERY slow
66
 
    // so we use traditional line segments drawing instead then.
67
 
    for (int i = 0; i < points.size()-1; ++i)
68
 
        ctx->painter()->drawLine( points.at(i), points.at(i+1) );
69
 
#endif
70
 
}
71
 
 
72
 
/*!
73
 
  Projects a point in a space defined by its x, y, and z coordinates
74
 
  into a point onto a plane, given two rotation angles around the x
75
 
  resp. y axis.
76
 
*/
77
 
const QPointF Plotter::PlotterType::project(
78
 
    QPointF point, QPointF maxLimits,
79
 
    double z, const QModelIndex& index ) const
80
 
{
81
 
    Q_UNUSED( maxLimits );
82
 
    ThreeDLineAttributes td = diagram()->threeDLineAttributes( index );
83
 
 
84
 
    //Pending Michel FIXME - the rotation does not work as expected atm
85
 
    double xrad = DEGTORAD( td.lineXRotation() );
86
 
    double yrad = DEGTORAD( td.lineYRotation() );
87
 
    QPointF ret = QPointF(point.x()*cos( yrad ) + z * sin( yrad ) ,  point.y()*cos( xrad ) - z * sin( xrad ) );
88
 
    return ret;
89
 
}
90
 
 
91
 
void Plotter::PlotterType::paintThreeDLines(
92
 
    PaintContext* ctx, const QModelIndex& index,
93
 
    const QPointF& from, const QPointF& to, const double depth  )
94
 
{
95
 
    // retrieve the boundaries
96
 
    const QPair< QPointF, QPointF > boundaries = diagram()->dataBoundaries();
97
 
    const QPointF& maxLimits = boundaries.second;
98
 
    const QPointF topLeft = project( from, maxLimits, depth, index  );
99
 
    const QPointF topRight = project ( to, maxLimits, depth, index  );
100
 
 
101
 
    const QPolygonF segment = QPolygonF() << from << topLeft << topRight << to;
102
 
    const QBrush indexBrush ( diagram()->brush( index ) );
103
 
    const PainterSaver painterSaver( ctx->painter() );
104
 
 
105
 
    if( diagram()->antiAliasing() )
106
 
        ctx->painter()->setRenderHint( QPainter::Antialiasing );
107
 
 
108
 
    ctx->painter()->setBrush( indexBrush );
109
 
    ctx->painter()->setPen( PrintingParameters::scalePen( diagram()->pen( index ) )  );
110
 
 
111
 
    reverseMapper().addPolygon( index.row(), index.column(), segment );
112
 
    ctx->painter()->drawPolygon( segment );
113
 
}
114
 
 
115
 
// this method is factored out from LineDiagram::paint, and contains
116
 
// the common parts of the method that  previously implemented all
117
 
// chart types in one
118
 
void Plotter::PlotterType::paintElements(
119
 
    PaintContext* ctx,
120
 
    DataValueTextInfoList& list,
121
 
    LineAttributesInfoList& lineList,
122
 
    LineAttributes::MissingValuesPolicy policy )
123
 
{
124
 
    Q_UNUSED( policy );
125
 
    // paint all lines and their attributes
126
 
    PainterSaver painterSaver( ctx->painter() );
127
 
    if ( diagram()->antiAliasing() )
128
 
        ctx->painter()->setRenderHint ( QPainter::Antialiasing );
129
 
    LineAttributesInfoListIterator itline ( lineList );
130
 
 
131
 
    QBrush curBrush;
132
 
    QPen curPen;
133
 
    QPolygonF points;
134
 
    while ( itline.hasNext() ) {
135
 
        const LineAttributesInfo& lineInfo = itline.next();
136
 
        const QModelIndex& index = lineInfo.index;
137
 
        const ThreeDLineAttributes td = diagram()->threeDLineAttributes( index );
138
 
        const ValueTrackerAttributes vt = diagram()->valueTrackerAttributes( index );
139
 
 
140
 
        if( td.isEnabled() ){
141
 
            paintThreeDLines( ctx, index, lineInfo.value, lineInfo.nextValue, td.depth() );
142
 
        } else {
143
 
            const QBrush br( diagram()->brush( index ) );
144
 
            const QPen pn( diagram()->pen( index ) );
145
 
            if( points.count() && points.last() == lineInfo.value && curBrush == br && curPen == pn ) {
146
 
                // line goes from last value in points to lineInfo.nextValue
147
 
                reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), points.last(), lineInfo.nextValue );
148
 
                points << lineInfo.nextValue;
149
 
            } else {
150
 
                if( points.count() )
151
 
                    paintPolyline( ctx, curBrush, curPen, points );
152
 
                curBrush = br;
153
 
                curPen   = pn;
154
 
                points.clear();
155
 
                // line goes from lineInfo.value to lineInfo,nextValue
156
 
                reverseMapper().addLine( lineInfo.index.row(), lineInfo.index.column(), lineInfo.value, lineInfo.nextValue );
157
 
                points << lineInfo.value << lineInfo.nextValue;
158
 
            }
159
 
        }
160
 
 
161
 
        if( vt.isEnabled() )
162
 
            paintValueTracker( ctx, vt, lineInfo.value );
163
 
    }
164
 
    if( points.count() )
165
 
        paintPolyline( ctx, curBrush, curPen, points );
166
 
    // paint all data value texts and the point markers
167
 
    paintDataValueTextsAndMarkers( diagram(), ctx, list, true );
168
 
}
169
 
 
170
 
AttributesModel* Plotter::PlotterType::attributesModel() const
171
 
{
172
 
    return m_private->attributesModel;
173
 
}
174
 
 
175
 
#if 0
176
 
QModelIndex LineDiagram::LineDiagramType::attributesModelRootIndex() const
177
 
{
178
 
    return m_private->diagram->attributesModelRootIndex();
179
 
}
180
 
 
181
 
int LineDiagram::LineDiagramType::datasetDimension() const
182
 
{
183
 
    return m_private->datasetDimension;
184
 
}
185
 
#endif
186
 
 
187
 
ReverseMapper& Plotter::PlotterType::reverseMapper()
188
 
{
189
 
    return m_private->reverseMapper;
190
 
}
191
 
 
192
 
#if 0
193
 
LineAttributes::MissingValuesPolicy LineDiagram::LineDiagramType::getCellValues(
194
 
    int row, int column,
195
 
    bool shiftCountedXValuesByHalfSection,
196
 
    double& valueX, double& valueY ) const
197
 
{
198
 
    return m_private->diagram->getCellValues( row, column, shiftCountedXValuesByHalfSection,
199
 
                                              valueX, valueY );
200
 
}
201
 
 
202
 
double LineDiagram::LineDiagramType::valueForCellTesting(
203
 
    int row, int column,
204
 
    bool& bOK,
205
 
    bool showHiddenCellsAsInvalid) const
206
 
{
207
 
    return m_private->diagram->valueForCellTesting( row, column, bOK, showHiddenCellsAsInvalid );
208
 
}
209
 
#endif
210
 
 
211
 
Plotter* Plotter::PlotterType::diagram() const
212
 
{
213
 
    return m_private->diagram;
214
 
}
215
 
 
216
 
void Plotter::PlotterType::paintAreas(
217
 
    PaintContext* ctx,
218
 
    const QModelIndex& index, const QList< QPolygonF >& areas,
219
 
    const uint transparency )
220
 
{
221
 
    QColor trans = diagram()->brush( index ).color();
222
 
    trans.setAlpha( transparency );
223
 
    QPen indexPen = diagram()->pen(index);
224
 
    indexPen.setColor( trans );
225
 
    const PainterSaver painterSaver( ctx->painter() );
226
 
 
227
 
    if( diagram()->antiAliasing() )
228
 
        ctx->painter()->setRenderHint( QPainter::Antialiasing );
229
 
 
230
 
    ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
231
 
    ctx->painter()->setBrush( trans );
232
 
 
233
 
    QPainterPath path;
234
 
    for( int i = 0; i < areas.count(); ++i )
235
 
    {
236
 
        const QPolygonF& p = areas[ i ];
237
 
        path.addPolygon( p );
238
 
        reverseMapper().addPolygon( index.row(), index.column(), p );
239
 
        path.closeSubpath();
240
 
    }
241
 
    ctx->painter()->drawPath( path );
242
 
}
243
 
 
244
 
#if 0
245
 
double LineDiagram::LineDiagramType::valueForCell( int row, int column )
246
 
{
247
 
    return diagram()->valueForCell( row, column );
248
 
}
249
 
#endif
250
 
 
251
 
void Plotter::PlotterType::appendDataValueTextInfoToList(
252
 
            AbstractDiagram * diagram,
253
 
            DataValueTextInfoList & list,
254
 
            const QModelIndex & index,
255
 
            const PositionPoints& points,
256
 
            const Position& autoPositionPositive,
257
 
            const Position& autoPositionNegative,
258
 
            const qreal value )
259
 
{
260
 
    Q_UNUSED( autoPositionNegative );
261
 
    m_private->appendDataValueTextInfoToList(
262
 
                    diagram, list, index, 0,
263
 
                    points, autoPositionPositive, autoPositionPositive, value );
264
 
}
265
 
 
266
 
void Plotter::PlotterType::paintValueTracker( PaintContext* ctx, const ValueTrackerAttributes& vt, const QPointF& at )
267
 
{
268
 
    CartesianCoordinatePlane* plane = qobject_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() );
269
 
    if( !plane )
270
 
        return;
271
 
 
272
 
    DataDimensionsList gridDimensions = ctx->coordinatePlane()->gridDimensionsList();
273
 
    const QPointF bottomLeft( ctx->coordinatePlane()->translate(
274
 
                              QPointF( plane->isHorizontalRangeReversed() ?
275
 
                                           gridDimensions.at( 0 ).end :
276
 
                                           gridDimensions.at( 0 ).start,
277
 
                                       plane->isVerticalRangeReversed() ?
278
 
                                           gridDimensions.at( 1 ).end :
279
 
                                           gridDimensions.at( 1 ).start ) ) );
280
 
    const QPointF markerPoint = at;
281
 
    const QPointF ordinatePoint( bottomLeft.x(), at.y() );
282
 
    const QPointF abscissaPoint( at.x(), bottomLeft.y() );
283
 
 
284
 
    const QSizeF markerSize = vt.markerSize();
285
 
    const QRectF ellipseMarker = QRectF( at.x() - markerSize.width() / 2,
286
 
                                         at.y() - markerSize.height() / 2,
287
 
                                         markerSize.width(), markerSize.height() );
288
 
 
289
 
    const QPointF ordinateMarker[3] = {
290
 
        QPointF( ordinatePoint.x(), at.y() + markerSize.height() / 2 ),
291
 
        QPointF( ordinatePoint.x() + markerSize.width() / 2, at.y() ),
292
 
        QPointF( ordinatePoint.x(), at.y() - markerSize.height() / 2 )
293
 
    };
294
 
 
295
 
    const QPointF abscissaMarker[3] = {
296
 
        QPointF( at.x() + markerSize.width() / 2, abscissaPoint.y() ),
297
 
        QPointF( at.x(), abscissaPoint.y() - markerSize.height() / 2 ),
298
 
        QPointF( at.x() - markerSize.width() / 2, abscissaPoint.y() )
299
 
    };
300
 
 
301
 
    QPointF topLeft = ordinatePoint;
302
 
    QPointF bottomRightOffset = abscissaPoint - topLeft;
303
 
    QSizeF size( bottomRightOffset.x(), bottomRightOffset.y() );
304
 
    QRectF area( topLeft, size );
305
 
 
306
 
    PainterSaver painterSaver( ctx->painter() );
307
 
    ctx->painter()->setPen( PrintingParameters::scalePen( vt.pen() ) );
308
 
    ctx->painter()->setBrush( QBrush() );
309
 
 
310
 
    ctx->painter()->drawLine( markerPoint, ordinatePoint );
311
 
    ctx->painter()->drawLine( markerPoint, abscissaPoint );
312
 
 
313
 
    ctx->painter()->fillRect( area, vt.areaBrush() );
314
 
 
315
 
    ctx->painter()->drawEllipse( ellipseMarker );
316
 
 
317
 
    ctx->painter()->setBrush( vt.pen().color() );
318
 
    ctx->painter()->drawPolygon( ordinateMarker, 3 );
319
 
    ctx->painter()->drawPolygon( abscissaMarker, 3 );
320
 
}
321
 
 
322
 
CartesianDiagramDataCompressor& Plotter::PlotterType::compressor() const
323
 
{
324
 
    return m_private->compressor;
325
 
}