KD Chart 2  [rev.2.7]
KDChartLeveyJenningsAxis.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2020 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
24 #include "KDChartLeveyJenningsAxis_p.h"
25 
26 #include <QDateTime>
27 #include <QPainter>
28 
29 #include "KDChartPaintContext.h"
30 #include "KDChartChart.h"
32 #include "KDChartAbstractGrid.h"
33 #include "KDChartPainterSaver_p.h"
34 #include "KDChartLayoutItems.h"
36 
37 #include <KDABLibFakes>
38 
39 #include <limits>
40 
41 using namespace KDChart;
42 
43 #define d (d_func())
44 
46  : CartesianAxis ( new Private( diagram, this ), diagram )
47 {
48  init();
49 }
50 
52 {
53  // when we remove the first axis it will unregister itself and
54  // propagate the next one to the primary, thus the while loop
55  while ( d->mDiagram ) {
56  LeveyJenningsDiagram *cd = qobject_cast< LeveyJenningsDiagram* >( d->mDiagram );
57  cd->takeAxis( this );
58  }
59  Q_FOREACH( AbstractDiagram *diagram, d->secondaryDiagrams ) {
60  LeveyJenningsDiagram *cd = qobject_cast< LeveyJenningsDiagram* >( diagram );
61  cd->takeAxis( this );
62  }
63 }
64 
65 void LeveyJenningsAxis::init ()
66 {
68  setDateFormat( Qt::TextDate );
69  const QStringList labels = QStringList() << tr( "-3sd" ) << tr( "-2sd" ) << tr( "mean" )
70  << tr( "+2sd" ) << tr( "+3sd" );
71 
72  setLabels( labels );
73 }
74 
79 {
80  return d->type;
81 }
82 
93 {
94  if ( type != d->type )
95  {
97  QPen pen = ta.pen();
98  QColor color = type == LeveyJenningsGridAttributes::Expected ? Qt::black : Qt::blue;
99  if ( qobject_cast< const LeveyJenningsDiagram* >( d->diagram() ) &&
100  qobject_cast< const LeveyJenningsCoordinatePlane* >( d->diagram()->coordinatePlane() ) )
101  {
102  color = qobject_cast< const LeveyJenningsCoordinatePlane* >( d->diagram()->coordinatePlane() )->gridAttributes().gridPen( type ).color();
103  }
104  pen.setColor( color );
105  ta.setPen( pen );
106  setTextAttributes( ta );
107  }
108  d->type = type;
109 }
110 
111 Qt::DateFormat LeveyJenningsAxis::dateFormat() const
112 {
113  return d->format;
114 }
115 
116 void LeveyJenningsAxis::setDateFormat(Qt::DateFormat format)
117 {
118  d->format = format;
119 }
120 
122 {
123  if ( other == this ) return true;
124  if ( ! other ) {
125  //qDebug() << "CartesianAxis::compare() cannot compare to Null pointer";
126  return false;
127  }
128  return ( static_cast<const CartesianAxis*>(this)->compare( other ) ) &&
129  ( type() == other->type() );
130 }
131 
133 {
134 
135  Q_ASSERT_X ( d->diagram(), "LeveyJenningsAxis::paint",
136  "Function call not allowed: The axis is not assigned to any diagram." );
137 
139  Q_ASSERT_X ( plane, "LeveyJenningsAxis::paint",
140  "Bad function call: PaintContext::coodinatePlane() NOT a levey jennings plane." );
141  Q_UNUSED(plane);
142  // note: Not having any data model assigned is no bug
143  // but we can not draw an axis then either.
144  if ( ! d->diagram()->model() )
145  return;
146 
147  if ( isOrdinate() )
148  paintAsOrdinate( context );
149  else
150  paintAsAbscissa( context );
151 }
152 
154 {
155  const LeveyJenningsDiagram* const diag = dynamic_cast< const LeveyJenningsDiagram* >( d->diagram() );
156 
157  Q_ASSERT( isOrdinate() );
159 
160  const qreal meanValue = type() == LeveyJenningsGridAttributes::Expected ? diag->expectedMeanValue()
161  : diag->calculatedMeanValue();
162  const qreal standardDeviation = type() == LeveyJenningsGridAttributes::Expected ? diag->expectedStandardDeviation()
163  : diag->calculatedStandardDeviation();
164  const TextAttributes labelTA = textAttributes();
165  const bool drawLabels = labelTA.isVisible();
166 
167  // nothing to draw, since we've no ticks
168  if ( !drawLabels )
169  return;
170 
171  const QObject* referenceArea = plane->parent();
172 
173  const QVector< qreal > values = QVector< qreal >() << ( meanValue - 3 * standardDeviation )
174  << ( meanValue - 2 * standardDeviation )
175  << ( meanValue )
176  << ( meanValue + 2 * standardDeviation )
177  << ( meanValue + 3 * standardDeviation );
178 
179  Q_ASSERT_X( values.count() <= labels().count(), "LeveyJenningsAxis::paintAsOrdinate", "Need to have at least 5 labels" );
180 
181  TextLayoutItem labelItem( tr( "mean" ),
182  labelTA,
183  referenceArea,
185  Qt::AlignLeft );
186 
187  QPainter* const painter = context->painter();
188  const PainterSaver ps( painter );
189  painter->setRenderHint( QPainter::Antialiasing, true );
190  painter->setClipping( false );
191 
192  painter->setPen ( PrintingParameters::scalePen( labelTA.pen() ) ); // perhaps we want to add a setter method later?
193 
194  for ( int i = 0; i < values.count(); ++i )
195  {
196  const QPointF labelPos = plane->translate( QPointF( 0.0, values.at( i ) ) );
197  const QString label = customizedLabel( labels().at( i ) );
198  labelItem.setText( label );
199  const QSize size = labelItem.sizeHint();
200  const float xPos = position() == Left ? geometry().right() - size.width() : geometry().left();
201  labelItem.setGeometry( QRectF( QPointF( xPos, labelPos.y() - size.height() / 2.0 ), size ).toRect() );
202 
203  // don't draw labels which aren't in the valid range (might happen for calculated SDs)
204  if ( values.at( i ) > diag->expectedMeanValue() + 4 * diag->expectedStandardDeviation() )
205  continue;
206 
207  if ( values.at( i ) < diag->expectedMeanValue() - 4 * diag->expectedStandardDeviation() )
208  continue;
209 
210  labelItem.paint( painter );
211  }
212 }
213 
215 {
216  Q_ASSERT( isAbscissa() );
217 
218  // this triggers drawing of the ticks
219  setLabels( QStringList() << QString::fromLatin1( " " ) );
220  CartesianAxis::paintCtx( context );
221 
222  const LeveyJenningsDiagram* const diag = dynamic_cast< const LeveyJenningsDiagram* >( d->diagram() );
224 
225  const QObject* referenceArea = plane->parent();
226  const TextAttributes labelTA = textAttributes();
227 
228  const bool drawLabels = labelTA.isVisible();
229 
230  if ( !drawLabels )
231  return;
232 
233 
234  const QPair< QDateTime, QDateTime > range = diag->timeRange();
235 
236  QPainter* const painter = context->painter();
237  const PainterSaver ps( painter );
238  painter->setRenderHint( QPainter::Antialiasing, true );
239  painter->setClipping( false );
240 
241 
242  TextLayoutItem labelItem( range.first.date().toString( dateFormat() ),
243  labelTA,
244  referenceArea,
246  Qt::AlignLeft );
247  QSize origSize = labelItem.sizeHint();
248  if ( range.first.secsTo( range.second ) < 86400 )
249  labelItem = TextLayoutItem( range.first.toString( dateFormat() ),
250  labelTA,
251  referenceArea,
253  Qt::AlignLeft );
254  QSize size = labelItem.sizeHint();
255 
256  float yPos = position() == Bottom ? geometry().bottom() - size.height() : geometry().top();
257  labelItem.setGeometry( QRectF( QPointF( geometry().left() - origSize.width() / 2.0, yPos ), size ).toRect() );
258  labelItem.paint( painter );
259 
260 
261  TextLayoutItem labelItem2( range.second.date().toString( dateFormat() ),
262  labelTA,
263  referenceArea,
265  Qt::AlignLeft );
266  origSize = labelItem2.sizeHint();
267  if ( range.first.secsTo( range.second ) < 86400 )
268  labelItem2 = TextLayoutItem( range.second.toString( dateFormat() ),
269  labelTA,
270  referenceArea,
272  Qt::AlignLeft );
273  size = labelItem2.sizeHint();
274  yPos = position() == Bottom ? geometry().bottom() - size.height() : geometry().top();
275  labelItem2.setGeometry( QRectF( QPointF( geometry().right() - size.width() + origSize.width() / 2.0, yPos ), size ).toRect() );
276  labelItem2.paint( painter );
277 }
KDChart::LeveyJenningsAxis::setDateFormat
void setDateFormat(Qt::DateFormat format)
Definition: KDChartLeveyJenningsAxis.cpp:116
KDChart::TextLayoutItem::setGeometry
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
Definition: KDChartLayoutItems.cpp:323
d
#define d
Definition: KDChartLeveyJenningsAxis.cpp:43
KDChart::CartesianAxis::isOrdinate
virtual bool isOrdinate() const
Definition: KDChartCartesianAxis.cpp:536
KDChart::TextLayoutItem::setText
void setText(const QString &text)
Definition: KDChartLayoutItems.cpp:244
KDChart::CartesianAxis::position
virtual const Position position() const
Definition: KDChartCartesianAxis.cpp:488
KDChart::LeveyJenningsAxis::~LeveyJenningsAxis
~LeveyJenningsAxis() override
Definition: KDChartLeveyJenningsAxis.cpp:51
KDChart::CartesianCoordinatePlane::translate
const QPointF translate(const QPointF &diagramPoint) const override
Translate the given point in value space coordinates to a position in pixel space.
Definition: KDChartCartesianCoordinatePlane.cpp:456
KDChart::AbstractAxis::setTextAttributes
void setTextAttributes(const TextAttributes &a)
Use this to specify the text attributes to be used for axis labels.
Definition: KDChartAbstractAxis.cpp:188
KDChart::LeveyJenningsDiagram::calculatedStandardDeviation
float calculatedStandardDeviation() const
Returns the calculated standard deviation over all QC values.
Definition: KDChartLeveyJenningsDiagram.cpp:309
KDChart::CartesianAxis
The class for cartesian axes.
Definition: KDChartCartesianAxis.h:43
KDChart::LeveyJenningsDiagram
LeveyDiagram defines a Levey Jennings chart.
Definition: KDChartLeveyJenningsDiagram.h:45
KDChart::LeveyJenningsCoordinatePlane
Levey Jennings coordinate plane This is actually nothing real more than a plain cartesian coordinate ...
Definition: KDChartLeveyJenningsCoordinatePlane.h:42
KDChart::PrintingParameters::scalePen
static QPen scalePen(const QPen &pen)
Definition: KDChartPrintingParameters.cpp:48
KDChart::TextLayoutItem::paint
void paint(QPainter *) override
Definition: KDChartLayoutItems.cpp:490
KDChart
Definition: KDChartAbstractCartesianDiagram.h:30
KDChart::PaintContext::coordinatePlane
AbstractCoordinatePlane * coordinatePlane() const
Definition: KDChartPaintContext.cpp:78
KDChart::LeveyJenningsDiagram::expectedMeanValue
float expectedMeanValue() const
Returns the expected mean values over all QC values.
Definition: KDChartLeveyJenningsDiagram.cpp:272
KDChart::TextLayoutItem::sizeHint
QSize sizeHint() const override
pure virtual in QLayoutItem
Definition: KDChartLayoutItems.cpp:411
KDChart::LeveyJenningsGridAttributes::Expected
@ Expected
Definition: KDChartLeveyJenningsGridAttributes.h:50
KDChart::LeveyJenningsAxis::LeveyJenningsAxis
LeveyJenningsAxis(LeveyJenningsDiagram *diagram=0)
C'tor of the class for levey jennings axes.
Definition: KDChartLeveyJenningsAxis.cpp:45
KDChartPaintContext.h
KDChart::TextAttributes::pen
QPen pen() const
Definition: KDChartTextAttributes.cpp:261
KDChartPrintingParameters.h
KDChart::CartesianAxis::Left
@ Left
Definition: KDChartCartesianAxis.h:54
KDChart::PaintContext
Stores information about painting diagrams.
Definition: KDChartPaintContext.h:42
KDChart::TextAttributes
A set of text attributes.
Definition: KDChartTextAttributes.h:47
KDChart::AbstractCoordinatePlane::parent
Chart * parent()
Definition: KDChartAbstractCoordinatePlane.cpp:198
KDChart::TextAttributes::isVisible
bool isVisible() const
Definition: KDChartTextAttributes.cpp:123
KDChart::AbstractAxis::setLabels
void setLabels(const QStringList &list)
Use this to specify your own set of strings, to be used as axis labels.
Definition: KDChartAbstractAxis.cpp:214
KDChart::LeveyJenningsAxis
The class for levey jennings axes.
Definition: KDChartLeveyJenningsAxis.h:45
KDChart::LeveyJenningsAxis::paintAsOrdinate
virtual void paintAsOrdinate(PaintContext *)
Definition: KDChartLeveyJenningsAxis.cpp:153
KDChart::LeveyJenningsAxis::paintAsAbscissa
virtual void paintAsAbscissa(PaintContext *)
Definition: KDChartLeveyJenningsAxis.cpp:214
KDChart::PaintContext::painter
QPainter * painter() const
Definition: KDChartPaintContext.cpp:68
KDChart::LeveyJenningsAxis::compare
bool compare(const LeveyJenningsAxis *other) const
Returns true if both axes have the same settings.
Definition: KDChartLeveyJenningsAxis.cpp:121
KDChart::CartesianAxis::paintCtx
void paintCtx(PaintContext *) override
reimpl
Definition: KDChartCartesianAxis.cpp:656
KDChart::AbstractAxis::labels
QStringList labels() const
Returns a list of strings, that are used as axis labels, as set via setLabels.
Definition: KDChartAbstractAxis.cpp:223
KDChartAbstractCartesianDiagram.h
KDChart::LeveyJenningsGridAttributes::GridType
GridType
Definition: KDChartLeveyJenningsGridAttributes.h:49
KDChartLayoutItems.h
KDChart::AbstractDiagram
AbstractDiagram defines the interface for diagram classes.
Definition: KDChartAbstractDiagram.h:51
KDChart::LeveyJenningsDiagram::calculatedMeanValue
float calculatedMeanValue() const
Returns the calculated mean values over all QC values.
Definition: KDChartLeveyJenningsDiagram.cpp:301
KDChart::LeveyJenningsAxis::setType
void setType(LeveyJenningsGridAttributes::GridType type)
Sets the type of the axis to type.
Definition: KDChartLeveyJenningsAxis.cpp:92
KDChart::AbstractAxis::customizedLabel
virtual const QString customizedLabel(const QString &label) const
Reimplement this method if you want to adjust axis labels before they are printed.
Definition: KDChartAbstractAxis.cpp:162
KDChart::LeveyJenningsDiagram::timeRange
QPair< QDateTime, QDateTime > timeRange() const
Returns the timerange of the diagram's data.
Definition: KDChartLeveyJenningsDiagram.cpp:448
KDChart::CartesianAxis::geometry
QRect geometry() const override
pure virtual in QLayoutItem
Definition: KDChartCartesianAxis.cpp:1103
KDChart::LeveyJenningsAxis::paintCtx
void paintCtx(PaintContext *) override
reimpl
Definition: KDChartLeveyJenningsAxis.cpp:132
KDChartChart.h
QPair
Definition: KDChartWidget.h:35
KDChart::TextAttributes::setPen
void setPen(const QPen &pen)
Set the pen to use for rendering the text.
Definition: KDChartTextAttributes.cpp:256
KDChart::AbstractAxis::diagram
const AbstractDiagram * diagram() const
Definition: KDChartAbstractAxis.cpp:249
KDChart::TextLayoutItem
Layout item showing a text.
Definition: KDChartLayoutItems.h:100
KDChart::LeveyJenningsAxis::type
LeveyJenningsGridAttributes::GridType type() const
Definition: KDChartLeveyJenningsAxis.cpp:78
KDChart::LeveyJenningsDiagram::expectedStandardDeviation
float expectedStandardDeviation() const
Returns the expected standard deviation over all QC values.
Definition: KDChartLeveyJenningsDiagram.cpp:293
KDChart::CartesianAxis::isAbscissa
virtual bool isAbscissa() const
Definition: KDChartCartesianAxis.cpp:528
QObject
QVector
Definition: KDChartWidget.h:34
KDChartLeveyJenningsAxis.h
KDChartEnums::MeasureOrientationMinimum
@ MeasureOrientationMinimum
Definition: KDChartEnums.h:293
KDChart::CartesianAxis::Bottom
@ Bottom
Definition: KDChartCartesianAxis.h:51
KDChart::AbstractCartesianDiagram::takeAxis
virtual void takeAxis(CartesianAxis *axis)
Removes the axis from the diagram, without deleting it.
Definition: KDChartAbstractCartesianDiagram.cpp:93
KDChart::LeveyJenningsAxis::dateFormat
Qt::DateFormat dateFormat() const
Definition: KDChartLeveyJenningsAxis.cpp:111
KDChart::AbstractAxis::textAttributes
TextAttributes textAttributes() const
Returns the text attributes to be used for axis labels.
Definition: KDChartAbstractAxis.cpp:197

Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/

https://www.kdab.com/development-resources/qt-tools/kd-chart/