KChart

KChartLeveyJenningsDiagram.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 "KChartLeveyJenningsDiagram.h"
10 #include "KChartLeveyJenningsDiagram_p.h"
11 
12 #include "KChartChart.h"
13 #include "KChartTextAttributes.h"
14 #include "KChartAbstractGrid.h"
15 #include "KChartPainterSaver_p.h"
16 
17 #include <QDateTime>
18 #include <QFontMetrics>
19 #include <QPainter>
20 #include <QSvgRenderer>
21 #include <QVector>
22 
23 using namespace KChart;
24 using namespace std;
25 
26 LeveyJenningsDiagram::Private::Private()
27 {
28 }
29 
30 LeveyJenningsDiagram::Private::~Private() {}
31 
32 
33 #define d d_func()
34 
35 
36 LeveyJenningsDiagram::LeveyJenningsDiagram( QWidget* parent, LeveyJenningsCoordinatePlane* plane )
37  : LineDiagram( new Private(), parent, plane )
38 {
39  init();
40 }
41 
42 void LeveyJenningsDiagram::init()
43 {
44  d->lotChangedPosition = Qt::AlignTop;
45  d->fluidicsPackChangedPosition = Qt::AlignBottom;
46  d->sensorChangedPosition = Qt::AlignBottom;
47 
48  d->scanLinePen = QPen( Qt::blue );
49  setPen( d->scanLinePen );
50 
51  d->expectedMeanValue = 0.0;
52  d->expectedStandardDeviation = 0.0;
53 
54  d->diagram = this;
55 
56  d->icons[ LotChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_black.svg" );
57  d->icons[ SensorChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_red.svg" );
58  d->icons[ FluidicsPackChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_blue.svg" );
59  d->icons[ OkDataPoint ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/circle_blue.svg" );
60  d->icons[ NotOkDataPoint ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/circle_blue_red.svg" );
61 
62  setSelectionMode( QAbstractItemView::SingleSelection );
63 }
64 
65 LeveyJenningsDiagram::~LeveyJenningsDiagram()
66 {
67 }
68 
70 {
71  LeveyJenningsDiagram* newDiagram = new LeveyJenningsDiagram( new Private( *d ) );
72  return newDiagram;
73 }
74 
76 {
77  if ( other == this ) return true;
78  if ( ! other ) {
79  return false;
80  }
81  /*
82  qDebug() <<"\n LineDiagram::compare():";
83  // compare own properties
84  qDebug() << (type() == other->type());
85  */
86  return // compare the base class
87  ( static_cast<const LineDiagram*>(this)->compare( other ) );
88 }
89 
91 {
92  if ( d->lotChangedPosition == pos )
93  return;
94 
95  d->lotChangedPosition = pos;
96  update();
97 }
98 
100 {
101  return d->lotChangedPosition;
102 }
103 
105 {
106  if ( d->fluidicsPackChangedPosition == pos )
107  return;
108 
109  d->fluidicsPackChangedPosition = pos;
110  update();
111 }
112 
114 {
115  return d->fluidicsPackChangedPosition;
116 }
117 
119 {
120  if ( d->sensorChangedPosition == pos )
121  return;
122 
123  d->sensorChangedPosition = pos;
124  update();
125 }
126 
128 {
129  return d->sensorChangedPosition;
130 }
131 
133 {
134  if ( d->fluidicsPackChanges == changes )
135  return;
136 
137  d->fluidicsPackChanges = changes;
138  update();
139 }
140 
142 {
143  return d->fluidicsPackChanges;
144 }
145 
147 {
148  if ( d->sensorChanges == changes )
149  return;
150 
151  d->sensorChanges = changes;
152  update();
153 }
154 
156 {
157  if ( d->scanLinePen == pen )
158  return;
159 
160  d->scanLinePen = pen;
161  update();
162 }
163 
165 {
166  return d->scanLinePen;
167 }
168 
169 QString LeveyJenningsDiagram::symbol( Symbol symbol ) const
170 {
171  return d->icons[ symbol ];
172 }
173 
174 void LeveyJenningsDiagram::setSymbol( Symbol symbol, const QString& filename )
175 {
176  if ( d->icons[ symbol ] == filename )
177  return;
178 
179  delete d->iconRenderer[ symbol ];
180  d->iconRenderer[ symbol ] = nullptr;
181 
182  d->icons[ symbol ] = filename;
183 
184  update();
185 }
186 
188 {
189  return d->sensorChanges;
190 }
191 
193 {
194  if ( d->expectedMeanValue == meanValue )
195  return;
196 
197  d->expectedMeanValue = meanValue;
198  d->setYAxisRange();
199  update();
200 }
201 
203 {
204  return d->expectedMeanValue;
205 }
206 
208 {
209  if ( d->expectedStandardDeviation == sd )
210  return;
211 
212  d->expectedStandardDeviation = sd;
213  d->setYAxisRange();
214  update();
215 }
216 
218 {
219  return d->expectedStandardDeviation;
220 }
221 
223 {
224  return d->calculatedMeanValue;
225 }
226 
228 {
229  return d->calculatedStandardDeviation;
230 }
231 
232 void LeveyJenningsDiagram::setModel( QAbstractItemModel* model )
233 {
234  if ( this->model() != nullptr )
235  {
236  disconnect( this->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
237  this, SLOT(calculateMeanAndStandardDeviation()) );
238  disconnect( this->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
239  this, SLOT(calculateMeanAndStandardDeviation()) );
240  disconnect( this->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
241  this, SLOT(calculateMeanAndStandardDeviation()) );
242  disconnect( this->model(), SIGNAL(columnsInserted(QModelIndex,int,int)),
243  this, SLOT(calculateMeanAndStandardDeviation()) );
244  disconnect( this->model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
245  this, SLOT(calculateMeanAndStandardDeviation()) );
246  disconnect( this->model(), SIGNAL(modelReset()),
247  this, SLOT(calculateMeanAndStandardDeviation()) );
248  disconnect( this->model(), SIGNAL(layoutChanged()),
249  this, SLOT(calculateMeanAndStandardDeviation()) );
250  }
251  LineDiagram::setModel( model );
252  if ( this->model() != nullptr )
253  {
254  connect( this->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
255  this, SLOT(calculateMeanAndStandardDeviation()) );
256  connect( this->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
257  this, SLOT(calculateMeanAndStandardDeviation()) );
258  connect( this->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
259  this, SLOT(calculateMeanAndStandardDeviation()) );
260  connect( this->model(), SIGNAL(columnsInserted(QModelIndex,int,int)),
261  this, SLOT(calculateMeanAndStandardDeviation()) );
262  connect( this->model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
263  this, SLOT(calculateMeanAndStandardDeviation()) );
264  connect( this->model(), SIGNAL(modelReset()),
265  this, SLOT(calculateMeanAndStandardDeviation()) );
266  connect( this->model(), SIGNAL(layoutChanged()),
267  this, SLOT(calculateMeanAndStandardDeviation()) );
268 
269  calculateMeanAndStandardDeviation();
270  }
271 }
272 
273 // TODO: This is the 'easy' solution
274 // evaluate whether this is enough or we need some better one or even boost here
275 void LeveyJenningsDiagram::calculateMeanAndStandardDeviation() const
276 {
278  // first fetch all values
279  const QAbstractItemModel& m = *model();
280  const int rowCount = m.rowCount( rootIndex() );
281 
282  for ( int row = 0; row < rowCount; ++row )
283  {
284  const QVariant var = m.data( m.index( row, 1, rootIndex() ) );
285  if ( !var.isValid() )
286  continue;
287  const qreal value = var.toReal();
288  if ( ISNAN( value ) )
289  continue;
290  values << value;
291  }
292 
293  qreal sum = 0.0;
294  qreal sumSquares = 0.0;
295  for ( qreal value : qAsConst(values) )
296  {
297  sum += value;
298  sumSquares += value * value;
299  }
300 
301  const int N = values.count();
302 
303  d->calculatedMeanValue = sum / N;
304  d->calculatedStandardDeviation = sqrt( ( static_cast< qreal >( N ) * sumSquares - sum * sum ) / ( N * ( N - 1 ) ) );
305 }
306 
307 // calculates the largest QDate not greater than \a dt.
308 static QDate floorDay( const QDateTime& dt )
309 {
310  return dt.date();
311 }
312 
313 // calculates the smallest QDate not less than \a dt.
314 static QDate ceilDay( const QDateTime& dt )
315 {
316  QDate result = dt.date();
317 
318  if ( QDateTime( result, QTime() ) < dt )
319  result = result.addDays( 1 );
320 
321  return result;
322 }
323 
324 // calculates the largest QDateTime like xx:00 not greater than \a dt.
325 static QDateTime floorHour( const QDateTime& dt )
326 {
327  return QDateTime( dt.date(), QTime( dt.time().hour(), 0 ) );
328 }
329 
330 // calculates the smallest QDateTime like xx:00 not less than \a dt.
331 static QDateTime ceilHour( const QDateTime& dt )
332 {
333  QDateTime result( dt.date(), QTime( dt.time().hour(), 0 ) );
334 
335  if ( result < dt )
336  result = result.addSecs( 3600 );
337 
338  return result;
339 }
340 
342 {
343  const qreal yMin = d->expectedMeanValue - 4 * d->expectedStandardDeviation;
344  const qreal yMax = d->expectedMeanValue + 4 * d->expectedStandardDeviation;
345 
346  d->setYAxisRange();
347 
348  // rounded down/up to the prev/next midnight (at least that's the default)
349  const QPair< QDateTime, QDateTime > range = timeRange();
350  const unsigned int minTime = range.first.toSecsSinceEpoch();
351  const unsigned int maxTime = range.second.toSecsSinceEpoch();
352 
353  const qreal xMin = minTime / static_cast< qreal >( 24 * 60 * 60 );
354  const qreal xMax = maxTime / static_cast< qreal >( 24 * 60 * 60 ) - xMin;
355 
356  const QPointF bottomLeft( QPointF( 0, yMin ) );
357  const QPointF topRight( QPointF( xMax, yMax ) );
358 
359  return QPair< QPointF, QPointF >( bottomLeft, topRight );
360 }
361 
363 {
364  if ( d->timeRange != QPair< QDateTime, QDateTime >() )
365  return d->timeRange;
366 
367  const QAbstractItemModel& m = *model();
368  const int rowCount = m.rowCount( rootIndex() );
369 
370  const QDateTime begin = m.data( m.index( 0, 3, rootIndex() ) ).toDateTime();
371  const QDateTime end = m.data( m.index( rowCount - 1, 3, rootIndex() ) ).toDateTime();
372 
373  if ( begin.secsTo( end ) > 86400 )
374  {
375  // if begin to end is more than 24h
376  // round down/up to the prev/next midnight
377  const QDate min = floorDay( begin );
378  const QDate max = ceilDay( end );
379  return QPair< QDateTime, QDateTime >( QDateTime( min, QTime() ), QDateTime( max, QTime() ) );
380  }
381  else if ( begin.secsTo( end ) > 3600 )
382  {
383  // more than 1h: rond down up to the prex/next hour
384  // if begin to end is more than 24h
385  const QDateTime min = floorHour( begin );
386  const QDateTime max = ceilHour( end );
387  return QPair< QDateTime, QDateTime >( min, max );
388  }
389  return QPair< QDateTime, QDateTime >( begin, end );
390 }
391 
393 {
394  if ( d->timeRange == timeRange )
395  return;
396 
397  d->timeRange = timeRange;
398  update();
399 }
400 
402 {
403  const unsigned int minTime = timeRange().first.toSecsSinceEpoch();
404 
405  for ( const QDateTime& dt : qAsConst(d->fluidicsPackChanges) )
406  {
407  const qreal xValue = ( dt.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
408  const QPointF point( xValue, 0.0 );
409  drawFluidicsPackChangedSymbol( ctx, point );
410  }
411 
412  for ( const QDateTime& dt : qAsConst(d->sensorChanges) )
413  {
414  const qreal xValue = ( dt.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
415  const QPointF point( xValue, 0.0 );
416  drawSensorChangedSymbol( ctx, point );
417  }
418 }
419 
421 {
422  d->reverseMapper.clear();
423 
424  // note: Not having any data model assigned is no bug
425  // but we can not draw a diagram then either.
426  if ( !checkInvariants( true ) ) return;
427  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
428 
429  QPainter* const painter = ctx->painter();
430  const PainterSaver p( painter );
431  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) < 4 )
432  return; // nothing to paint for us
433 
434  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
435  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( painter ) );
436 
437  const QAbstractItemModel& m = *model();
438  const int rowCount = m.rowCount( rootIndex() );
439 
440  const unsigned int minTime = timeRange().first.toSecsSinceEpoch();
441 
442  painter->setRenderHint( QPainter::Antialiasing, true );
443 
444  int prevLot = -1;
445  QPointF prevPoint;
446  bool hadMissingValue = false;
447 
448  for ( int row = 0; row < rowCount; ++row )
449  {
450  const QModelIndex lotIndex = m.index( row, 0, rootIndex() );
451  const QModelIndex valueIndex = m.index( row, 1, rootIndex() );
452  const QModelIndex okIndex = m.index( row, 2, rootIndex() );
453  const QModelIndex timeIndex = m.index( row, 3, rootIndex() );
454  const QModelIndex expectedMeanIndex = m.index( row, 4, rootIndex() );
455  const QModelIndex expectedSDIndex = m.index( row, 5, rootIndex() );
456 
457  painter->setPen( pen( lotIndex ) );
458 
459  QVariant vValue = m.data( valueIndex );
460  qreal value = vValue.toReal();
461  const int lot = m.data( lotIndex ).toInt();
462  const bool ok = m.data( okIndex ).toBool();
463  const QDateTime time = m.data( timeIndex ).toDateTime();
464  const qreal xValue = ( time.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
465 
466  QVariant vExpectedMean = m.data( expectedMeanIndex );
467  const qreal expectedMean = vExpectedMean.toReal();
468  QVariant vExpectedSD = m.data( expectedSDIndex );
469  const qreal expectedSD = vExpectedSD.toReal();
470 
471  QPointF point = ctx->coordinatePlane()->translate( QPointF( xValue, value ) );
472 
473  if ( vValue.isNull() )
474  {
475  hadMissingValue = true;
476  }
477  else
478  {
479  if ( !vExpectedMean.isNull() && !vExpectedSD.isNull() )
480  {
481  // this calculates the 'logical' value relative to the expected mean and SD of this point
482  value -= expectedMean;
483  value /= expectedSD;
484  value *= d->expectedStandardDeviation;
485  value += d->expectedMeanValue;
486  point = ctx->coordinatePlane()->translate( QPointF( xValue, value ) );
487  }
488 
489  if ( prevLot == lot )
490  {
491  const QPen pen = painter->pen();
492  QPen newPen = pen;
493 
494  if ( hadMissingValue )
495  {
496  newPen.setDashPattern( QVector< qreal >() << 4.0 << 4.0 );
497  }
498 
499  painter->setPen( newPen );
500  painter->drawLine( prevPoint, point );
501  painter->setPen( pen );
502  // d->reverseMapper.addLine( valueIndex.row(), valueIndex.column(), prevPoint, point );
503  }
504  else if ( row > 0 )
505  {
506  drawLotChangeSymbol( ctx, QPointF( xValue, value ) );
507  }
508 
509  if ( value <= d->expectedMeanValue + 4 * d->expectedStandardDeviation &&
510  value >= d->expectedMeanValue - 4 * d->expectedStandardDeviation )
511  {
512  const QPointF location( xValue, value );
513  drawDataPointSymbol( ctx, location, ok );
514  d->reverseMapper.addCircle( valueIndex.row(),
515  valueIndex.column(),
516  ctx->coordinatePlane()->translate( location ),
517  iconRect().size() );
518  }
519  prevLot = lot;
520  prevPoint = point;
521  hadMissingValue = false;
522  }
523 
524  const QModelIndex current = selectionModel()->currentIndex();
525  if ( selectionModel()->rowIntersectsSelection( lotIndex.row(), lotIndex.parent() ) || current.sibling( current.row(), 0 ) == lotIndex )
526  {
527  const QPen pen = ctx->painter()->pen();
528  painter->setPen( d->scanLinePen );
529  painter->drawLine( ctx->coordinatePlane()->translate( QPointF( xValue, d->expectedMeanValue - 4 *
530  d->expectedStandardDeviation ) ),
531  ctx->coordinatePlane()->translate( QPointF( xValue, d->expectedMeanValue + 4 *
532  d->expectedStandardDeviation ) ) );
533  painter->setPen( pen );
534  }
535  }
536 
537  drawChanges( ctx );
538 
539  ctx->setCoordinatePlane( plane );
540 }
541 
543 {
544  const Symbol type = ok ? OkDataPoint : NotOkDataPoint;
545 
546  QPainter* const painter = ctx->painter();
547  const PainterSaver ps( painter );
548  const QPointF transPos = ctx->coordinatePlane()->translate( pos ).toPoint();
549  painter->translate( transPos );
550 
551  painter->setClipping( false );
552  iconRenderer( type )->render( painter, iconRect() );
553 }
554 
556 {
557  const QPointF transPos = ctx->coordinatePlane()->translate(
558  QPointF( pos.x(), d->lotChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
559  4 * d->expectedStandardDeviation
560  : d->expectedMeanValue -
561  4 * d->expectedStandardDeviation ) );
562 
563 
564  QPainter* const painter = ctx->painter();
565  const PainterSaver ps( painter );
566  painter->setClipping( false );
567  painter->translate( transPos );
568  iconRenderer( LotChanged )->render( painter, iconRect() );
569 }
570 
572 {
573  const QPointF transPos = ctx->coordinatePlane()->translate(
574  QPointF( pos.x(), d->sensorChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
575  4 * d->expectedStandardDeviation
576  : d->expectedMeanValue -
577  4 * d->expectedStandardDeviation ) );
578 
579  QPainter* const painter = ctx->painter();
580  const PainterSaver ps( painter );
581  painter->setClipping( false );
582  painter->translate( transPos );
583  iconRenderer( SensorChanged )->render( painter, iconRect() );
584 }
585 
587 {
588  const QPointF transPos = ctx->coordinatePlane()->translate(
589  QPointF( pos.x(), d->fluidicsPackChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
590  4 * d->expectedStandardDeviation
591  : d->expectedMeanValue -
592  4 * d->expectedStandardDeviation ) );
593 
594  QPainter* const painter = ctx->painter();
595  const PainterSaver ps( painter );
596  painter->setClipping( false );
597  painter->translate( transPos );
598  iconRenderer( FluidicsPackChanged )->render( painter, iconRect() );
599 }
600 
602 {
603  const Measure m( 12.5, KChartEnums::MeasureCalculationModeAuto, KChartEnums::MeasureOrientationAuto );
604  TextAttributes test;
605  test.setFontSize( m );
606  const QFontMetrics fm( test.calculatedFont( coordinatePlane()->parent(), KChartEnums::MeasureOrientationAuto ) );
607  const qreal height = fm.height() / 1.2;
608  return QRectF( -height / 2.0, -height / 2.0, height, height );
609 }
610 
612 {
613  if ( d->iconRenderer[ symbol ] == nullptr )
614  d->iconRenderer[ symbol ] = new QSvgRenderer( d->icons[ symbol ], this );
615 
616  return d->iconRenderer[ symbol ];
617 }
LineDiagram * clone() const override
Creates an exact copy of this diagram.
Qt::Alignment lotChangedSymbolPosition() const
Returns the position of the lot change symbol.
virtual void drawLotChangeSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a lot changed symbol for the data point at pos.
Class only listed here to document inheritance of some KChart classes.
virtual int rowCount(const QModelIndex &parent) const const =0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const =0
QSvgRenderer * iconRenderer(Symbol symbol)
Returns the SVG icon renderer for symbol.
Levey Jennings coordinate plane This is actually nothing real more than a plain cartesian coordinate ...
void setRenderHint(QPainter::RenderHint hint, bool on)
virtual const QPointF translate(const QPointF &diagramPoint) const =0
Translate the given point in value space coordinates to a position in pixel space.
virtual QRectF iconRect() const
Returns the rectangle being used for drawing the icons.
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
void update()
Calling update() on the plane triggers the global KChart::Chart::update()
QDateTime toDateTime() const const
LeveyDiagram defines a Levey Jennings chart.
void setClipping(bool enable)
void setTimeRange(const QPair< QDateTime, QDateTime > &timeRange)
Sets the timeRange visible on the x axis.
bool compare(const LeveyJenningsDiagram *other) const
Returns true if both diagrams have the same settings.
bool compare(const AbstractAreaBase *other) const
Returns true if both areas have the same settings.
QTime time() const const
void setSymbol(Symbol symbol, const QString &filename)
Sets the symbol being used for symbol to a SVG file filename.
void drawLine(const QLineF &line)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
AlignTop
QVector< QDateTime > sensorChanges() const
Returns the list of all sensor changes.
void setLotChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the lot change symbol to pos.
QVector< V > values(const QMultiHash< K, V > &c)
qreal x() const const
void setDashPattern(const QVector< qreal > &pattern)
PartitionTable::TableType type
const QFont calculatedFont(const QObject *autoReferenceArea, KChartEnums::MeasureOrientation autoReferenceOrientation) const
Returns the font in the size that is used at drawing time.
Stores information about painting diagrams.
int toInt(bool *ok) const const
bool isNull() const const
virtual void drawDataPointSymbol(PaintContext *paintContext, const QPointF &pos, bool ok)
Draws a data point symbol for the data point at pos.
Qt::Alignment sensorChangedSymbolPosition() const
Returns the position of the sensor changed symbol.
QString symbol(Symbol symbol) const
Returns the SVG file name usef for symbol.
void setPen(const QColor &color)
void setScanLinePen(const QPen &pen)
Sets the pen used for drawing the scan line to pen.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
virtual void drawSensorChangedSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a sensor changed symbol for the data point at pos.
int row() const const
void setFluidicsPackChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the fluidics pack changed symbol to pos.
virtual QVariant data(const QModelIndex &index, int role) const const =0
float calculatedMeanValue() const
Returns the calculated mean values over all QC values.
QPair< QDateTime, QDateTime > timeRange() const
Returns the timerange of the diagram&#39;s data.
QModelIndex parent() const const
int hour() const const
void setExpectedStandardDeviation(float sd)
Sets the expected standard deviaction over all QC values to sd.
void setFluidicsPackChanges(const QVector< QDateTime > &changes)
Sets the date/time of all fluidics pack changes to changes.
QCA_EXPORT void init()
Qt::Alignment fluidicsPackChangedSymbolPosition() const
Returns the position of the fluidics pack changed symbol.
virtual void drawFluidicsPackChangedSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a fluidics pack changed symbol for the data point at pos.
QDate date() const const
QPoint toPoint() const const
qint64 secsTo(const QDateTime &other) const const
qint64 toSecsSinceEpoch() const const
QModelIndex sibling(int row, int column) const const
void setFontSize(const Measure &measure)
Set the size of the font used for rendering text.
int height() const const
int count(const T &value) const const
int column() const const
bool toBool() const const
void translate(const QPointF &offset)
A set of text attributes.
float calculatedStandardDeviation() const
Returns the calculated standard deviation over all QC values.
QString fromLatin1(const char *str, int size)
bool isValid() const const
float expectedStandardDeviation() const
Returns the expected standard deviation over all QC values.
LineDiagram defines a common line diagram.
QDate addDays(qint64 ndays) const const
qreal toReal(bool *ok) const const
void setSensorChanges(const QVector< QDateTime > &changes)
Sets the date/time of all sensor changes to changes.
QDateTime addSecs(qint64 s) const const
void setSensorChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the sensor changed symbol to pos.
QVector< QDateTime > fluidicsPackChanges() const
Returns the list of all fluidics pack changes.
Global namespace.
void drawChanges(PaintContext *paintContext)
Draws the fluidics pack and sensor changed symbols.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const QPen & pen() const const
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
void setExpectedMeanValue(float meanValue)
Sets the expected mean value over all QC values to meanValue.
QPen scanLinePen() const
Returns the pen being used for drawing the scan line.
Measure is used to specify relative and absolute sizes in KChart, e.g.
Definition: KChartMeasure.h:37
void paint(PaintContext *paintContext) override
float expectedMeanValue() const
Returns the expected mean values over all QC values.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jan 27 2022 22:33:23 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.