KChart

KChartPolarDiagram.cpp
1/*
2 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include "KChartPolarDiagram.h"
10#include "KChartPolarDiagram_p.h"
11
12#include "KChartPaintContext.h"
13#include "KChartPainterSaver_p.h"
14#include "KChartMath_p.h"
15
16#include <QPainter>
17
18using namespace KChart;
19
20PolarDiagram::Private::Private() :
21 rotateCircularLabels( false ),
22 closeDatasets( false )
23{
24}
25
26PolarDiagram::Private::~Private() {}
27
28#define d d_func()
29
30PolarDiagram::PolarDiagram( QWidget* parent, PolarCoordinatePlane* plane ) :
31 AbstractPolarDiagram( new Private( ), parent, plane )
32{
33 //init();
34}
35
36PolarDiagram::~PolarDiagram()
37{
38}
39
40
41void PolarDiagram::init()
42{
43 setShowDelimitersAtPosition( Position::Unknown, false );
44 setShowDelimitersAtPosition( Position::Center, false );
45 setShowDelimitersAtPosition( Position::NorthWest, false );
46 setShowDelimitersAtPosition( Position::North, true );
47 setShowDelimitersAtPosition( Position::NorthEast, false );
48 setShowDelimitersAtPosition( Position::West, false );
49 setShowDelimitersAtPosition( Position::East, false );
50 setShowDelimitersAtPosition( Position::SouthWest, false );
51 setShowDelimitersAtPosition( Position::South, true );
52 setShowDelimitersAtPosition( Position::SouthEast, false );
53 setShowDelimitersAtPosition( Position::Floating, false );
54
55 setShowLabelsAtPosition( Position::Unknown, false );
56 setShowLabelsAtPosition( Position::Center, false );
57 setShowLabelsAtPosition( Position::NorthWest, false );
58 setShowLabelsAtPosition( Position::North, true );
59 setShowLabelsAtPosition( Position::NorthEast, false );
60 setShowLabelsAtPosition( Position::West, false );
61 setShowLabelsAtPosition( Position::East, false );
62 setShowLabelsAtPosition( Position::SouthWest, false );
63 setShowLabelsAtPosition( Position::South, true );
64 setShowLabelsAtPosition( Position::SouthEast, false );
65 setShowLabelsAtPosition( Position::Floating, false );
66}
67
69{
70 PolarDiagram* newDiagram = new PolarDiagram( new Private( *d ) );
71 // This needs to be copied after the fact
72 newDiagram->d->showDelimitersAtPosition = d->showDelimitersAtPosition;
73 newDiagram->d->showLabelsAtPosition = d->showLabelsAtPosition;
74 newDiagram->d->rotateCircularLabels = d->rotateCircularLabels;
75 newDiagram->d->closeDatasets = d->closeDatasets;
76 return newDiagram;
77}
78
79const QPair<QPointF, QPointF> PolarDiagram::calculateDataBoundaries () const
80{
81 if ( !checkInvariants(true) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
82 const int rowCount = model()->rowCount(rootIndex());
83 const int colCount = model()->columnCount(rootIndex());
84 qreal xMin = 0.0;
85 qreal xMax = colCount;
86 qreal yMin = 0, yMax = 0;
87 for ( int iCol=0; iCol<colCount; ++iCol ) {
88 for ( int iRow=0; iRow< rowCount; ++iRow ) {
89 qreal value = model()->data( model()->index( iRow, iCol, rootIndex() ) ).toReal(); // checked
90 yMax = qMax( yMax, value );
91 yMin = qMin( yMin, value );
92 }
93 }
94 QPointF bottomLeft ( QPointF( xMin, yMin ) );
95 QPointF topRight ( QPointF( xMax, yMax ) );
96 return QPair<QPointF, QPointF> ( bottomLeft, topRight );
97}
98
99
100
101void PolarDiagram::paintEvent ( QPaintEvent*)
102{
103 QPainter painter ( viewport() );
105 ctx.setPainter ( &painter );
106 ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
107 paint ( &ctx );
108}
109
110void PolarDiagram::resizeEvent ( QResizeEvent*)
111{
112}
113
114void PolarDiagram::paintPolarMarkers( PaintContext* ctx, const QPolygonF& polygon )
115{
116 Q_UNUSED(ctx);
117 Q_UNUSED(polygon);
118 // obsolete, since we are using real markers now!
119}
120
122{
123 qreal dummy1, dummy2;
124 paint( ctx, true, dummy1, dummy2 );
125 paint( ctx, false, dummy1, dummy2 );
126}
127
129 bool calculateListAndReturnScale,
130 qreal& newZoomX, qreal& newZoomY )
131{
132 // note: Not having any data model assigned is no bug
133 // but we can not draw a diagram then either.
134 if ( !checkInvariants(true) )
135 return;
136 d->reverseMapper.clear();
137
138 const int rowCount = model()->rowCount( rootIndex() );
139 const int colCount = model()->columnCount( rootIndex() );
140
142 // Check if all of the data value texts / data comments fit into the available space...
143 d->labelPaintCache.clear();
144
145 for ( int iCol = 0; iCol < colCount; ++iCol ) {
146 for ( int iRow=0; iRow < rowCount; ++iRow ) {
147 QModelIndex index = model()->index( iRow, iCol, rootIndex() ); // checked
148 const qreal value = model()->data( index ).toReal();
150 QPointF( value, iRow ) ) + ctx->rectangle().topLeft();
151 //qDebug() << point;
152 d->addLabel( &d->labelPaintCache, index, nullptr, PositionPoints( point ),
153 Position::Center, Position::Center, value );
154 }
155 }
156
159
160 if ( d->labelPaintCache.paintReplay.count() ) {
161 // ...and zoom out if necessary
162 const qreal oldZoomX = newZoomX;
163 const qreal oldZoomY = newZoomY;
164
166 d->paintDataValueTextsAndMarkers( ctx, d->labelPaintCache, true, true, &txtRectF );
167 const QRect txtRect = txtRectF.toRect();
169 const qreal gapX = qMin( txtRect.left() - curRect.left(), curRect.right() - txtRect.right() );
170 const qreal gapY = qMin( txtRect.top() - curRect.top(), curRect.bottom() - txtRect.bottom() );
171 if ( gapX < 0.0 ) {
172 newZoomX = oldZoomX * ( 1.0 + ( gapX - 1.0 ) / curRect.width() );
173 }
174 if ( gapY < 0.0 ) {
175 newZoomY = oldZoomY * ( 1.0 + ( gapY - 1.0 ) / curRect.height() );
176 }
177 }
178 } else {
179 // Paint the data sets
180 for ( int iCol = 0; iCol < colCount; ++iCol ) {
181 //TODO(khz): As of yet PolarDiagram can not show per-segment line attributes
182 // but it draws every polyline in one go - using one color.
183 // This needs to be enhanced to allow for cell-specific settings
184 // in the same way as LineDiagram does it.
185 QBrush brush = d->datasetAttrs( iCol, KChart::DatasetBrushRole ).value<QBrush>();
186 QPolygonF polygon;
187 for ( int iRow = 0; iRow < rowCount; ++iRow ) {
188 QModelIndex index = model()->index( iRow, iCol, rootIndex() ); // checked
189 const qreal value = model()->data( index ).toReal();
190 QPointF point = coordinatePlane()->translate( QPointF( value, iRow ) )
191 + ctx->rectangle().topLeft();
192 polygon.append( point );
193 //qDebug() << point;
194 }
195 if ( closeDatasets() && !polygon.isEmpty() ) {
196 // close the circle by connecting the last data point to the first
197 polygon.append( polygon.first() );
198 }
199
200 PainterSaver painterSaver( ctx->painter() );
201 ctx->painter()->setRenderHint ( QPainter::Antialiasing );
202 ctx->painter()->setBrush( brush );
203 QPen p = d->datasetAttrs( iCol, KChart::DatasetPenRole ).value< QPen >();
204 if ( p.style() != Qt::NoPen )
205 {
206 ctx->painter()->setPen( PrintingParameters::scalePen( p ) );
207 ctx->painter()->drawPolyline( polygon );
208 }
209 }
210 d->paintDataValueTextsAndMarkers( ctx, d->labelPaintCache, true );
211 }
212}
213
218
219/*virtual*/
221{
222 return model()->rowCount(rootIndex());
223}
224
225/*virtual*/
227{
228 return model() ? model()->rowCount(rootIndex()) : 0.0;
229}
230
231/*virtual*/
233{
234 return 5; // FIXME
235}
236
238{
239 Q_UNUSED( degrees );
240 qWarning() << "Deprecated PolarDiagram::setZeroDegreePosition() called, setting ignored.";
241}
242
244{
245 qWarning() << "Deprecated PolarDiagram::zeroDegreePosition() called.";
246 return 0;
247}
248
249void PolarDiagram::setRotateCircularLabels( bool rotateCircularLabels )
250{
251 d->rotateCircularLabels = rotateCircularLabels;
252}
253
254bool PolarDiagram::rotateCircularLabels() const
255{
256 return d->rotateCircularLabels;
257}
258
259void PolarDiagram::setCloseDatasets( bool closeDatasets )
260{
261 d->closeDatasets = closeDatasets;
262}
263
264bool PolarDiagram::closeDatasets() const
265{
266 return d->closeDatasets;
267}
268
269void PolarDiagram::setShowDelimitersAtPosition( Position position,
270 bool showDelimiters )
271{
272 d->showDelimitersAtPosition[position.value()] = showDelimiters;
273}
274
275void PolarDiagram::setShowLabelsAtPosition( Position position,
276 bool showLabels )
277{
278 d->showLabelsAtPosition[position.value()] = showLabels;
279}
280
281bool PolarDiagram::showDelimitersAtPosition( Position position ) const
282{
283 return d->showDelimitersAtPosition[position.value()];
284}
285
286bool PolarDiagram::showLabelsAtPosition( Position position ) const
287{
288 return d->showLabelsAtPosition[position.value()];
289}
290
291
292
virtual const QPointF translate(const QPointF &diagramPoint) const =0
Translate the given point in value space coordinates to a position in pixel space.
QRect geometry() const override
pure virtual in QLayoutItem
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
QBrush brush() const
Retrieve the brush to be used for painting datapoints globally.
Base class for diagrams based on a polar coordinate system.
Stores information about painting diagrams.
PolarDiagram defines a common polar diagram.
virtual PolarDiagram * clone() const
Creates an exact copy of this diagram.
void paint(PaintContext *paintContext) override
\reimpl
qreal numberOfValuesPerDataset() const override
\reimpl
void setZeroDegreePosition(int degrees)
void resize(const QSizeF &area) override
\reimpl
void setCloseDatasets(bool closeDatasets)
Close each of the data series by connecting the last point to its respective start point.
qreal valueTotals() const override
\reimpl
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
\reimpl
qreal numberOfGridRings() const override
\reimpl
Stores the absolute target points of a Position.
Defines a position, using compass terminology.
KChartEnums::PositionValue value() const
Returns an integer value corresponding to this Position.
virtual int columnCount(const QModelIndex &parent) const const=0
virtual QVariant data(const QModelIndex &index, int role) const const=0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual int rowCount(const QModelIndex &parent) const const=0
QAbstractItemModel * model() const const
QModelIndex rootIndex() const const
QWidget * viewport() const const
T qobject_cast(QObject *object)
Qt::PenStyle style() const const
qreal toReal(bool *ok) const const
void resize(const QSize &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:52:19 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.