2
KDChart - a multi-platform charting engine
5
/****************************************************************************
6
** Copyright (C) 2005-2007 Klarälvdalens Datakonsult AB. All rights reserved.
8
** This file is part of the KD Chart library.
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).
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.
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.
26
**********************************************************************/
28
#include "KDChartPlotter_p.h"
29
#include "KDChartPlotter.h"
31
#include "KDChartValueTrackerAttributes.h"
33
using namespace KDChart;
35
Plotter::Private::Private( const Private& rhs )
36
: AbstractCartesianDiagram::Private( rhs )
40
void Plotter::Private::setCompressorResolution(
42
const AbstractCoordinatePlane* plane )
44
compressor.setResolution( static_cast<int>( size.width() * plane->zoomFactorX() ),
45
static_cast<int>( size.height() * plane->zoomFactorY() ) );
49
void Plotter::Private::paintPolyline(
51
const QBrush& brush, const QPen& pen,
52
const QPolygonF& points ) const
54
ctx->painter()->setBrush( brush );
55
ctx->painter()->setPen( PrintingParameters::scalePen(
61
#if QT_VERSION > 0x040299
62
ctx->painter()->drawPolyline( points );
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) );
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
77
const QPointF Plotter::PlotterType::project(
78
QPointF point, QPointF maxLimits,
79
double z, const QModelIndex& index ) const
81
Q_UNUSED( maxLimits );
82
ThreeDLineAttributes td = diagram()->threeDLineAttributes( index );
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 ) );
91
void Plotter::PlotterType::paintThreeDLines(
92
PaintContext* ctx, const QModelIndex& index,
93
const QPointF& from, const QPointF& to, const double depth )
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 );
101
const QPolygonF segment = QPolygonF() << from << topLeft << topRight << to;
102
const QBrush indexBrush ( diagram()->brush( index ) );
103
const PainterSaver painterSaver( ctx->painter() );
105
if( diagram()->antiAliasing() )
106
ctx->painter()->setRenderHint( QPainter::Antialiasing );
108
ctx->painter()->setBrush( indexBrush );
109
ctx->painter()->setPen( PrintingParameters::scalePen( diagram()->pen( index ) ) );
111
reverseMapper().addPolygon( index.row(), index.column(), segment );
112
ctx->painter()->drawPolygon( segment );
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(
120
DataValueTextInfoList& list,
121
LineAttributesInfoList& lineList,
122
LineAttributes::MissingValuesPolicy 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 );
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 );
140
if( td.isEnabled() ){
141
paintThreeDLines( ctx, index, lineInfo.value, lineInfo.nextValue, td.depth() );
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;
151
paintPolyline( ctx, curBrush, curPen, points );
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;
162
paintValueTracker( ctx, vt, lineInfo.value );
165
paintPolyline( ctx, curBrush, curPen, points );
166
// paint all data value texts and the point markers
167
paintDataValueTextsAndMarkers( diagram(), ctx, list, true );
170
AttributesModel* Plotter::PlotterType::attributesModel() const
172
return m_private->attributesModel;
176
QModelIndex LineDiagram::LineDiagramType::attributesModelRootIndex() const
178
return m_private->diagram->attributesModelRootIndex();
181
int LineDiagram::LineDiagramType::datasetDimension() const
183
return m_private->datasetDimension;
187
ReverseMapper& Plotter::PlotterType::reverseMapper()
189
return m_private->reverseMapper;
193
LineAttributes::MissingValuesPolicy LineDiagram::LineDiagramType::getCellValues(
195
bool shiftCountedXValuesByHalfSection,
196
double& valueX, double& valueY ) const
198
return m_private->diagram->getCellValues( row, column, shiftCountedXValuesByHalfSection,
202
double LineDiagram::LineDiagramType::valueForCellTesting(
205
bool showHiddenCellsAsInvalid) const
207
return m_private->diagram->valueForCellTesting( row, column, bOK, showHiddenCellsAsInvalid );
211
Plotter* Plotter::PlotterType::diagram() const
213
return m_private->diagram;
216
void Plotter::PlotterType::paintAreas(
218
const QModelIndex& index, const QList< QPolygonF >& areas,
219
const uint transparency )
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() );
227
if( diagram()->antiAliasing() )
228
ctx->painter()->setRenderHint( QPainter::Antialiasing );
230
ctx->painter()->setPen( PrintingParameters::scalePen( indexPen ) );
231
ctx->painter()->setBrush( trans );
234
for( int i = 0; i < areas.count(); ++i )
236
const QPolygonF& p = areas[ i ];
237
path.addPolygon( p );
238
reverseMapper().addPolygon( index.row(), index.column(), p );
241
ctx->painter()->drawPath( path );
245
double LineDiagram::LineDiagramType::valueForCell( int row, int column )
247
return diagram()->valueForCell( row, column );
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,
260
Q_UNUSED( autoPositionNegative );
261
m_private->appendDataValueTextInfoToList(
262
diagram, list, index, 0,
263
points, autoPositionPositive, autoPositionPositive, value );
266
void Plotter::PlotterType::paintValueTracker( PaintContext* ctx, const ValueTrackerAttributes& vt, const QPointF& at )
268
CartesianCoordinatePlane* plane = qobject_cast<CartesianCoordinatePlane*>( ctx->coordinatePlane() );
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() );
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() );
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 )
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() )
301
QPointF topLeft = ordinatePoint;
302
QPointF bottomRightOffset = abscissaPoint - topLeft;
303
QSizeF size( bottomRightOffset.x(), bottomRightOffset.y() );
304
QRectF area( topLeft, size );
306
PainterSaver painterSaver( ctx->painter() );
307
ctx->painter()->setPen( PrintingParameters::scalePen( vt.pen() ) );
308
ctx->painter()->setBrush( QBrush() );
310
ctx->painter()->drawLine( markerPoint, ordinatePoint );
311
ctx->painter()->drawLine( markerPoint, abscissaPoint );
313
ctx->painter()->fillRect( area, vt.areaBrush() );
315
ctx->painter()->drawEllipse( ellipseMarker );
317
ctx->painter()->setBrush( vt.pen().color() );
318
ctx->painter()->drawPolygon( ordinateMarker, 3 );
319
ctx->painter()->drawPolygon( abscissaMarker, 3 );
322
CartesianDiagramDataCompressor& Plotter::PlotterType::compressor() const
324
return m_private->compressor;